Search code examples
javascriptarraysfetch-apigithub-api

Javascript Fetch inside a map


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:

enter image description here

Someone can help me? Thanks in advance

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


Solution

  • 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))