api.get(...).then(...).catch(...).finally is not a function
Only a native Promise (constructed with new Promise
) is guaranteed to have a .finally
method (in newer environments). (in older environments, .finally
won't work at all with Promises created with new Promise
)
It looks like axios doesn't use new Promise
internally - rather, it just returns a thenable, which is not guaranteed to have a finally
method (and because it doesn't, it throws an error).
While you could use the explicit Promise construction antipattern to wrap the axios call in a native new Promise
, so that it has Promise.prototype.finally
in its prototype chain, a better option (thanks Bergi!) is to just use Promise.resolve
, which will turn a thenable into a native Promise while preserving the failure or success of the thenable:
get(API, params = this.defaultParams) {
this.call = "GET";
let constructedURL = this.constructURL(API, params);
axiosRetry(axios, { retries: this.retry });
return Promise.resolve(axios.get(constructedURL, this.config));
}
The promise should be taking finally
of es6, which I am not sure is something that gets supported by the axios
promise, if I may, I sugest use then
instead of finally
import API from "../../utils/API";
componentDidMount() {
let merchantId = this.props.merchant.id;
let api = new API(this.props.gatheredTokens);
let self = this;
api.setRetry(10);
api
.get("merchantMessages", { repl_str: merchantId })
.then(response => this.merchantMessageConfiguration(response.data))
.catch(function (error) {
console.log(error);
})
.then(function () {
self.state.list.push(
<Card
merchant={self.props.merchant}
key={self.props.merchant.id}
bubblemsg={self.state.bubblemsg}
/>
);
})
.then(function () {
self.merchantNoticeLoading(self);
});
}
You can use a npm package promise.prototype.finally for polyfill.
doing like this:
var promiseFinally = require('promise.prototype.finally');
promiseFinally.shim();
or in TypeScript:
//@ts-expect-error
import promiseFinally from 'promise.prototype.finally';
promiseFinally.shim();
The package will override the function if Promise.prototype.finally
is not found in user browser. And if the browser support Promise.prototype.finally
, it will just use the native function.
I use Create React App
for building frontend project. It seems that Babel and TypeScript won't manage with this tough things, you should deal with it on your own.
I suggest to use another then
instead of using finally
. then
after catch
is works like a finally
. don't forget to use at least one catch
in your promise chain, in order to handle your instructions failure.
So this two line of code is the same:
api.get(…).then(…).catch(…).then(...)
and
api.get(…).then(…).catch(…).finally(...)