最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Javascript Fetch inside a map - Stack Overflow

programmeradmin2浏览0评论

I have a website/portfolio where I display all my projects using the Github API. My goal is to create a filter for these projects, so I created a file in the root of some repositories called "built-with.json", that file exists in only two repositories just for test purpose, that is a array of technologies I used in the project (example: ["React", "Javascript", ...]). So I need to fetch the Github APi(that part it's working well), then fetch that file, and return a new Array of projects but with an "filters" key where the value is the array inside of "built-with.json". Example:

Github API return (example of just one project returning):

[{
"id": 307774617,
"node_id": "MDEwOlJlcG9zaXRvcnkzMDc3NzQ2MTc=",
"name": "vanilla-javascript-utility-functions",
"full_name": "RodrigoWebDev/vanilla-javascript-utility-functions",
"private": false
}]

New array of objects that a I need:

[{
"id": 307774617,
"node_id": "MDEwOlJlcG9zaXRvcnkzMDc3NzQ2MTc=",
"name": "vanilla-javascript-utility-functions",
"full_name": "RodrigoWebDev/vanilla-javascript-utility-functions",
"private": false,
"filters": ["HTML5", "CSS3", "JS", "React"]
}]

This is what I did:

const url = ";sort=created";
fetch(url)
  .then((response) => response.json())
  .then((data) => {
      return data.map(item => {
        //item.full_name returns the repositorie name
        fetch(`/${item.full_name}/master/built-with.json`)
          .then(data => {
            item["filters"] = data
            return item
          })
      })
    })
  .then(data => console.log(data))

But it does not work! I get this in the console:

Someone can help me? Thanks in advance

Note: Sorry if you find some gramatical errors, my English it's a working in progress

I have a website/portfolio where I display all my projects using the Github API. My goal is to create a filter for these projects, so I created a file in the root of some repositories called "built-with.json", that file exists in only two repositories just for test purpose, that is a array of technologies I used in the project (example: ["React", "Javascript", ...]). So I need to fetch the Github APi(that part it's working well), then fetch that file, and return a new Array of projects but with an "filters" key where the value is the array inside of "built-with.json". Example:

Github API return (example of just one project returning):

[{
"id": 307774617,
"node_id": "MDEwOlJlcG9zaXRvcnkzMDc3NzQ2MTc=",
"name": "vanilla-javascript-utility-functions",
"full_name": "RodrigoWebDev/vanilla-javascript-utility-functions",
"private": false
}]

New array of objects that a I need:

[{
"id": 307774617,
"node_id": "MDEwOlJlcG9zaXRvcnkzMDc3NzQ2MTc=",
"name": "vanilla-javascript-utility-functions",
"full_name": "RodrigoWebDev/vanilla-javascript-utility-functions",
"private": false,
"filters": ["HTML5", "CSS3", "JS", "React"]
}]

This is what I did:

const url = "https://api.github.com/users/RodrigoWebDev/repos?per_page=100&sort=created";
fetch(url)
  .then((response) => response.json())
  .then((data) => {
      return data.map(item => {
        //item.full_name returns the repositorie name
        fetch(`https://raw.githubusercontent.com/${item.full_name}/master/built-with.json`)
          .then(data => {
            item["filters"] = data
            return item
          })
      })
    })
  .then(data => console.log(data))

But it does not work! I get this in the console:

Someone can help me? Thanks in advance

Note: Sorry if you find some gramatical errors, my English it's a working in progress

Share Improve this question edited Mar 20, 2024 at 10:00 VLAZ 29k9 gold badges62 silver badges83 bronze badges asked Oct 31, 2020 at 0:38 RodrigoRodrigo 1511 gold badge1 silver badge11 bronze badges 3
  • 1 A couple of things here. You don't need the .then() chained onto fetch(). fetch() returns a promise. Array.prototype.map() returns an array. Put together, you end up with an array of promises. You can resolve the array of promises with Promise.all(arrayOfPs) – Randy Casburn Commented Oct 31, 2020 at 0:46
  • You need to chain a promise.all. please look at this. – Brenden Commented Oct 31, 2020 at 0:47
  • You miss out a return before the inner fetch('https://raw.githubusercontent… – hackape Commented Oct 31, 2020 at 0:49
Add a comment  | 

3 Answers 3

Reset to default 12

A couple of things here. You don't need the .then() chained onto fetch(). fetch() returns a promise. Array.prototype.map() returns an array. Put together, you end up with an array of promises. You can resolve the array of promises with Promise.all(arrayOfPs)

EDIT: After your comments and reviewing your question, I've rewritten this so that it retrieves the skills from the filtered list of repositories.

const url = `https://api.github.com/users/RodrigoWebDev/repos?per_page=100&sort=created`;

(async() => {
  // Final results 
  let results;
  try {
    // Get all repositories
    const repos = await fetch(url).then((res) => res.json());
    const responses = await Promise.all(
      // Request file named 'build-with.json' from each repository
      repos.map((item) => {
        return fetch(
          `https://raw.githubusercontent.com/${item.full_name}/master/built-with.json`
        );
      })
    );
    // Filter out all non-200 http response codes (essentially 404 errors)
    const filteredResponses = responses.filter((res) => res.status === 200);
    results = Promise.all(
      // Get the project name from the URL and skills from the file
      filteredResponses.map(async(fr) => {
        const project = fr.url.match(/(RodrigoWebDev)\/(\S+)(?=\/master)/)[2];
        const skills = await fr.json();
        return {
          project: project,
          skills: skills
        };
      })
    );
  } catch (err) {
    console.log("Error: ", err);
  }
  results.then((s) => console.log(s));
})();

The problem was that the fetch wasn't being returned hence the .map() was returning undefined. May I suggest a solution using async-await.

const url = "https://api.github.com/users/RodrigoWebDev/repos?per_page=100&sort=created";

getData(url).then(data => console.log(data));
  
async function getData(url){
  const response = await fetch(url);
  const data = await response.json();
  const arrOfPromises = data.map(item => fetch(`https://raw.githubusercontent.com/${item.full_name}/master/built-with.json`)
  );
  return Promise.all(arrOfPromises);
}

You have multiple problems:

  1. Inside of map function you do not return any result
  2. Result of your map function will actually be another Promise (because of fetch inside).

So what you need to do:

  1. Return promise from map - as a result you will have array of promises
  2. Wait for all promises from point 1 using Promise.all

Something like this:



    var url1 = "https://api.github.com/users/RodrigoWebDev/repos?per_page=100&sort=created";
    var datum = fetch(url1)
      .then((response) => response.json())
      .then((data) => {
          return Promise.all(data.map(item => {
            //item.full_name returns the repositorie name
            return fetch(`https://raw.githubusercontent.com/${item.full_name}/master/built-with.json`)
              .then(data => {
                item["filters"] = data
                return item
              })
          }));
        }).then(data => console.log(data))

发布评论

评论列表(0)

  1. 暂无评论