-2

I'm using fetch to get information, sometimes it shows everything well, sometimes if shows nothing everything is undefined, and sometimes it shows some data well with some data as undefined. the images shows my issue:

enter image description here

and that's my code:

// fetch the movies from API

class Movie {

  constructor(id) {
    this.id = id;
    this.load();
  }
  finalize(json) {
    this.name = json.original_title;
    this.img = json.poster_path;
    this.link = name.replace(/[^a-zA-Z\s/ ]/g, "");
    var MyArray = {
      'name': `${this.name}`,
      'img': `${this.img}`,
      'link': `/movies/${this.link}.html`
    }
    console.log(MyArray)
  }

  load() {
    fetch(`https://api.themoviedb.org/3/movie/${this.id}?api_key=a913ee104db6b795d20852a9ed989036`)
      .then((res) => res.json())
      .then((json) => {
        this.finalize(json)
      })
      .catch(err => {
        console.error(err);
      });
  }

}

// The array of movies

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

// show the movies in the page

function LoadMovies() {
  var table = document.querySelector('#movies')
  for (var i = 0; i < MyMovies.length; i++) {
    var item = MyMovies[i];
    var row = `<img id="img" src="${'https://image.tmdb.org/t/p/w185/' + item.img}" alt="${item.name}" class="thumb" onclick="location.href='${"movies/" + item.link + ".html"}'">`
    table.innerHTML += row
  }
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
moncef
  • 3
  • 5
  • Really hard to say - what is the response of the http request? What does the data look like? I'd start there – Tom Apr 10 '22 at 22:21
  • `new Movie()` doesn't wait for the async fetch to complete. I don't think there's a way to wait for an asynchronous class constructor. See https://stackoverflow.com/questions/43431550/async-await-class-constructor – Barmar Apr 10 '22 at 22:23
  • @Tom the data look like this : ```{ 'name': `${this.name}`, 'img': `${this.img}`, 'link': `/movies/${this.link}`}``` – moncef Apr 10 '22 at 22:26
  • @Barmar so how can i fix that, can you answer with the solution please ? – moncef Apr 10 '22 at 22:26
  • @jabaa can you answer by the solution? – moncef Apr 10 '22 at 22:30

2 Answers2

0

You can wait until all movies are initialized:

// fetch the movies from api

class Movie {

  constructor(id) {
    this.id = id;
    this.isInitialized = this.load();
  }
  finalize(json) {
    this.name = json.original_title;
    this.img = json.poster_path;
    this.link = name.replace(/[^a-zA-Z\s/ ]/g, "");
    var MyArray = {
      'name': `${this.name}`,
      'img': `${this.img}`,
      'link': `/movies/${this.link}.html`
    }
    console.log(MyArray)
  }

  load() {
    return fetch(`https://api.themoviedb.org/3/movie/${this.id}?api_key=a913ee104db6b795d20852a9ed989036`)
      .then((res) => res.json())
      .then((json) => {
        this.finalize(json)
      })
      .catch(err => {
        console.error(err);
      });
  }

}

// The array of movies

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

// show the movies in the page

async function LoadMovies() {
  var table = document.querySelector('#movies');
  await Promise.all(MyMovies.map(movie => movie.isInitialized));
  for (var i = 0; i < MyMovies.length; i++) {
    var item = MyMovies[i];
    var row = `<img id="img" src="${'https://image.tmdb.org/t/p/w185/' + item.img}" alt="${item.name}" class="thumb" onclick="location.href='${"movies/" + item.link + ".html"}'">`
    table.innerHTML += row
  }
}

LoadMovies();
<table id="movies">

</table>
jabaa
  • 5,844
  • 3
  • 9
  • 30
0

The constructor doesn't wait for the fetch to complete, so you're trying to use all the Movie objects before the information has been fetched. There's no way to await a class constructor, because it always returns a class instance, not a promise (see Async/Await Class Constructor).

Instead of calling this.load() in the constructor, do it in the loop.

class Movie {

  constructor(id) {
    this.id = id;
  }
  finalize(json) {
    this.name = json.original_title;
    this.img = json.poster_path;
    this.link = name.replace(/[^a-zA-Z\s/ ]/g, "");
    var MyArray = {
      'name': `${this.name}`,
      'img': `${this.img}`,
      'link': `/movies/${this.link}.html`
    }
    console.log(MyArray)
  }

  load() {
    fetch(`https://api.themoviedb.org/3/movie/${this.id}?api_key=a913ee104db6b795d20852a9ed989036`)
      .then((res) => res.json())
      .then((json) => {
        this.finalize(json)
      })
      .catch(err => {
        console.error(err);
      });
  }

}

// The array of movies

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

// show the movies in the page

async function LoadMovies() {
  var table = document.querySelector('#movies')
  for (var i = 0; i < MyMovies.length; i++) {
    var item = MyMovies[i];
    await item.load();
    var row = `<img id="img" src="${'https://image.tmdb.org/t/p/w185/' + item.img}" alt="${item.name}" class="thumb" onclick="location.href='${"movies/" + item.link + ".html"}'">`
    table.innerHTML += row
  }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612