Reputation: 25
Its my first work with async/await
i call several api methods and tryne inject data from response body to html-DOM
as you can see i added some async await because i make call to other function with catch
and this works really fine (as i can see from console.log)
but when i trying insert my result to html it returning "undefined"
i have done some tips with return new Promise, but nothing help
async function getProduct(productId) {
var productTitle = '';
return fetch('http://193.176.79.173/api/products/' + productId, {
method: 'GET'
})
.then((response) => response.json())
.then(function(data) {
return data['data']['title'];
})
}
async function getProducts(orderId) {
fetch('http://193.176.79.173/api/orders/20210524155243107', {
method: 'GET'
})
.then((response) => response.json())
.then(async function(data) {
var productsText = '';
console.log(data);
for (var i = 0; i < data['orderProducts'].length; i++) {
var product = await getProduct(data['orderProducts'][i].product_id);
console.log(product);
productsText += '<div class="mdl-card__title">' +
'<h2 class="mdl-card__title-text">' + await getProduct(data['orderProducts'][i].product_id) +
'/h2>';
console.log(productsText);
}
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(productsText);
}, 1000);
});
})
}
var myList = document.querySelector('#list');
async function drawTable() {
fetch('http://193.176.79.173/api/paidOrders/')
.then((response) => response.json())
.then(async function(data) {
var products = '';
for (var i = 0; i < data.data.length; i++) {
var listItem = document.createElement('div');
var orderId = data.data[i].id;
orderIdNew = orderId.toString();
var lastChar = orderIdNew.substr(orderIdNew.length - 1);
lastChar = parseInt(lastChar, 10) - 1;
var orderIdNewNew = orderIdNew.replace(/.$/, lastChar);
listItem.id = orderIdNewNew;
products = await getProducts(orderIdNewNew);
listItem.classList.add("mdl-card", "mdl-shadow--2dp", "mdl-cell", "mdl-cell--4-col");
listItem.innerHTML = '<div style="padding: 16px"> Заказ № ' + orderIdNewNew +
'<div class="flex"><b>Статус:</b> ' + data.data[i].status + '</div>' +
'<div class="flex"><b>Сумма:</b> ' + data.data[i].summ + '</div>' +
'<b>Состав заказа:</b> </div>' +
products +
'</div>'
myList.appendChild(listItem);
}
})
.then((data) => {
console.log(data);
});
}
setTimeout(function() {
drawTable()
}, 2000);
But in the end i get undefined instead of "products" value
Upvotes: 2
Views: 5058
Reputation: 554
It seems like a code management problem. Unfortunately, I can't test it to solve it for you, but I've noticed a few issues.
The first one (like @Bergi mentioned) is that the two functions getProducts
and drawTable
don't return anything
The second issue is that you're not really taking full advantage of async
& await
, for example, you can write the functiongetProduct
like so:
async function getProduct(productId) {
var productTitle = '';// this is useless btw
let response = await fetch('http://193.176.79.173/api/products/' + productId, {
method: 'GET'
});
let json = await response.json();
let result = json['data']['title'];
return result;
}
This way you can make the code lot easier to read and debug
So try replacing all .then(
with async
/await
syntax, and add return
to getProducts
and drawTable
, then you'll notice the error
And finally, if you're new to async
/await
I would recommend you those two videos:
16.13: async/await Part 1 - Topics of JavaScript/ES8
16.14: async/await Part 2 - Topics of JavaScript/ES8
They're very similar to your case
Upvotes: 4
Reputation: 125
agree to the 2 comments above. You have to return something inside a async function, or throw an exception, that lead to .then or .catch.
You can await a fetch.then(...toJSON...) that returns a normal object inside a async function. Or make a long chain calling, put all codes inside .then(...).
see documents at:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Upvotes: 0