Home > Software design >  How to insert data from another API call into function
How to insert data from another API call into function

Time:05-04

I am building a project website which uses the rawg api to fetch data about games and displays them on the screen. I have also implemented a search functionality. My function getGame is using the base url which is called API_URL. My problem is that the data returned by this link does not return description as one of its variables. It has other stuff like game id and game name etc but no description. I have checked the docs and it says that in order to get the details of a game i need to use a different fetch link which takes in id as a parameter. So i implemented another function called getDescription() which takes in an id from the games.forEach function. I am able to console log all the descriptions of the games that are being displayed. My question is how would i be able to insert the description into the dom inside my showGames function. My code is attached below. Thanks.

const API_URL = `https://api.rawg.io/api/games?key=${apiKey}&page=5&page_size=40`;
const SEARCH_API = `https://api.rawg.io/api/games?key=${apiKey}&search="`;
const form = document.getElementById('form');
const search = document.getElementById('search-game');
const main = document.getElementById('main');

getGames(API_URL)
async function getGames(url){
  const request = await fetch(url)
  const response = await request.json()
  showGames(response.results)
}

async function getDescription(id){
  const request = await fetch(`https://api.rawg.io/api/games/${id}?key=${apiKey}`)
  const response = await request.json();
  showDescription(response.description)
}

function showGames(games){
  main.innerHTML = '';
  games.forEach(game => {
    const { background_image, name, released, rating_top, id } = game;
    const gameEl = document.createElement('div');
    const platform = game.parent_platforms.map(platform => platform.platform.name).join(', ');
    getDescription(id)
    gameEl.classList.add('card');
    gameEl.innerHTML = `
    <div >
      <img src="${background_image}" alt="" >
    </div>
    <div >
    <div >
      <h1 >${name}</h1>
      <h3>Release date: ${released}</h3>
      <p>Platforms: <span>${platform}</span></p>
      <p>*****I WANT TO ENTER THE DESCRIPTION HERE*****</p>
    </div>
      <div >
        <span >${rating_top}</span>
      </div>
    </div>
    `;
    main.appendChild(gameEl);
  })
}

Edit Here is my console log for response inside getDescription function Console log

I was able to get my wanted output by adding async right after my forEach like this games.forEach(async game => {....}) Here is my working code

const API_URL = `https://api.rawg.io/api/games?key=${apiKey}&page=5&page_size=40`;
const SEARCH_API = `https://api.rawg.io/api/games?key=${apiKey}&search="`;
const form = document.getElementById('form');
const search = document.getElementById('search-game');
const main = document.getElementById('main');

getGames(API_URL)
async function getGames(url){
  const request = await fetch(url)
  const response = await request.json()
  showGames(response.results)
}

async function getDescription(id){
  const request = await fetch(`https://api.rawg.io/api/games/${id}?key=${apiKey}`)
  const response = await request.json();
  return response;
}

function showGames(games){
  main.innerHTML = '';
  games.forEach(async game => {
    const { background_image, name, released, rating_top, id } = game;
    const gameEl = document.createElement('div');
    const platform = game.parent_platforms.map(platform => platform.platform.name).join(', ');
    const response = await getDescription(id)
    gameEl.classList.add('card');
    gameEl.innerHTML = `
    <div >
      <img src="${background_image}" alt="" >
    </div>
    <div >
    <div >
      <h1 >${name}</h1>
      <h3>Release date: ${released}</h3>
      <p>Platforms: <span>${platform}</span></p>
      <p>${response.description}</p>
    </div>
      <div >
        <span >${rating_top}</span>
      </div>
    </div>
    `;
    main.appendChild(gameEl);
  })
}

CodePudding user response:

As you said that getDescription function just returns a string, so you can do something like this

async function getDescription(id){
  const request = await fetch(`https://api.rawg.io/api/games/${id}?key=${apiKey}`)
  const response = await request.json();
  //showDescription(response.description)
  //instead of using a function, just return the response from this func
  return response
}

function showGames(games){
  main.innerHTML = '';
  games.forEach(game => {
    const { background_image, name, released, rating_top, id } = game;
    const gameEl = document.createElement('div');
    const platform = game.parent_platforms.map(platform => platform.platform.name).join(', ');
    //save response into a variable
    const response = getDescription(id)
    gameEl.classList.add('card');
    gameEl.innerHTML = `
    <div >
      <img src="${background_image}" alt="" >
    </div>
    <div >
    <div >
      <h1 >${name}</h1>
      <h3>Release date: ${released}</h3>
      <p>Platforms: <span>${platform}</span></p>
      <p>${response.description}</p>
    </div>
      <div >
        <span >${rating_top}</span>
      </div>
    </div>
    `;
    main.appendChild(gameEl);
  })
}

Then use that variable response.description in the html string literal

CodePudding user response:

You should be able to save the response of showDescription in a variable and then include it in your inner Html.

What it struggle with this is the fact that if array.forEach has a callback that returns a promise (like the async showDescription()), the javascript engine will not wait it to be resolved or rejected, so console will show an error that description is null.

There is a nice question where you can find how to loop promises here

You have to update getDescription like this:

async function getDescription(id){
  const request = await fetch(`https://api.rawg.io/api/games/${id}?key=${apiKey}`)
  const response = await request.json();
  return response.description;
}

edit showGames like this

async function showGames(games) {
...

and use for inside showGames

 for (const game of games) {
    const description = await getDescription(game.id)
...
  }

Every loop will wait getDescription() to be completed before start the next loop

  • Related