Search code examples
javascriptjqueryloopsgetjson

GetJSON Affecting Only Last Element


I have some movies which I'd like to have posters above them. I tried making a loop for all items and using getJSON with OMDb API to get poster link, but it seem so affect only the last item. I understand JavaScript, but when it comes to jQuery I'm completely lost. I'd appreciate any help. There's no dumb questions, right? :)

I'll let the code do the rest of the talking...

<html>
  <head>
    <script src="http://code.jquery.com/jquery-3.2.1.js"></script>
  </head>
  <body>
    <ul>
      <a href="http://www.imdb.com/title/tt1232829/" target="_blank"><li><h1>21 Jump Street</h1><h2>2012</h2></li></a>
      <a href="http://www.imdb.com/title/tt2294449/" target="_blank"><li><h1>22 Jump Street</h1><h2>2014</h2></li></a>
      <a href="http://www.imdb.com/title/tt1637725/" target="_blank"><li><h1>Ted</h1><h2>2012</h2></li></a>
    </ul>   
    <script>
      function appendPosters() {    
        var lis = document.getElementsByTagName("li");
        for (i = 0; i < lis.length; i++) {                        
          var newImg = document.createElement("img");

          lis[i].appendChild(newImg);
          lis[i].insertBefore(lis[i].lastChild, lis[i].firstChild);

          var getA = lis[i].parentElement;
          var imdbLink = getA.getAttribute("href");
          var imdbId = imdbLink.substr(26, 9);
          var getImg = lis[i].firstChild;

          $.getJSON('http://www.omdbapi.com/?i=' + imdbId).then(function(response) {
            var poster = response.Poster;
            getImg.setAttribute("src", poster);
          });
        }
      }    
      appendPosters();
    </script>    
  </body>
</html>

Please keep in mind that HTML code and variables cannot be changed due to them being a part of other scripts.


Solution

  • Your first issue is that your HTML is invalid. The a elements cannot be children of the ul. You need to place them inside the li.

    From there you can use jQuery to loop over the li elements, finding the href of the a within them. I amended the logic to get the IMDB Id to split the value by the / which should be a lot more robust. Your current method would easily be broken simply by changing to https:// URLs. You can then make the request to get the poster URL. Once that completes you can create the new img element, setting the src as required. Try this:

    function appendPosters() {
      $("li").each(function() {
        var $li = $(this);
        var urlArr = $li.find('a').prop('href').split('/');
        var imdbId = urlArr[urlArr.length -2];
        
        $.getJSON('http://www.omdbapi.com/?i=' + imdbId).then(function(response) {
          $li.append('<img src="' + response.Poster + '" />');
        });
      });
    }
    
    appendPosters();
    <html>
    <script src="http://code.jquery.com/jquery-3.2.1.js"></script>
    <ul>
      <li>
        <a href="http://www.imdb.com/title/tt1232829/" target="_blank">
          <h1>21 Jump Street</h1>
          <h2>2012</h2>
        </a>
      </li>
      <li>
        <a href="http://www.imdb.com/title/tt2294449/" target="_blank">
          <h1>22 Jump Street</h1>
          <h2>2014</h2>
        </a>
      </li>
      <li>
        <a href="http://www.imdb.com/title/tt1637725/" target="_blank">
          <h1>Ted</h1>
          <h2>2012</h2>
        </a>
      </li>
    </ul>