Home > Software design >  get data from array of functions
get data from array of functions

Time:04-05

i got the data from this array but when i add it to the loop to show all the arrays it only show me only one array help pleaseeee

this is the problem : https://i.imgur.com/huAv70U.png

the function to get data from api ( the problem isnt here this works fine )

function Movie(id){
fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=${apikey}`)
    .then((res) => res.json())
    .then((data) => {
    name = data.original_title;
    img = data.poster_path;
    link = name.replace(/[^a-zA-Z\s/ ]/g, "")
    var MyArray = {'name':`${name}`, 'img':`${img}`, 'link':`/movies/${link}.html`}
    console.log(MyArray)
    })
    .catch(err => {
        console.error(err);
    });
}

The Array :

var MyMovies = [
    Movie(238),
    Movie(899082),
    Movie(899),
]

the function to display all arrays (the problem is here i think)

function LoadMovies(){
    buildTable(MyMovies)
    function buildTable(data){
        var table = document.querySelector('#movies')
    
        for (var i = 0; i < data.length; i  ){
            var row = `<img id="img" src="${"https://image.tmdb.org/t/p/w342/"   img}" alt="${name}"  onclick="location.href='${link}';">`
            table.innerHTML  = row
        }
    }
}

the console.log show this : Uncaught TypeError: Cannot read properties of undefined (reading 'img')

CodePudding user response:

The main problem is that you Movie function doesn't return anything. You need to return the results of the fetch method. And later you need to use Promise.all(MyMovies) to get all results from the all Movie() calls.

This is how you need to do it:

async function Movie(id) {
  return fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=${apikey}`)
    .then((res) => res.json())
    .then((data) => {
      name = data.original_title;
      img = data.poster_path;
      link = name.replace(/[^a-zA-Z\s/ ]/g, "");
      return {
        name,
        img,
        link: `/movies/${link}.html`
      };
    })
    .catch((err) => {
      console.error(err);
    });
}

const MyMovies = [Movie(238), Movie(899082), Movie(899)]

async function LoadMovies() {
  const table = document.querySelector("#movies");
  const movies = await Promise.all(MyMovies);

  movies.forEach((m) => {
    var row = `<YOUR_RAW>`;

    table.innerHTML  = row;
  });
}

CodePudding user response:

you are trying to access img inside for loop that's not defined. You can get these values from data like :-

var row = "<img id="img" src="${"https://image.tmdb.org/t/p/w342/" data[i].img}" alt="${data[i].name}" onclick="location.href='${data[i].link}';">

or you can use spread operator to get the values:-

const {img,link,name}= data[i]; <img id="img" src="${"https://image.tmdb.org/t/p/w342/" img}" alt="${name}" onclick="location.href='${link}';">

Hope this will resolve your issue!!

CodePudding user response:

The img is undefined in the case the API doesn't return anything or when the API is processing. Use async/await to wait until the API return something, once you get the data, img will be assigned a value and there would be no error. Use this piece of code:

async function Movie(id) {
  return fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=${apikey}`)
    .then((res) => res.json())
    .then((data) => {
      name = data.original_title;
      img = data.poster_path;
      link = name.replace(/[^a-zA-Z\s/ ]/g, "");
      return {
        name,
        img,
        link: `/movies/${link}.html`
      };
    })
    .catch((err) => {
      console.error(err);
    });
}

const MyMovies = [Movie(238), Movie(899082), Movie(899)]

async function LoadMovies() {
  const table = document.querySelector("#movies");
  const movies = await Promise.all(MyMovies);

  movies.forEach((m) => {
    var row = `<YOUR_RAW>`;

    table.innerHTML  = row;
  });
}

OR

you can wrap your for loop in if condition,

function LoadMovies(){
    buildTable(MyMovies)
    function buildTable(data){
        var table = document.querySelector('#movies')
    if(img){
        for (var i = 0; i < data.length; i  ){
            var row = `<img id="img" src="${"https://image.tmdb.org/t/p/w342/"   img}" alt="${name}"  onclick="location.href='${link}';">`
            table.innerHTML  = row
        }
}
    }
}

CodePudding user response:

I find multiple errors. First of all, you need the values of all Promise results. I would do it like this:

var MyMovies = [
    238,
    899082,
    899,
];

// Promise.all stops, if one request fails, this method doesn't.
var index = 0;
var answers = [];
(function loop() {
    var value = MyMovies[index];
    fetch(`https://api.themoviedb.org/3/movie/${value}?api_key=${apikey}`)
    .then((res) => res.json())
    .then(data => {
        var link = data.original_title.replace(/[^a-zA-Z\s/ ]/g, "");
        answers.push({
            name: data.original_title,
            img: data.poster_path,
            link: `/movies/${link}.html`,
        });
    });
    index  ;
    if (index < MyMovies.length) {
        loop();
    }
})();
buildTable(answers);

after that, you should be able to iterate over the array, like you do. Just make sure, you also access to the object

function buildTable(data){
    var table = document.querySelector('#movies');
    for (var i = 0, o; o = data[i]; i  ){
        var row = `<img id="img" src="https://image.tmdb.org/t/p/w342/${o.img}" alt="${o.name}"  onclick="location.href='${o.link}';">`
        table.innerHTML  = row
    }
}
  • Related