4

Would like to be able to click the images and display data from a second fetch call using the imdbID that matches the clicked poster.

I'm trying to print movie posters to the page - the movie posters will then be clickable - on click they will display Director, actors and year info in a div ("info").

I can't figure out how to make all of the images react to the click event. (I think it's because img id, but I can't get the code to work if I get the images by class). I can get the data from the second fetch but it only works on the first poster and with data from the last image. (The first poster is also the only one that is clickable.

CodeSandbox here: https://codesandbox.io/s/1ojvormxn7

I can console log the data from the second call but it doesn't match the image and I'm not sure how I can print it where it needs to go.

 document.getElementById("searchButton").addEventListener("click", () => {
  const inputSearch = document.getElementById("searchInput").value;
  //console.log(inputSearch);
  fetch(`https://www.omdbapi.com/?apikey=d2d93339&s=${inputSearch}`)
    .then(response => response.json())
    .then(data => {
      console.log(data);
      let posterImage = "";
      let imdb = "";
      data.Search.map(results => {
        //console.log(results.Poster);
        return (
          (posterImage += `<img id="resultPic" class="resultPic" src="${
            results.Poster
          }">`) && (imdb = results.imdbID)
        );
      });
      document.getElementById("app").innerHTML = posterImage;
      document
        .getElementById("resultPic")
        .addEventListener("click", getInfo => {
          fetch(`https://www.omdbapi.com/?apikey=d2d93339&i=${imdb}`)
            .then(response => response.json())
            .then(data => {
              console.log(data);

            });
        });
    });
});
  • Lol... my answer was deleted by a moderator. Cool. – Andrew Koster May 01 '19 at 18:49
  • Dude just comes in and deletes my post without a word, leaves with no explanation. – Andrew Koster May 01 '19 at 18:51
  • return ( (posterImage += ``) && (imdb = results.imdbID) ); What are you trying to do here, exactly? Because it looks to me like you're: Adding HTML for an image to this posterImage string that you're building. Assigning imdb = results.imdbID. Putting the result of these two seemingly unrelated operations together into a boolean expression with &&. It's that last point especially that confuses me. Why are you doing that? – Andrew Koster May 01 '19 at 18:51
  • Another thing to check: that imdb variable. You're assigning a value to it every time you do the map iteration, but you're overwriting it with the next iteration. So at the end of all the map iterations, it will only have the value of the last item in data.Search. Is this your intent? – Andrew Koster May 01 '19 at 18:51
  • It's also weird that you're calling the map function and discarding the result. Look at the description here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map "The map() method creates a new array with the results of calling a provided function on every element in the calling array." It doesn't make sense to use this, instead of a simple interation like forEach or for, unless you're using the result that it's building for you. – Andrew Koster May 01 '19 at 18:52
  • If one of these things solves the problem, let me know, I'll re-post it as an answer and hope it doesn't get deleted again. – Andrew Koster May 01 '19 at 18:53

2 Answers2

1

What you need to do is to use a uniq id for each img tag, to do so, you can use imdbID like this :

<img id=resultPic-${results.imdbID}

This way you always have a uniq id, then after render the img tags, you can map the data again and this time add click event to each img tag, and you don't need really to have another call to the api, you can do it like this :

data.Search.map(results => {
    document
      .getElementById(`resultPic-${results.imdbID}`)
      .addEventListener("click", getInfo => {
        console.log(results);
      });
  });

I update your code here, as you can see on console logs, once you click on each poster, you will rceive data for that poster which you can use it anywhere you want :

https://codesandbox.io/s/p981v90nx

Emad Dehnavi
  • 3,262
  • 4
  • 19
  • 44
1

A few issues I see:

  1. You're assigning the same ID to every image, so your getElementById call is never going to work like you want it to.
  2. Not sure what data.Search.map is supposed to be returning.
  3. Consider event delegation. You can add the listener to a parent element and do something based on the event target. Something like this:
<div id="container">
[images are appended to this container]
</div>

var container = document.getElementById("container");
container.addEventListener("click", (e) => {
    // e.target will return the object the user clicked (e.g. the image)
    // you could perform a fetch based on some attribute you assigned to the image perhaps
})

One way or another you'll need to differentiate the images somehow. You could also create an array of the images and map over that.

Miles Grover
  • 609
  • 3
  • 5
  • Hey Miles, I'm working on a solution that incorporates your answer with another one from above. I'll let you know how it turns out. Thank you for your help! – KristenRen1 May 01 '19 at 21:40