trigun0x2
trigun0x2

Reputation: 233

Ruby Each loop in Slim

I want to be able to loop through an instance var through a javascript but I'm not quite sure how to make it work.

javascript:
  [email protected] do |spot|
      map.addMarker({
        lat: "#{spot.latitude}",
        lng: "#{spot.longitude}",
        title: "spot",
      });
  });

What I tried: Using <% @spots.each do |spot| %> and without the quotes for the #{}

Upvotes: 7

Views: 10192

Answers (2)

Chen
Chen

Reputation: 584

easy fix but not efficient if spots are too long.

[email protected] do |spot|
  javascript:
    map.addMarker({
      lat: "#{spot.latitude}",
      lng: "#{spot.longitude}",
      title: "spot",
    });

2. loop in js instead of view context

javascript:
  var spots = #{@spots.to_json};
  $(spots).each(function(index, obj) {
    map.addMarker({
      lat: obj.latitude,
      lng: obj.longitude,
      title: "spot",
    });
  });

Upvotes: 2

mr rogers
mr rogers

Reputation: 3260

It seems that once you're in the javascript: slim block, you can't also do the ruby loop.

I was able to get this to mostly work

- @spots.each do |spot|
  javascript:
    map.addMarker({
      lat: #{spot.latitude},
      lng: #{spot.longitude},
      title: "spot"
    });

but that makes separate script tags for each addMarker call which seems pretty dumb.

You could also try putting the data on the page as JSON and then do the loop in Javascript. Something like this:

javascript:
  var spots = #{raw @spots.to_json};
  var ii = 0;
  var nspots = spots.length;
  for(;ii<nspots;++ii) {
    theMap.addMarker(spots[ii]);
  }

You'd want to make sure that theMap is available by the time this stuff runs, but I think this might do the trick. You should also check the JSON format of each @spot. Depending on how you have JSON setup, each spot may look like

{'spot': { 'latitude': ###, 'longitude': ### } } 

which means you'll have to dereference the object in the loop.

Upvotes: 8

Related Questions