I am using ASP.Net MVC 3 Razor view engine.
I have a requirement to generate some JavaScript code in my View based on a value in my View Model. The value I need to use is a boolean, for this example lets call it IsSet
.
So what I want to do is create a JavaScript boolean based on this value that I can use in the script later on.
Keep in mind that for all below examples I have this bit of code at the top of my view...
@{ string IsSet = Model.IsSet ? "true" : "false"; }
NOTE: All examples below are JavaScript.
First attempt...
var IsSet = @(IsSet);
... this actually works, the problem is it breaks the auto-formatting (CTRL + E, D) in VS 2010 due to badly formatted JavaScript - as you might expect, and this is not acceptable.
Second attempt...
var IsSet = "@(IsSet)";
...I know, JavaScript is clever, it will auto-parse my string when needed. Ooops, forgot it is a string type and anything other than empty evaluates to true.
Third attempt...
var IsSet = Boolean("@(IsSet)");
....surely this will work... nope, convert non-empty string to true again (bad parser!)
Fourth attempt...
var IsSet = "@(IsSet)" === "true";
Finally something that works, but it doesn't look great to me.
I will use this if need be but ultimately my question is: Is there a better way to handle this kind of situation? Perhaps, the unwanted behaviour in my first attempt is just something that Microsoft may have overlooked?
If anybody has a nice and tidy fifth attempt for me, that would be good.
The important thing for me is that the auto-formatting in VS 2010 does not break
Thanks
I just wrestled with the same issue for about an hour. My final solution was equivalent to the following.
var IsSet = @(Model.IsSet.ToString().ToLower()); // Inside JavaScript block
This requires no additional code.
None of the versions shown so far (both in the question and answers) is something that I would use. Here's how I would do it:
@model MyViewModel
<script type="text/javascript">
var isSet = @Html.Raw(Json.Encode(Model.IsSet));
// TODO: use the isSet javascript variable here as a standard boolean value
</script>
or if you needed other properties of your view model to be manipulated with javascript you could JSON encode the entire model:
@model MyViewModel
<script type="text/javascript">
var model = @Html.Raw(Json.Encode(Model));
if (model.IsSet) {
alert(model.FooBar);
}
</script>
Version 1 is the only one of those that I'd vote for even if they all worked, because it's the most human-readable. Unfortunately I don't have VS at home so I can't try it out to see what the auto-formatting issue is, but if at all possible I'd want to ignore the issue and go ahead and use that version given that there's nothing actually wrong with the code - it is just VS that is confused. (Are you saying VS is trying to interpret the whole thing as JS and thus finding it invalid?)
But if you want some other options:
Fifth attempt...
@{ string IsSet = Model.IsSet ? "true" : ""; }
var isSet = !!"@(IsSet)";
// OR
var isSet = Boolean("@(IsSet)");
Coerce the string value into a boolean with the old double-not-operator trick - as you already pointed out both "true" and "false" would become true, but this problem goes away if you use "true" and "" (empty string) - so you can use Boolean()
as per your "third attempt".
Sixth attempt...
@{ string IsSet = Model.IsSet ? "true" : "false"; }
// helper function at the top of your page:
function bool(strVal) {
return strVal === "true";
}
// variable declaration
var isSet = bool("@(IsSet)");
OK, so you end up with a fairly pointless function at the top of your page, but it keeps the actual variable declarations reasonably tidy and if debugging client side you'll see bool("false")
or bool("true")
.
Seventh attempt...
I don't like the extra step of creating the server-side string IsSet = Model.IsSet ? "true" : "false";
in advance. I don't know Razor syntax, but can you say something along the lines of:
var isSet = !!"@(Model.IsSet ? "true" : "")";
// OR, better:
var isSet = !!"@(rzrBool(Model.IsSet))";
// where rzrBool() is a server-side helper function (that you would create)
// which returns "true" or ""
I would expect all of my "attempts" to work, but again I think your "first attempt" is the best option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With