How do you embed a map method inside a map method using jquery, json and custom data attributes

I am creating a rails app. I am using data attribute to capture json.

  <% @image_urls.each_slice(5) do |row| %>
    <% row.each do |_, urls| %>
      <li class="square-image" data-urls=<%= urls.to_json %>>
        <span class="user-image"><%= image_tag(urls.sample) %></span>
      </li>
    <% end %>
  <% end %>

      

With this json I am trying to update the src attribute every second by going to different urls that are in json. Working hours. When I do the first map, I grab the URL successfully.

However, when I do a nested map, I get the error "Uncaught TypeError: undefined is not a function". Right now, I don't have an update to the src part as I am just trying to grab every url within one.

Things I've tried:

  • Change map to each = failed.
  • Play with the $ (url) and $ (u) syntax.

    var time = setInterval(function(){updateImage()}, 1000);
    var square_urls = ($($(".square-image")[0]).data("urls"));
    
      function updateImage(){
        square_urls.map(function(urls){
          urls.map(function(u){
            console.log(u);
          });
        });
      }
    
          

If I don't do the second map, I get the urls successfully.

The second map gives me an error: "Uncaught TypeError: undefined is not a function".

+1


source to share


2 answers


I reworked my thinking to focus on updating one image first; It seems like I was trying to do too much at once and needed to break it. In the updateImage function, I update one square image, find the length by updating it randomly, and then call the randomized url into an array.

After running updateImage, I focused on updating all images. In the updateAllImages function, I can use the updateImage function and not have a nest and hence clutter my code. Note, I was dumped at first since I didn't implement jquery, every method calls the index and value (unlike Ruby), so I had to make sure to add an argument for the index (_ in this case).

The updateAllImages function is called through a time function that is updated every second.

View



  <ul>
  <% @image_urls.each_slice(5) do |row| %>
    <% row.each do |_, urls| %>
      <li class="square-image" data-urls=<%= urls.to_json %>>
        <span class="user-image"><%= image_tag(urls.sample) %></span>
      </li>
    <% end %>
  <% end %>
  </ul>  

      

JQuery

  var squares = $(".square-image");
  var time = setInterval(function(){updateAllImages(squares)}, 1000);

  function updateAllImages(squares) {
    $.each(squares, function(_, square) {
      updateImage(square);
    });
  }

  function updateImage(square) {
    var urls = $(square).data("urls");
    var urlCount = urls.length;
    var randomIndex = Math.floor(Math.random() * urlCount);
    var newUrl = urls[randomIndex];

    // the image currently lives in a span so that why I
    // need to call children twice
    var image = $(square).children().children()[0];
    image.src = newUrl;
  }
});

      

+1


source


I think this is what you are going to do:

var $squares = $(".square-image");
var urls = $squares.map(function(square) { return $(square).data("urls"); });

      

According to jQuery documentation:

The returned array will be flattened into the resulting array.



So, assuming it data-urls

has an array in it, there should be no more work needed to generate all urls from all images.

Note that jQuery's display function is for selection. He had no side effects.

// Use `each` when you want to *do* something instead of *select* something.
$.each(urls, function(url) { console.log(url); });

      

0


source







All Articles