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;
};
The way I see it, you need to return promise(I mean need to return axios
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
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;
};