Peter T. Walker
Peter T. Walker

Reputation: 322

Making api requests on an array of objects using async/await and Promise.all()

I'm creating a simple book search app, I make an initial api request to get an array of book objects, then I need to make an api request on each individual book to get the dimensions. When I console.log the initial array of books the book objects have the added attribute('height'), but I believe it is because the array is updated after I make my api calls. Then when I console.log the array after I make the individual api calls I'm given an array of promises. Last when I Promise.all() the array of promises they all come back undefined. I've been playing around with async/await for a bit and would appreciate any tips or feedback you think would help me figure out how to be able to return an array of my books with the "height" attribute I add in the individual api calls.

    
    searchBook = (event) => {
    event.preventDefault();
    axios
      .get(
        "https://www.googleapis.com/books/v1/volumes?q=" +
          this.state.searchField +
          "&key=" +
          this.state.apiKey
      )
      .then((data) => {
        //fill in missing attributes
        const cleanData = this.cleanData(data.data.items);

        //filter books for specific author
        const filterAuthor = this.filterAuthor(cleanData);

        //add height attribute to book
        const addHeight = this.addHeight(filterAuthor);

        console.log(filterAuthor); //returns array of book objects

        console.log(addHeight); //returns array of promises

        Promise.all(addHeight).then((data) => {
          console.log(data); //returns array of undefined
        });
        //this.setState({ books: addHeight }); 
      });
  };

  //add 'height' attribute to book objects
  addHeight = (data) => {
    const addHeight = data.map(async (book) => {
      await axios
        .get(
          "https://www.googleapis.com/books/v1/volumes/" +
            book.id +
            "?key=" +
            this.state.apiKey
        )
        .then((data) => {
          if (data.data.volumeInfo?.dimensions) {
            book["height"] =
              data.data.volumeInfo.dimensions.height.split(" ")[0] / 2.54; //convert cm to in
          } else {
            book["height"] = "0";
          }
          return book;
        });
    });
    return addHeight;
  };

Upvotes: 1

Views: 1066

Answers (1)

Stark Jeon
Stark Jeon

Reputation: 1145

TLDR

The way I see it, you need to return promise(I mean need to return axios

Answer

I think there is no return value in promise object. when you use async/await at const addHeight = data.map(async (book)=> {...}) this callback can't return anything. So when you return axios, your promise can get right data

Example

 addHeight = (data) => {
    const addHeight = data.map((book) => {
     return axios
        .get(
          "https://www.googleapis.com/books/v1/volumes/" +
            book.id +
            "?key=" +
            this.state.apiKey
        )
        .then((data) => {
          if (data.data.volumeInfo?.dimensions) {
            book["height"] =
              data.data.volumeInfo.dimensions.height.split(" ")[0] / 2.54;
          } else {
            book["height"] = "0";
          }
          return book;
        });
    });
    return addHeight;
  };

Upvotes: 0

Related Questions