In this case I fetch review data from inside a 'for loop' as you can see here:
fetch('https://api.yotpo.com/products/xx-apikey-xx/{{product.id}}/bottomline')
As not all of the products have reviews, and thus not available which gives a 404 response back for that products. This gives me a lot of errors in the console because the specific id doesn't exist (getElementById ...).
<script>
fetch('https://api.yotpo.com/products/xx-apikey-xx/{{product.id}}/bottomline').then(function (response) {
if (response.ok) return response.json();
}).then(function (obj) {
var averageScore = (obj).response.bottomline.average_score;
var averageTen = averageScore * 2;
var averageOverlay = 100 - averageScore * 20;
var reviewCount = (obj).response.bottomline.total_reviews;
var reviewCountText = "reviews";
console.log(obj);
document.getElementById("jsonproductreviewcount-{{ product.id }}").innerHTML = "<span class='reviewCount d-flex'>" + reviewCount + " " + reviewCountText + "</span>";
document.getElementById("sterrenOverlay-{{ product.id }}").style.width = averageOverlay + "%";
}).catch(function (error) {
console.error('Oops! Errrrrorrr...');
console.error(error);
})
</script>
Should I use some IF / ELSE statement to check if the productid / response gives a 200 code? But how?
Although the people who created fetch apparently disagree, to my mind a non-success response is an error, so I always treat it as one; see ***:
fetch('https://api.yotpo.com/products/xx-apikey-xx/{{product.id}}/bottomline')
.then(function (response) {
if (!response.ok) { // ***
throw new Error(`HTTP error ${response.status}`); // ***
} // ***
return response.json();
})
.then(function (obj) {
var averageScore = (obj).response.bottomline.average_score;
var averageTen = averageScore * 2;
var averageOverlay = 100 - averageScore * 20;
var reviewCount = (obj).response.bottomline.total_reviews;
var reviewCountText = "reviews";
console.log(obj);
document.getElementById("jsonproductreviewcount-{{ product.id }}").innerHTML = "<span class='reviewCount d-flex'>" + reviewCount + " " + reviewCountText + "</span>";
document.getElementById("sterrenOverlay-{{ product.id }}").style.width = averageOverlay + "%";
})
.catch(function (error) {
console.error('Oops! Errrrrorrr...');
console.error(error);
});
That will transfer control from your first then callback to your catch callback.
A couple of side notes:
(obj).xyz, just use obj.xyz.var is effectively deprecated; new code should be written with let and/or const.async/await rather than explicit promise callback functions.For what it's worth:
fetch("https://api.yotpo.com/products/xx-apikey-xx/{{product.id}}/bottomline")
.then((response) => {
if (!response.ok) { // ***
throw new Error(`HTTP error ${response.status}`); // ***
} // ***
return response.json();
})
.then((obj) => {
const { average_score, total_reviews } = obj.response.bottomline;
const averageTen = average_score * 2;
const averageOverlay = 100 - average_score * 20;
const reviewCountText = "reviews";
console.log(obj);
document.getElementById("jsonproductreviewcount-{{ product.id }}").innerHTML =
`<span class="reviewCount d-flex">${total_reviews} ${reviewCountText}</span>`;
document.getElementById("sterrenOverlay-{{ product.id }}").style.width = averageOverlay + "%";
})
.catch((error) => {
console.error("Oops! Errrrrorrr...");
console.error(error);
});