i wrote an application in VueJS and i have to send first a get call to get the redirect url.
this.$axios.get('http://first-url.call').then(function(response) {
console.log(response.request.res.responseUrl)
let postUrl = response.request.res.responseUrl
}).catch(function(error){
console.log(error)
});
In my next call i want to use the "response.request.res.responseUrl" as post url
this.$axios.post(postUrl).then(function(response) {
console.log(response);
}).catch(function(error){
console.log(error)
});
Unfortunately, i cannot save the "response.request.res.responseUrl" response in a js variable. I'm not so familiar with async / await so maybe someone can help how i can store the first response into a value that i can use in my second call?
CodePudding user response:
It's simpler to write it exclusively with async..await
syntax:
try {
let response = await this.$axios.get('http://first-url.call')
let postUrl = response.request.res.responseUrl;
response = await this.$axios.post(postUrl)
...
} catch (err) {
...
}
It's beneficial to know the exact meaning of it. The key is correct promise chaining:
this.$axios.get('http://first-url.call')
.then((response) => {
let postUrl = response.request.res.responseUrl;
return this.$axios.post(postUrl)
})
.then((response) => {...})
.catch(...);
This way promises are executed in correct order and don't have unnecessary nested callbacks.
Be aware of incorrect use of function
, it will lead to this problem.
CodePudding user response:
Here is a solution without async/await: Make the second axios call within the first successful call. You need to use arrow functions for this so you keep the correct this
on your Vue instance:
this.$axios.get('http://first-url.call').then((response) => {
console.log(response.request.res.responseUrl)
let postUrl = response.request.res.responseUrl
this.$axios.post(postUrl).then((response) => {
console.log(response);
}).catch(function(error){
console.log(error)
});
}).catch((error) =>{
console.log(error)
});
CodePudding user response:
There are a number of ways to deal with this.
The simplest is to create a variable outside the callbacks. Though the following still relies on your first call completing before the second one.
let postUrl = null
this.$axios.get('http://first-url.call').then(function(response) {
postUrl = response.request.res.responseUrl
})
The next best (really the best) solution is to use async/await instead of .then()
so you don't have callback scoping issues. This approach also guarantees you won't have a race condition because it will "await" for the first call to finish before making the second call.
The following would need to take place inside a function with async
.
async function doWhatever() {
const response = await this.$axios.get('http://first-url.call')
const postResponse = await
this.$axios.post(response.request.res.responseUrl)
}
Finally, the last option is you nest your callbacks. This allows the second callback to have access to the scope of the first callback.
this.$axios.get('http://first-url.call').then(function(response) {
this.$axios.post(response.request.res.responseUrl).then(function(postResponse) {
// do something with the postResponse
})
})
Also, while the above code will work, it's usually better to chain promises.
this.$axios.get('...')
.then(function(response) {
// we return the promise so it can be handled in the next .then()
return this.$axios.post(response.request.res.responseUrl)
})
.then(function(postResponse) {
// do something with the postResponse
})
Notice how this last example starts to look a lot like async/await.