0

I'm adding the results of a search to a map using OpenStreetMap. For each returned search result, I need to plot the latitude and longitude on a map as such:

L.marker([39.616886,-86.310997]).addTo(map)
.bindPopup('the institutions name')
.openPopup();

How do I do that within a forEach loop? Here's what I attempted, but I'm getting an error:

The name L doesn't exist in the current context.

@foreach (var u in Model.listschools)
{
    L.marker([@u.lat, @u.longt]).addTo(map)
        .bindPopup(@u.instnm)
    .openPopup();
}
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
Sartorialist
  • 291
  • 2
  • 18
  • Convert the model to a javascript array first - `var list = @Html.Raw(Json.Encode(Model.listschools));` and then loop in a script –  Apr 16 '18 at 22:07
  • 1
    @StephenMuecke Why would one want to do that? Doing it in C# like the OP did is much nicer, unless you want to save the server resources and let the client's machine do the work. For this kind of simple code with no processing, there's not much to be saved, if any, so it's not worth even thinking of it. – Racil Hilan Apr 16 '18 at 22:09
  • 1
    Try wrapping `` tags around it. – nurdyguy Apr 16 '18 at 22:11
  • 1
    @RacilHilan - Are you serious - OP code is javascript! –  Apr 16 '18 at 22:12
  • @StephenMuecke Yes, I am serious, do I look like joking? :). No, the OP's code is not JavaScript. It's C# Razor and JavaScript mix. So what's your point? :P – Racil Hilan Apr 16 '18 at 22:14
  • Refer [this answer](https://stackoverflow.com/questions/30730055/jquery-how-to-traverse-iterate-over-a-list-of-object/30730172#30730172) for an example –  Apr 16 '18 at 22:22
  • Just in case your model is too large to parse using @StephenMuecke 's answer, you can use [this workaround](https://stackoverflow.com/questions/24155468/json-encode-throwing-exception-json-length-exceeded/39277843#39277843) to fix the maxlength issue – mhodges Apr 16 '18 at 22:25
  • @StephenMuecke That's a nice way to do it, but again, I wouldn't do that unless there is a heavy processing required which outweigh the extra time that the serialization will take. In this question, there is no processing at all, so why one would want to pay the extra cost of serialization? Still, it's a nice solution if you like the code to stay all in one language instead of mixing. Why don't you post it as an alternative answer? – Racil Hilan Apr 16 '18 at 22:30

1 Answers1

2

Razor is considering the code inside @foreach as C# code, so you need to tell it that it is not. One way to do so can be by placing it between <text></text>:

@foreach (var u in Model.listschools)
{
    <text>L.marker([@u.lat, @u.longt]).addTo(map)
           .bindPopup('@u.instnm')
           .openPopup();</text>
}

Also notice that you forgot the quotes on this line:

.bindPopup('@u.instnm')
Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
  • `.marker()`, `.addTo()`, `.bindPopup()`, and `.openPopup()` are JavaScript functions from the OpenLayers library. The OP wants to create markers on a map for each lat/long coord in `Model.listschools`. @StephenMuecke is spot on for how to do this in his original comment on the post. – mhodges Apr 16 '18 at 22:21
  • Yes, I understand that, he wants to generate JavaScript code within the `foreach` loop. Stephen Muecke's way can do the job too, but it's not the only way and not what the OP is asking for. The OP clearly asked how to insert the model values in the JavaScript code. Anyway, my answer will do the job too, so why you think it's wrong? You can favour Stephen Muecke's way, but that doesn't make mine wrong. – Racil Hilan Apr 16 '18 at 22:26
  • 1
    I think this answer is closer to the OP's actual question than StephenMuecke's comment/solution, though I agree it could be done either way. The original error the OP was getting was because of the missing `` tags but @RacilHilan also caught the missing quotes. – nurdyguy Apr 16 '18 at 22:28
  • I see what you mean. I guess I've always considered it bad practice to write C# within JavaScript, but it would work nonetheless. – mhodges Apr 16 '18 at 22:29
  • @mhodges A bad practice? Why? Stephen Muecke's is also writing C# withing JavaScript :P. He assigned the result of the serialization to a JavaScript variable, didn't he? There are many cases where you cannot avoid even having C# code in between the JavaScript lines. There is absolutely nothing wrong with it. But like I said in my comment to Stephen, if you prefer to keep the code in one language (as much as possible), then sure, do it in the way you like. But saying that the other ways is wrong and not what the OP wants? It seems you changed your attitude about that, which is welcomed :) – Racil Hilan Apr 16 '18 at 22:37
  • @RacilHilan Assigning a single variable does not equate to writing loops and dealing with static typing, using different library functions, namespacing, different syntax, different code conventions, etc. I'm afraid you took me too literally lol. Either way, it's a functional answer, but I still consider it bad practice. Can't get my upvote, but i've removed the downvote. – mhodges Apr 16 '18 at 22:46
  • @RacilHilan Not to mention, you have to rewrite a lot of code if you decide to go away from Razor templates, or C# on your backend. If you pass the variable in and let the JavaScript do the work, you have a pretty clear separation of concerns. You can pass in the data however you'd like and your JavaScript will all still function the same. – mhodges Apr 16 '18 at 22:49
  • @mhodges No, I didn't take you literally. I know exactly what you meant. It was half joke half true, notice the `:P` smiley :). If you read my comments to Stephen, I did say that it looks cleaner in one language, but you're paying the cost of serialization. You decide if that's worth it, but in some scenarios you just cannot separate. And, that has nothing to do with the separation of concerns. See, your C# application is generating HTML and that's what it's meant to do. Similarly, it can generate JavaScript and CSS. That's part of its rendering job. – Racil Hilan Apr 16 '18 at 22:59
  • @RacilHilan `consistency + readability + maintainability < a few ms of performance gain`, got it. – mhodges Apr 16 '18 at 23:06
  • @mhodges Agreed, but you're making assumptions. Let me give you an example. We have no idea about the OP's `Model.listschools`, how many properties it has, and how it is used outside the code in the question. Let's say it has 20 properties that are used to render HTML, and it has 100 items. You're serializing the all the 20 properties for 100 items only to use 3, so that's 17x100=1700 needless serializations. ;) Again, you can decide whether to pay that price. And if the same list is used in other JS code that cannot be in the same block, and you use the same method, that's 3400 extra ;). – Racil Hilan Apr 16 '18 at 23:11