Axios complete event - javascript

I'm using Axios for API services and just curious if there's any official way to handle a "complete" event as we have used in Ajax call.
So like
axios.get('/v1/api_endpoint?parameters')
.then((res) => { .. })
.catch((err) => { .. })
.complete(() => {}) // <== is there any way to handle this complete event?

Following the axios documentation here, the secondary .then() is the one that I'm looking for.
Here's a good example of how to handle that axios complete event which will always be executed whether it has succeeded or failed.
axios.get('/v1/api_endpoint?with_parameters')
.then((res) => { // handle success })
.catch((err) => { // handle error })
.then(() => { // always executed }) <-- this is the one

If you have to check whether an API call is a success or not, then you can use below code:
const response = await axios.post(
"http://localhost:8000/xyz",
{ token, user }
);
const status = response.status
if (status == 200) {
console.log('Success')
toast("Successful Transaction", { type: "success" });
} else {
console.log('Falure')
toast("Falure", { type: "error" });
}
You can also use finally to check if the event is completed or not. Attaching the link for your reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally

Related

How can I write a .then function with async/await, so that I can catch the response from axios (in seperate files and methods, in vue)

My target is to catch a respone, from a axios request, which works greate with .then, but I would like use async/await, since it is a new approach with lots of benefits.
(The update method is called multiple times)
How transform my saveEdit method (which gets a response form the update method) with async/await, so that I can catch the response from axios.
Method of my .vue file:
...
saveEdit (event, targetProperty, updateValue) {
this.update(this[updateValue])
.then((result) => {
if (result.status === 200) {
this.fetchData()
this.cancelEdit()
}
})
}
...
My function of my store module:
(api is a handler for axios, basicall axios. ...)
update ({ commit, rootGetters }, details) {
...
const requestUrl = `some adress`
return api
.patch(
requestUrl,
validatedDetails
)
.then(response => {
return response
})
.catch(error => {
return Promise.reject(error)
})
}
Other stackoverflow posts related to that problem, did answer my question, since in the examples are in one file and one method.
Thanks in advance
you can try someting like:
update ({ commit, rootGetters }, details) {
...
const requestUrl = `some adress`
return api.patch(
requestUrl,
validatedDetails
)
}
and :
async saveEdit (event, targetProperty, updateValue) {
try {
const result = await this.update(this[updateValue])
if (result.status === 200) {
this.fetchData()
this.cancelEdit()
}
} catch (error) {
// handle api call error
}
}

How do I cancel a ongoing GET request with axios

I have an inputfield, onChange it sends my value of the inputfield to an API. So, the api will start fetching all the data. but when I continue typing again, I want that previous request to be canceled.
I'm using axios for making my request and tried looking at the documentation but I can't seem to figure out how it really works, can someone explain how to do this?
Here is my function that gets called by every new input:
const onChange = (value) => {
setTimeout(async() => {
let result = []
if (y === "keyword") result = await AutoSuggestionKeyword({
value: value
});
else {
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
await axios.get(`https://${api_uri}/${value.toLowerCase()}`)
.catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
}).then(resp => {
console.log(resp)
});
source.cancel();
}
}, 500)
}
You need to provide a cancelToken in your request,
axios.get(`https://${api_uri}/${value.toLowerCase()}`, {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
});
I don't think you can cancel an HTTP request, but what you can do is wrap it in debounce function, debounce function wait for a certain time before calling the callback or function you wrap or pass on it.
you can simply google debounce and it will give you articles or npm packages that you can use.
I think this article also has the same issue you are trying to resolve
Happy coding
Edit 1: yeah so you can cancel the http request see comment below

How to efficiently call setState on both cases - succes and error?

I'm using react and I have an asynchronous action that receives some data from API using axios. I also have a flag (state variable tableLoaded) which describes if data is fetched.
this.props.fetchDataAction(requestParams).then(
() => {
this.setState({
data: this.props.reports.data
});
}
).then(() => {
this.setState({ tableLoaded: true })
});
I want my flag tableLoaded to be set to true in both cases - either after API call succeded and failed, so I just added another then() on my Promise, which triggers function that sets this flag to true.
My question is - is this the best solution to achieve my goal? Or should I repeat this code in both cases?
You should use the Promise.finally syntax.
this.props.fetchDataAction(requestParams)
.then(() => {
// Do your thing on success
this.setState({
data: this.props.reports.data
});
})
.catch((error) => {
// Do something if failed
})
.finally(() => {
// Do this in all cases..
this.setState({ tableLoaded: true })
});
Edit:
If the return from fetchDataAction is an Axios promise, then you should replace .finally by .then because Axios doesn't offer the finally method. I would then say that your original suggestion was correct. You could comment the second .then so you know why.
this.props.fetchDataAction(requestParams)
.then(() => {
// Do your thing on success
this.setState({
data: this.props.reports.data
});
})
.catch((error) => {
// Do something if failed
})
.then(() => { // Triggered in all cases by axios
// Do this in all cases..
this.setState({ tableLoaded: true })
});
You can use all() to catch success and failures
One issue you'll run into with the current approach is that any possible errors will prevent the last .then from running, making it possible for tableLoaded to remain false if something does go wrong. See this pen for an example of this issue.
Promise.finally is one good way to step around this, as another answer points out, but my personal preference would be to use async/await.
try {
await this.props.fetchDataAction(requestParams)
this.setState({
data: this.props.reports.data
})
} catch (error) {
// handle error
}
this.setState({ tableLoaded: true })

AsyncStorage.setItem Promise not fulfilling or erroring?

I've looked through a few posts such as this post
I want to use a console.log to see if I successfully set an item to AsyncStorage.
Here is my code:
export function saveDeckTitleAPI(key,title) {
return AsyncStorage.setItem(uuid(), JSON.stringify(new DeckCreator(title)))
.then(data => {
debugger;
console.log('INSIDE SET ITEM');
AsyncStorage.getItem(data.key).then(item => {
console.log(item);
})
})
.catch(err => {
console.err(err);
});
}
When I run this code, the .then and the .catch aren't fulfilled. I tried logging the promise by itself, and I get a similar result as the post above.
Do I have to use async/await? Is that the problem here? Here are the docs to setItem.
You can pass a callback as the third argument. If there's an error, it will be the callback's first parameter. If there's no error, console log that all is well and good, otherwise log the error.
Yes you need async and await
You can get an inspiration from the code below, the way I do a facebook login with setItem
const doFacebookLogin = async dispatch => {
const { type, token } = await
Facebook.logInWithReadPermissionsAsync('xxxx', {
permissions: ['public_profile']
});
if (type === 'cancel') {
return dispatch({ type: FACEBOOK_LOGIN_FAIL });
}
await AsyncStorage.setItem('fb_token', token);
dispatch({ type: FACEBOOK_LOGIN_SUCCESS, payload: token });
};

Catch() not handling 404

I'm making a script to fetch some data from my api:
const success = (response) => {
console.log(response);
};
const failed = (error) => {
console.log(error);
};
axios.$http.get('/somedata')
.then((response) => {
success(response.data);
})
.catch((error) => {
failed(error);
});
/somepage is a non-existing page so it returns a 404. But the catch is not handling this. Why not? In my console I have the error TypeError: Cannot read property 'data' of undefined. Why does it not run the failed() function? I don't understand.
Found out it was related to a custom interceptor handling 401-errors (but not 404 errors)...
Judging by the error message, it looks like "success(response.data);" is being called. Is it possible the server is successfully returning a page that says something like "Error 404" rather than actually returning http response code 404?
You could impliment a check for 404s.
axios.$http.get('/somedata')
.then(response => {
if(response.status !== 404) //or any status code really
success(response.data);
else
failed(response)
})
.catch((error) => {
failed(error);
});
Then again what you probably want to check for is to make sure it's a 200 that returns.
axios.$http.get('/somedata')
.then(response => {
if(response.status === 200)
success(response.data);
else
failed(response)
})
.catch((error) => {
failed(error);
});

Categories

Resources