Home > front end >  chaining responses with axios and Vue js
chaining responses with axios and Vue js

Time:10-31

I am trying to chain three requests in one with Axios. I am practicing vue.js so please correct me if my approach is not ideal.

The goal is to have three requests. One is a post followed by 2 Gets. What I would like to achieve is one chained request.

My questions are:

  1. Is this a good way to handle this? Should they be chained together like this?

  2. Is it possible to map the response to a model like I did in the first post request and pass it to the next?

     const apiClient: AxiosInstance = axios.create({
     headers: {
         'content-type': 'application/json',
         'X-RapidAPI-Key': '08f852e........22fb3e2dc0...',
         'X-RapidAPI-Host': 'judge0-ce.p.rapidapi.com'
     },
     params: {base64_encoded: 'true', fields: '*'},
    });
    
    export const api = {
    
     async submitCode(code: Code) {
         code.language_id = 60
         code.stdin = "Sn..2Uw"
         code.source_code = btoa(code.source_code)
         apiClient.post<Token>(`https://judge0-ce.p.rapidapi.com/submissions?language_id=${code.language_id}&source_code=${code.source_code}&stdin=SnVkZ2Uw`)
         .then(function (response) {
             console.log("res.data", response.data.token);
         }).then(function (token) {
             console.log("token", token); // <---- empty
             `https://judge0-ce.p.rapidapi.com/submissions/${token}`  // <---- get request
         }).then(function (response) {
             console.log("res.data", response);
         }).then(function (response  ) {
             // here I will need a model
         })
         .catch((err) => {
             const error = err.response ? err.response.data : err;
             console.log("error"   error);
         })
     }
    

    }

CodePudding user response:

You useasync, then don't chain promices

async function submitCode(code: Code) {
    code.language_id = 60
    code.stdin = "Sn..2Uw"
    code.source_code = btoa(code.source_code)

    try { // ~ global `.catch`
        const token = await apiClient.post<Token>(`https://blah`)
        const get1result = await apiClient.get<Blah>(`https://balah?${token}`)
        const get2result = await apiClient.get<Blah>(`https://balah?${token}`)

        doBlah({token, get1result, get2result})
    } catch (err) { // maybe should check object type here
        const error = err.response ? err.response.data : err;
        console.log("error"   error);
    }
}

As for Vue, I can only recomment to use asyncComputed which you can feet Promise into if you need that


Express also had express.api or something with which you can skip https://blah/com/api/ part of url, check it

CodePudding user response:

You have to await each function if the next one is dependent on the previous. Or you could use Promise chaining in the traditional sense using new Promise(resolve, reject). Async only applies to top level, so you will need to declare subsequent functions 'async' again as shown.

I would also suggest setting axios defaults with a base URL so you don't have to repeat the full URL each time. Note that console.log statements are not "Thenable" so your 1st statement has no effect, nor does your 3rd, other than to define your next variable.

const apiClient = axios.create({
  baseURL: 'https://judge0-ce.p.rapidapi.com/submissons',
  // ... headers ... //
});

export const api = {
  async submitCode(code){
  // ... code variable ...//
  await apiClient.post(
    `?language_id=${code.language_id}&source_code=${code.source_code}&stdin=SnVkZ2Uw`)
    .then(async (response1) => {
      const token = response1.data.token
      await api.get(`/${token}`)
    }).then(async (response2) => {
      console.log(response2.data)
      const model = response2.data.map((val1) => apiClient.get(`anotherGet/${val1.id}`))
      const result = await Promise.all(model)
      return result.map((val2) => val2.data)
    })
  // ... catch ...//
}}
  • Related