Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use two map function with two fetching URL

I have two API that I should turn them array like that

[
            {
                key: "0",
                label: 'Installation',
                children: [
                    { key: "0-0", label: 'Getting Started', url: 'https://reactjs.org/docs/getting-started.html' },
                    { key: "0-1", label: 'Add React', url: 'https://reactjs.org/docs/add-react-to-a-website.html' },
                    { key: "0-2", label: 'Create an App', url: 'https://reactjs.org/docs/create-a-new-react-app.html' },
                    { key: "0-3", label: 'CDN Links', url: 'https://reactjs.org/docs/cdn-links.html' }
                ]
            },
            {
                key: "1",
                label: 'Main Concepts',
                children: [
                    { key: "1-0", label: 'Hello World', url: 'https://reactjs.org/docs/hello-world.html' },
                    { key: "1-1", label: 'Introducing JSX', url: 'https://reactjs.org/docs/introducing-jsx.html' },
                    { key: "1-2", label: 'Rendering Elements', url: 'https://reactjs.org/docs/rendering-elements.html' },
                    { key: "1-3", label: 'Components and Props', url: 'https://reactjs.org/docs/components-and-props.html' },
                    { key: "1-4", label: 'State and LifeCycle', url: 'https://reactjs.org/docs/state-and-lifecycle.html' },
                    { key: "1-5", label: 'Handling Events', url: 'https://reactjs.org/docs/handling-events.html' }
                ]
            }
        ];

By the way, I have two API, one of them get all categories, the second API is to take the names of the children. So I created chained fetch, but I can not take the children object correctly. children array turns that 'children: Promise {<fulfilled>: Array(11)}' What does fulfilled mean here, because my code not working due to that reason? I want to share my code also:

 getCategories() {
    return fetch('https://challenge.fnaghshin.com/api/cat')
      .then((res) => res.json())
      .then((d) => {
        return Promise.all(
          d.map((e) => {
            return {
              key: e.id,
              label: e.name,
              date: e.created_at,
              children: fetch(
                `https://challenge.fnaghshin.com/api/catpro/${e.id}`
              )
                .then((res) => res.json())
                .then((d) =>
                  d.map((e) => {
                    return {
                      key: e.id,
                      label: e.name,
                    };
                  })
                ),
            };
          })
        );
      });
  }

I also used Promise.all() to wait all promises fulfilled than turn me right array, but I failed.

like image 825
sayinmehmet47 Avatar asked Oct 17 '25 07:10

sayinmehmet47


1 Answers

The cleanest solution IMO is to use async/await, with nested Promises it quickly gets fairly unreadable.

async function getCategories() {
  const response = await fetch("https://challenge.fnaghshin.com/api/cat");
  const categories = await response.json();

  const childrenResponses = await Promise.all(
    categories.map((cat) =>
      fetch(`https://challenge.fnaghshin.com/api/catpro/${cat.id}`)
    )
  );

  const childrenData = await Promise.all(
    childrenResponses.map((response) => response.json())
  );

  return categories.map((cat, index) => ({
    key: cat.id,
    label: cat.name,
    date: cat.created_at,
    children: childrenData[index].map((child) => ({
      key: child.id,
      label: child.title
    }))
  }));
}

So first you get your categories, that's pretty simple. Then what you want to do is to use Promise.all() on list of fetch calls with IDs you have from categories (childrenResponses). Then you have to do the same because of .json() in fetch (it would be even cleaner with e.g. axios or similar higher level library instead of fetch), and once you have categories and childrenData you just have to map it the way you want. You can make it a bit more concise by doing e.g. this instead:

const categories = await fetch(
  "https://challenge.fnaghshin.com/api/cat"
).then((res) => res.json());

although in my opinion it's less readable. You should probably also do some error handling, e.g. with try/catch.

like image 195
paolostyle Avatar answered Oct 19 '25 20:10

paolostyle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!