Warm tip: This article is reproduced from serverfault.com, please click

Getting .json is not a function on Promise.all w/fetch

发布于 2020-11-27 23:38:07

Oh once again I have those Promise.all blues:( I have a function that makes an array of fetch call's from provided urls and then we want to retrieve data via a Promise.all and return array of reponses or better yet just return the promise to calling function. . The problem is this results in error w/console showing:

There was problem retrieving data. TypeError: r.json is not a function

The code for the function is :

 const getLeagueLeaders = (url, params) => {
  // First let's create the array of url's
  let queryURLs = [];

  params.forEach((param) => {
    queryURLs.push(
      fetch(`${url}${new URLSearchParams(param)}`, {
        method: "get",
        headers: {
          Authorization:
            "Basic ==",
        },
      }).then((res) => res.json())
    );
  });

  return (
    Promise.all(queryURLs)
      // map array of responses into an array of response.json() to read their content
      .then((responses) => responses.map((r) => r.json()))
      .catch((err) => {
        console.error("There was problem retrieving data.", err);
      })
  );
};
    
    module.exports = getLeagueLeaders;

And in Vue component

 mounted: async function () {
        const leagueLeadersResponseArray = await getLeagueLeaders(
          this.fetchBaseUrl,
          this.params
        );
this.qbLeaders =
      leagueLeadersResponseArray[0].cumulativeplayerstats.playerstatsentry;

Obviously leagueLeadersResponseArray is undefined. I researched .json() and dont see how I am using it incorrectly. At first i thought I needed a Promise.all wrapper for the responses.map((r) => r.json()) but that did no good either. I looked at this link but I am not using fetch as he is. Any guidance much appreciated....

Updated working code for anybody else:

// ---------- src/js/modules/ ------------------ //

/* jshint ignore:start */
// Make function to retrieve League Leaders in a Category

const getLeagueLeaders = (url, params) => {
  // First let's create the array of url's
  let queryURLs = [];

  params.forEach((param) => {
    queryURLs.push(
      fetch(`${url}${new URLSearchParams(param)}`, {
        method: "get",
        headers: {
          Authorization:
            "Basic ==",
        },
      }).then((res) => res.json())
    );
  });

  return Promise.all(queryURLs).catch((err) => {
    console.error("There was problem retrieving data.", err);
  });
};

module.exports = getLeagueLeaders;
Questioner
Alan
Viewed
0
Aplet123 2020-11-28 07:56:09

Your template string is around the entire fetch when it should only be in the argument to fetch:

  params.forEach((param) => {
    queryURLs.push(fetch(`${url}${new URLSearchParams(param)}`, {
      method: "get",
      headers: {
        Authorization:
          "Basic *****==",
      }
    }));
  });

Then, you have a .then(data => {return data}), which doesn't do anything since the return returns from the then callback, not the function. You should instead return the promise that Promise.all gives you:

  return Promise.all(queryURLs)
    // map array of responses into an array of response.json() to read their content
    .then((responses) => responses.map((r) => r.json())) // Get error There was problem retrieving data. TypeError: r.json is not a function
    .catch((err) => {
      console.error("There was problem retrieving data.", err);
    });