using viewbag with jquery - asp.net mvc 3
Asked Answered
L

3

10

I have a ViewBag.IsLocal set to true in controller. I would like to use jquery to check the ViewBag value and display an alert.

Code:

if(@ViewBag.IsLocal == true)
{
alert("yeah");
}

I never get the alert. When I use Firebug to see the value of ViewBag it's True ( with capital T). Do I have to do something like == 'True'? I tried it all and none of that worked.

Thank you for help.

H

Lifesaver answered 26/10, 2011 at 15:42 Comment(3)
how are you exposing the ViewBag to javascript?Embayment
I don't think I do. I tried doing something like var isLocal = ViewBag.IsLocal; and then do if(isLocal == true) but that didn't work eitherLifesaver
You seem to be confusing server side code and client side code. Your controller runs on a webserver, javascript (including jQuery) runs in the browser.Embayment
R
21

If you view source on the rendered page, what's being inserted in place of your razor nugget? If IsLocal is a bool type, I think you'll see this:

@if(True == true)
{
  alert("yeah");
}

The reason for that is because true.ToString() is True.

In which case, you'll need to make a string comparison there:

if('@ViewBag.IsLocal' == 'True')
{
  alert("yeah");
}
Ramonramona answered 26/10, 2011 at 15:50 Comment(14)
Neither of your two code snippets will work. There is no alert function defined in .NET. You need to tell the Razor interpreter to not interpret it as server side code and consider it as literal.Pipestone
Of course the first one doesn't work. It wasn't supposed to be an example of working code. Did you even read my answer?Ramonramona
ya this answer is more confused than the OP, it further blurs the line between JS and C#Embayment
If he's trying to do anything serious with the JavaScript, it would be a disaster trying to use Razor's conditional instead of getting the value into the rendered code and letting JavaScript handle it. You have to blur the line one way or the other; might as well blur it in the right direction.Ramonramona
You are missing the point, and you are still wrong. See Darin's answer for the correct seperation of client/server code.Embayment
Darin's answer is a very poor approach for anything more complex than a trivial example. What if the OP needs to test ViewBag.IsLocal and a client-side value in the same conditional, for example? Trying to drive client-side interaction from the server-side is the classic mistake ASP.NET devs have been making for years in WebForms and ASP.NET AJAX. It has been proven to be a bad approach time and time again.Ramonramona
@DaveWard, see my updated answer for an example to handle this case.Pipestone
@Darin: That's much better. I don't understand why you would claim my code doesn't work (it does; test it), but then post something using a refined version of the same approach?Ramonramona
So putting a server side conditional around some JS is a classic mistake, yet putting a server side variable inside of a client side conditional is supposed to be better? That's FAR worse.Embayment
@NeilN: I think you're missing my point. I don't care which syntax you use to get the server-side value injected into JavaScript. The important thing is to get the value to the client-side, instead of trying to run the conditional from the server-side when the page is rendered.Ramonramona
@DaveWard, you are correct. Your code works indeed. I didn't read carefully. I apologize, it's completely my fault. But the syntax seems brittle inside the if condition.Pipestone
Aside from worse code readibility, it does make sense to not send code to the client that you can determine server side will not be used.Embayment
@DarinDimitrov: I agree that the string comparison isn't as nice as the approach you added to your answer. As it stands now, yours is definitely a better approach. I more wanted the OP to be able to see that he was extremely close already, and that his guess about comparing with True was right.Ramonramona
@NeilN: It's a mistake to assume his ultimate goal is all-or-nothing on the client-side code. That happens sometimes, but it's pretty rare. The alert() was probably just a trivial example for simplicity's sake. Usually, you want to run the same, shared client-side code either way, but influence its operation based on the server-side variable.Ramonramona
P
21

Assuming you have set the IsLocal property to a boolean value in your controller action:

public ActionResult Index()
{
    ViewBag.IsLocal = true;
    return View();
}

you could do this on the view:

<script type="text/javascript">
    @if(ViewBag.IsLocal)
    {
        <text>alert("yeah");</text>
    }
</script>

And please don't use ViewBag/ViewData. Use view models and strongly typed views.

So here's a better approach that I prefer. You could JSON serialize your view model into a javascript variable and then deal with it. Like this:

@model MyViewModel

<script type="text/javascript">
    var model = @Html.Raw(Json.Encode(Model));
    // at this stage model is a javascript variable containing
    // your server side view model so you could manipulate it as you wish
    if(model.IsLocal)
    {
        alert("hello " + model.FirstName);
    }
</script>

Obviously if you don't need your entire view model you could JSON serialize only a subset of it => only the part that will be needed by client scripts.

Pipestone answered 26/10, 2011 at 15:48 Comment(10)
If he's doing anything more complex than an alert() example, mixing server-side Razor conditionals into his JavaScript would be a really bad idea.Ramonramona
@DaveWard, in this case he needs to use a server side variable to include or not a given script. This entire script body could be wrapped in a <text></text> nodes in order to be considered as literal. Inside the script there should be no more mixings. I agree with you that it would be better to externalize the script into a separate javascript file. In this case this <script> tag could be included conditionally using the same syntax as I shown in my answer (wrapping in <text> nodes which have a special meaning in Razor)Pipestone
You're assuming that he's using that variable to include a script. He didn't say that in the question. What if he needs to test for IsLocal and a client-side condition at some point? Or, do anything more trivial than the if IsLocal then alert(), really? IMO, it doesn't make sense to try to drive that interaction from the server-side, when you can do it from the client-side just as easily (and cleaner, without the <text> clutter) and gain more flexibility.Ramonramona
@DaveWard, simple, in this case modify the if condition: if (model.IsLocal && someOtherjavascriptVariable) { ... }. It's pure javascript now. No more <text> if my suggestion of using view models is followed.Pipestone
The edited addition is much better (and ironically another step down the same exact same approach that earned me two downvotes...)Ramonramona
@DaveWard, it's if('@ViewBag.IsLocal' == 'True') that earned you my downvote. You talk about not mixing server side and client side variables and yet that's what you suggest with it.Pipestone
I was trying to give the guy a direct answer to his actual question. He was so close, why over-complicate the answer and hide that from him?Ramonramona
@DaveWard, well, that's your point. Personally I prefer to show good practices rather than showing the OP a direct answer knowing that his approach is wrong and it will work in this case but it will break when he tries to use it in other parts of the code. For example for testing string values that he set in ViewBag. Strings containing single quotes for example. So I just wanted to anticipated his next question when he asks why the following doesn't work: if('@ViewBag.Name' == 'Jeanne d\'Arc')Pipestone
Yes, we have often differed in that way here. :) I think there's merit to both approaches to the answers, and the question is better for having both our answers.Ramonramona
I don't understand why I can't mix server side variables that I pass to a view with client site variables in jquery. I do that all the time. How am I supposed to tell jquery to do something if for example price of the product is 0?Lifesaver
R
21

If you view source on the rendered page, what's being inserted in place of your razor nugget? If IsLocal is a bool type, I think you'll see this:

@if(True == true)
{
  alert("yeah");
}

The reason for that is because true.ToString() is True.

In which case, you'll need to make a string comparison there:

if('@ViewBag.IsLocal' == 'True')
{
  alert("yeah");
}
Ramonramona answered 26/10, 2011 at 15:50 Comment(14)
Neither of your two code snippets will work. There is no alert function defined in .NET. You need to tell the Razor interpreter to not interpret it as server side code and consider it as literal.Pipestone
Of course the first one doesn't work. It wasn't supposed to be an example of working code. Did you even read my answer?Ramonramona
ya this answer is more confused than the OP, it further blurs the line between JS and C#Embayment
If he's trying to do anything serious with the JavaScript, it would be a disaster trying to use Razor's conditional instead of getting the value into the rendered code and letting JavaScript handle it. You have to blur the line one way or the other; might as well blur it in the right direction.Ramonramona
You are missing the point, and you are still wrong. See Darin's answer for the correct seperation of client/server code.Embayment
Darin's answer is a very poor approach for anything more complex than a trivial example. What if the OP needs to test ViewBag.IsLocal and a client-side value in the same conditional, for example? Trying to drive client-side interaction from the server-side is the classic mistake ASP.NET devs have been making for years in WebForms and ASP.NET AJAX. It has been proven to be a bad approach time and time again.Ramonramona
@DaveWard, see my updated answer for an example to handle this case.Pipestone
@Darin: That's much better. I don't understand why you would claim my code doesn't work (it does; test it), but then post something using a refined version of the same approach?Ramonramona
So putting a server side conditional around some JS is a classic mistake, yet putting a server side variable inside of a client side conditional is supposed to be better? That's FAR worse.Embayment
@NeilN: I think you're missing my point. I don't care which syntax you use to get the server-side value injected into JavaScript. The important thing is to get the value to the client-side, instead of trying to run the conditional from the server-side when the page is rendered.Ramonramona
@DaveWard, you are correct. Your code works indeed. I didn't read carefully. I apologize, it's completely my fault. But the syntax seems brittle inside the if condition.Pipestone
Aside from worse code readibility, it does make sense to not send code to the client that you can determine server side will not be used.Embayment
@DarinDimitrov: I agree that the string comparison isn't as nice as the approach you added to your answer. As it stands now, yours is definitely a better approach. I more wanted the OP to be able to see that he was extremely close already, and that his guess about comparing with True was right.Ramonramona
@NeilN: It's a mistake to assume his ultimate goal is all-or-nothing on the client-side code. That happens sometimes, but it's pretty rare. The alert() was probably just a trivial example for simplicity's sake. Usually, you want to run the same, shared client-side code either way, but influence its operation based on the server-side variable.Ramonramona
F
0

You can use the following function

function parseBoolean(str)
{ 
   return /^true$/i.test(str);
}

and Use it as

if(parseBoolean('@ViewBag.IsLocal') == true) 
{ 
   alert("yeah");
}
Foliaceous answered 26/9, 2012 at 12:26 Comment(2)
Insted of doing crazy HTML to highlight your code, use 4 spaces. Check my edit.Architecture
thaks j0k i will consider this in my further Questions and answers.Foliaceous

© 2022 - 2024 — McMap. All rights reserved.