Is it possible to use axios.all with a then() for each promise?

It seems at this post day, axios recommends using Promise.all instead of axios.all https://github.com/axios/axios this is what worked for me, with Nuxtjs

async nuxtServerInit(vuexContext, context) {
    console.log(context);

    const primaryMenuData = {
      query: `query GET_MENU($id: ID!) {
        menu(id: $id, idType: NAME) {
          count
          id
          databaseId
          slug
          name
          menuItems {
            edges {
              node {
                url
                label
                target
              }
            }
          }
        }
      }`,
      variables: {
        "id": "Primary"
      }
    }

    const primaryMenuOptions = {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      data: primaryMenuData,
      url: 'http://localhost/graphql'
    };

    const postsData = {
      query: `query GET_POSTS($first: Int) {
        posts(first: $first) {
          edges {
            node {
              postId
              title
              date
              excerpt
              slug
              author {
                node {
                  name
                }
              }
              featuredImage {
                node {
                  altText
                  caption
                  sourceUrl(size: MEDIUM)
                }
              }
            }
          }
        }
      }`,
      variables: {
        "first": 15
      }
    }

    const postsOptions = {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      data: postsData,
      url: 'http://localhost/graphql'
    };
        
    try {
      const [primaryMenuResponse, postsResponse] = await Promise.all([
        await axios(primaryMenuOptions),
        await axios(postsOptions)
      ])
      
      vuexContext.commit('setPrimaryMenu', primaryMenuResponse.data.data.menu.menuItems.edges);
      vuexContext.commit('setPosts', postsResponse.data.data.posts.edges);

    } catch (error) {
      console.error(error);
    }      
  },

If the behaviour of your second attempt is indeed like that, then that would be an indication that axios is not Promise/A+ compliant. The then callback's return value must be the value with which the promise returned by that then is fulfilled. Since that is the promise you push into the array, the value that axios.all would return for that promise can only be known by executing the then callbacks first.

Even though you do not return a value explicitly in the then callback, this does not affect the above rule: in that case the return value is undefined and it is that value that should be provided by axios.all once the corresponding promise is resolved.

See in particular the rules 2.2.7, 2.2.7.1, 2.3.2.1, 2.3.2.2 in the specs of Promise/A+:

2.2.7 then must return a promise.

promise2 = promise1.then(onFulfilled, onRejected);

2.2.7.1 If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).

[...]

To run [[Resolve]](promise, x), perform the following steps:

[...]

2.3.2 If x is a promise, adopt its state:

2.3.2.1 If x is pending, promise must remain pending until x is fulfilled or rejected.

2.3.2.2 If/when x is fulfilled, fulfill promise with the same value.

So I would suggest using a Promise/A+ compliant promise implementation instead. There are several other libraries, like for instance request-promise.

Alternatively, you could use the native ES6 Promise implementation, and promisify the http.request method yourself.

ES6 offers Promise.all which guarantees to provide the resolved values in the same order as the promises were provided.


Okay, so I found a way to do what I needed without using using a then on each get. Since the params passed in to axios.get contain enough info to determine the save location, and since I can read the params back from the response, I can do something like the following:

let promises = [];

for (let i = 0; i < requests.length; i++) {
    promises.push(axios.get(request[i].url, { params: {...} }));
}

axios.all(promises)
    .then(axios.spread((...args) => {
        for (let i = 0; i < args.length; i++) {
            myObject[args[i].config.params.saveLocation] = args[i].data;
        }
    }))
    .then(/* use the data */);

This ensures all the data is received and saved to the object before it is used.