1

I'm having a problem with passing data from one API into another. It works but only after I submit it twice. Perhaps I don't understand Async/await well? Below is the code:

async function mainOne(e) {
  e.preventDefault();

  try {
    const movieFetch = await pullMovie();
    const earningFetch = await convertEarnings(movieFetch);
  
  } catch(err){
    console.log(err)
}

Here are the two functions:

const pullMovie = async () => {

let apiKey = '******'; //Omitted but it does function//
let title1 = movieOne.replaceAll(' ', '+')
let urlOne = `http://www.omdbapi.com/?t=${title1}&apikey=${apiKey}`

const response = await fetch(urlOne);
const data = await response.json();
setMovieOneInfo({
  title: data.Title,
  year: data.Year,
  poster: data.Poster,
  earnings: data.BoxOffice
})
return movieOneInfo; }    
 

Here's the second:

  const convertEarnings = async (movie) => {
      let startingAmount = Number(movie.earnings.replace('$', '').replaceAll(',', ''));
      
      let startingYear = Number(movie.year);
      let url= `https://inflation-api.herokuapp.com/api/?value=${startingAmount}&year=${startingYear}`
      
      let response  = await fetch(url);
      let data = await response.json();

      const formatter = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
        minimumFractionDigits: 2
      })
      
      const formatAdjEarnings = formatter.format(data.response.adjustedValue)

      setMovieOneAdjEarnings(formatAdjEarnings)

      return movieOneAdjEarnings;
      
  }

The first function (pullMovie) feeds the component prop, but if I try to console.log in the mainOne function, it won't display correctly. Can someone please help? Thanks!

bjm
  • 13
  • 2

2 Answers2

0

No, you don't understand enough reaction states. Setting the state is an asynchronous operation. You cannot do this, as movieOneInfo will still refer to the old value:

setMovieOneInfo({
  title: data.Title,
  year: data.Year,
  poster: data.Poster,
  earnings: data.BoxOffice
})
return movieOneInfo;

See more here

Dmitriy Mozgovoy
  • 1,419
  • 2
  • 8
  • 7
  • Thank you!! The previous post you sent helped me fix my issue with useEffect(). – bjm Sep 21 '21 at 18:30
0

Your problem is not on async/await. It's on the state update expectation. React state updates are asynchronous and it's not guaranteed that it's immediately dispatched.

You can extract the state to be updated and return that instead of the state.(check comments in the below code).

You can do this to address your issue:

const pullMovie = async () => {

  let apiKey = '******'; //Omitted but it does function//
  let title1 = movieOne.replaceAll(' ', '+')
  let urlOne = `http://www.omdbapi.com/?t=${title1}&apikey=${apiKey}`

  const response = await fetch(urlOne);
  const data = await response.json();

  // Solution starts here - construct the new state object
  const newMovieInfo = {
    title: data.Title,
    year: data.Year,
    poster: data.Poster,
    earnings: data.BoxOffice
  };
  setMovieOneInfo(newMovieInfo);
  // return the object created above.
  return newMovieInfo ; 
}  
Karthik R
  • 5,523
  • 2
  • 18
  • 30