0

Im having trouble combining two async variables into one array:

My code:

async function fetchMenus ({actions, state}) {
      return actions.theme.fetchToken().then(async () => {
        const items = await fetch("url", {
          method: "GET",
          headers: {
              Authorization: `Bearer ${state.theme.token}`,
          },
        });
        const menu = await fetch("url", {
          method: "GET",
          headers: {
              Authorization: `Bearer ${state.theme.token}`,
          },
        });

        return [menu.json(), items.json()];
      });
    };

As a response i recieve 2 fulfilled promises, but i want to receive the results. How can i solve this?

enter image description here

3
  • the syntax is incorrect why you are using .then with await in line #2 Commented May 28, 2020 at 8:04
  • yes actually the await was wrong, but ufortunately it doesnt solve the issue Commented May 28, 2020 at 8:06
  • You already know how to use await. Why not use it on the promises for the json body as well? Commented May 28, 2020 at 8:09

3 Answers 3

3

You just need to await your response json.

async function fetchMenus ({actions, state}) {
      return actions.theme.fetchToken().then(async () => {
        const items = await fetch("url", {
          method: "GET",
          headers: {
              Authorization: `Bearer ${state.theme.token}`,
          },
        });
        const menu = await fetch("url", {
          method: "GET",
          headers: {
              Authorization: `Bearer ${state.theme.token}`,
          },
        });
        const itemsJson = await items.json();
        const menuJson = await menu.json();
        return [menuJson, itemsJson];
      });
    };

Edit: I agree with other posters about using Promise.all as well.

Sign up to request clarification or add additional context in comments.

4 Comments

I would recommend to do the const itemsJson = await items.json(); before starting to fetch the second response, though.
Curious, what's the reasoning behind that recommendation?
It's just weird to have to two requests interlaced like that. I would even recommend using a helper function that can be called twice to remove the code duplication.
Ok, yeah I agree. I was wondering if there was some secret low-level knowledge you had of how fetch I/O works that made this suboptimal. :p
2

There are mistakes for example .json() is async too.

Also using Promise.all() is a bit faster because your API calls doesnt seem to depend on eatch other.

Because you return an array you can directly write return await Promise.all(menu.json(), items.json()) because Promise all returns an array

async function fetchMenus({ actions, state }) {
  let token = await actions.theme.fetchToken();
  let [items, menu] = await Promise.all(
    fetch("url", {
      method: "GET",
      headers: {
        Authorization: `Bearer ${state.theme.token}`
      }
    }),
    fetch("url", {
      method: "GET",
      headers: {
        Authorization: `Bearer ${state.theme.token}`
      }
    })
  );
  return await Promise.all(menu.json(), items.json());
}

Comments

1

You can do

Promise.all(fetchMenus(parameters).result).then((results) => {
 ... work with results
});

Promise.all puts an array of promises into a new promise, so to say.

It is typically used after having started multiple asynchronous tasks to run concurrently and having created promises for their results, so that one can wait for all the tasks being finished.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.