Fetching data from a API with javascript fetch and promise

Can anyone guide me in the right direction? I can’t seem to get this code to work. I do feel like I am on the verge of getting it but for some reason, I cant see the solution.

My objective is to fetch data from multiple APIs and display the relevant data in my HTML.

So I got everything working fine until I had to retrieve the profile information of the consumers. This is due to the fact that I need to call the one API to get an id from it and using that id, construct the profile API and then retrieve that data.

This is my HTML

<div class="section trustpilot">
    <div class="container">
        <div id="compInfo" class="row"></div>
        <div id="tpwidget" class="row"></div>
    </div>
</div>

This is my Javascript

<script>

function reviewTemplate(info) {

 function consumer1() {
     const consumerId = info.consumer.id;
      const httpUrl = 
    `https://api.trustpilot.com/v1/consumers/${consumerId}/profile? 
     apikey=*myapikey*`

    return fetch (httpUrl)
   .then(res => res.json())

}

 return `
<div class="col-md-6">
    <div class="review">
        <div class="title"><h6>${info.title}</h6></div>
        <div class="comment"><p>${info.text}</p></div>
        <div class="displayname col-md-6"><p>${info.consumer.displayName} 
        </p></div>
        <div class="row">
          <div class="timePassed col-md-6">${ 
           moment(info.createdAt).fromNow() }</div>
           <div class="col-md-6"></div>
        </div>
     </div>
</div>
 `
}

function compTemplate(rate) {
return `
   <div class="col-md-6">
       <div class="review">
           <div class="title"><h6>${rate.total}</h6></div>
           <div class="comment"><p>${rate.fiveStars}</p></div>
       </div>
   </div>
    `
}


 // FUNCTION LOADS ON PAGE LOAD

 window.onload = function() {
   "use strict";

     // SETS TRUSTPILOT URLS AS AN ARRAY
   const urls = [
     "https://api.trustpilot.com/v1/business-units/4fa8fbc8000064000515212e/reviews/? stars[]=4&stars[]=5&apikey=*myapikey*",
"https://api.trustpilot.com/v1/business-units/46d6a890000064000500e0c3?apikey=*myapikey*", 
"https://api.trustpilot.com/v1/resources/images/stars/4?apikey=*myapikey*",
"https://api.trustpilot.com/v1/resources/images/logos?apikey=*myapikey*"
];

  // MAKES A CALL TO EACH URL IN ARRAY AND RETURNS AN ARRAY OF OBJECTS
    Promise.all(urls.map(url =>
  fetch(url).then(resp => resp.json())
  ))

  // RETURNS THE REVIEWS OBJECT
  .then(data => {

  function getreviews(data) {
        return data.reviews; 
  };

  // RETURNS NUMBER OF REVIEWS AS AN ARRAY
  function getNumReviews(data) {
    return data.numberOfReviews;
  };

  // RETURNS LIGHTBACKGROUND ARRAY OF TP LOGOS
 function getTpLogo(data) {
     return data.lightBackground;
  };

  // SETS STAR RATING WORDING ACCORDING TO NUMBER SYMBOL 

function starRatingWords(sr) {
    if (sr == 5) {
        sr = "EXCELLENT";
        return sr;
    } else if
    (sr == 4) {
        sr = "GREAT";
        return sr;
    } else {
        sr = "AVERAGE";
        return sr;
    }
};

console.log(data);

const reviewinfo = data.map(getreviews);
const numReviews = data.map(getNumReviews);
const tpLogo = data.map(getTpLogo);
const review = reviewinfo[0]; // creates a new array of reviews
const consumer = review.map(i => i.consumer);
const compInfo = data[1]; // array of company info
const scores = numReviews[1]; // array of trust scores and star ratings
const starsurl = data[2]
const tplogo = data[3]; // array of logo urls 
const sr = compInfo.stars;

 document.getElementById("tpwidget").innerHTML = `
<div class="row">
    <div class="col-12">${starRatingWords(sr)}</div>
    <div class="col-12">${compInfo.trustScore}/ 10</div>
    <div class="col-12">bOnline Trustscore is ${compInfo.trustScore}/ 10</div>
    <div class="col-12"><img style="width: 250px" src="${starsurl.star512x96.url}" alt="stars" /></div>
    <div class="col-12">Based on ${scores.total} reviews.</div>
    <div class="col-12">bOnline has ${scores.fiveStars} 5 star reviews</div>
    <div class="col-12">See some of the reviews here.</div>
    <div class="col-12"><img style="width: 250px" src="${tpLogo[3].logo288x72.url}" alt="tpLogo" /></div>
 </div>
  ${review.map(reviewTemplate).join('')}
 `
     })
 };
 </script>

The json is formatted like;

0 - 3 Object


1 contains My company info

2 contains My star rating images

3 contains Trustpilot images

Ok so in order to get the consumer details I need to call this api url:

 https://api.trustpilot.com/v1/consumers/${consumerId}/profile? 
 apikey=*myapikey*

The ID i get from the consumer object as shown in the image.

I trust I have added enough info and explained properly. Thanks in advance.

Hey there!

First of all: the proper indentation can help a lot to identify the problem. Tools like Atom or VSCode can do that for you automatically.

I found the following problems to start with:

  1. consumer1 is an unused function
  2. the variables consumer and tplogo are unused

Your first API URL has a space in it:

"https://api.trustpilot.com/v1/business-units/4fa8fbc8000064000515212e/reviews/? stars[]=4&stars[]=5&apikey=*myapikey*",
just after ?

That might be the first cause.

Second:

You are already using const/let/fetch/template literals. Why not use async/await to make the code clearer to read? Then you wouldn’t need any thens.

Also:

What you get from the resolved Promise.all is an array of the results from each item.
So

data[0] = business-units/4fa8fbc8000064000515212e/reviews/
data[1] = business-units/46d6a890000064000500e0c3 
data[2] = resources/images/stars/4
data[3] = resources/images/logos

That means your reviews are stored in data[0]

But what you actually do, is that you loop through all four datapoints (reviews, stars, logo etc) and then do data.map(getReviews) I guess what you actually want to do, is data[0].map.

Hope this helps.

Best,
Martin

1 Like

Hi there thanks so much. Let me look at Async await and get back to you. The space in the URL occurred when I added the code to this site sorry about that (I had to indent it 4 spaces in.)

The issue Im having is getting the id from the one call then using that id in the next url call, and having that info accessible in the review template.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.