Access javascript variable in template loop

Asked

Viewed 1,604 times

3

I am creating an Asp.Net MVC project and found a problem in View. See the code:

<script>
var data = [];

for (var i = 0; i < '@(Model.Count())'; i++) {
    data[i] = {
        "source": '@(Model.ElementAtOrDefault(0).Source)',
        "percentage": '@(Model.ElementAtOrDefault(0).Percentage)'
    };
}
</script>

Well, what I need is simple! Instead of passing a fixed index (in case 0), I need to pass the value of i, but it was declared in javascript and I can’t access it inside the expression where I get the model value.

  • 1

    A "source": '@(Model.ElementAtOrDefault('+i.toString()+').Source)' did not resolve?

  • Opa my brother, unfortunately I had already tried, but not sure, because when the parentheses after the arroba is opened, he sees the '+i.toString()+' as a literal string.

4 answers

5

That can’t be done.

The expression @(Model.ElementAtOrDefault(0).Source) has to be evaluated on the server side, before of the html being sent to the browser and therefore, before of javascript being executed.

As the value of i is dynamic and will only be known when javascript is executed in the browser, it is impossible to use the variable i in the expression.

The solution is to convert all elements of the model to two arrays in javascript out of loop using for example Model.Select(x => x.Source) and Model.Select(x => x.Percentage) (this can be evaluated on the server side), and then use the javascript arrays within the loop.


Edit

Based in this answer, I think the syntax is as follows:

var elems = [];

@foreach (var elem in Model)
{
    @:elems.push(
              new {
                   source = @elem.Source
                   percentage = @elem.Percentage
              });
}
  • Now yes! It was very clear, would you have any example code for that? model is the type Ienumerable<T> and I’m having trouble putting everything on an array.

  • 1

    @Jedaiasrodrigues Actually, you have to use two arrays. I edited the answer, I hope it helps! :)

  • Dude, you’re a big shot! But I couldn’t make it work... :( See: var modelSource = new Array();&#xA; modelSource = @Model.Select(x => x.Source);

  • 1

    @Jedaiasrodrigues Hmm I have little experience with Razor syntax, but try this post: Razor MVC Populating Javascript array with Model Array

  • 1

    @Jedaiasrodrigues Based on this example, I updated the answer with the syntax that I think be correct.

  • Dude, it makes a lot of sense what you did, but you’re not getting the data. I’m giving an analysis, thank you very much.

Show 1 more comment

1

Try using the syntax razor and then assign the value of a array generated for the variable javascript.

Something like that:

@{
   var vetor = new object[Model.Count()];
}

@for (int i = 0; i < Model.Count(); i++)
{
    vetor[i] = new {
                 source = Model.ElementAtOrDefault(i).Source,
                 percentage = Model.ElementAtOrDefault(i).Percentage
               };
}

and then on javascript just assign the array for the variable.

<script>
    var data = @vetor;
</script>
  • Top of line its logic, but unfortunately there is an error when creating the vector variable. Invalid Expression term 'Object'

  • 1

    I changed the answer. There was one missing new before objet[Model.Count()]. try it there

  • Dude, it makes a lot of sense what you did, but you’re not getting the data. I’m giving an analysis, thank you very much.

  • The problem is only time to assign the array of razor in the array of javascript, just doesn’t work. But all your syntax razor is working perfectly! There just seems to be some kind of incompatibility...

1


Gentlemen, unfortunately none of the answers worked at first, but they helped and helped a lot to arrive at the solution!
I believe that the problem was basically some kind of incompatibility between the type of variable array of Razor with javascript, so I had to pass the data manually.
The code should be like this:

<script>
var indexJS = 0;
var data = [];
@{
    for (int i = 0; i < Model.Count(); i++)
    {
        @:(data[indexJS] = { "source" : '@Model.ElementAtOrDefault(i).Source', "percentage": '@Model.ElementAtOrDefault(i).Percentage' });
        @:(indexJS++);
    }
}
</script>

Well, it turns out I can only control the index of model using razor, then I use the variable i of the loop for that I created inside Razor @{} to control the indexes, and inside the loop I can access the variable data javascript created using @: and controlling the index of such an array with a javascript variable indexJS.
I hope this will also help someone else in the future. And thank you very much for all the help!

1

I solved with the help of another post !!


For any Model in your project, for example

@model IEnumerable<ProjetoNamespace.Models.SeuModelo>

To access such a list one must use :

<script>
   var minhaLista = @Html.Raw(Json.Encode(Model));
   for(var i = 0; i < minhaLista.length; i++){
       var elementoLista = minhaLista[i];
       //acesse os atributos a partir do elemento !
       //elementoLista.<atributo>
   }
</script>

That’s it, guys, I hope to help someone !

Browser other questions tagged

You are not signed in. Login or sign up in order to post.