具有以下结构:
ApiService.js
App.jsx
components/
Tracks.jsx
...
这是我的ApiService.js
:
// ApiService.js
import Axios from 'axios';
class ApiService {
constructor() {
this.axios = Axios.create();
this.axios.interceptors.response.use(null, this.authInterceptor);
this.get = this.axios.get.bind(this.axios);
this.post = this.axios.post.bind(this.axios);
}
async authorize() {
console.log('Async in authorize')
const { accessToken } = await this.axios.post('/get_token/1', {});
this.setAccessToken(accessToken);
return accessToken; // return it to the component that invoked it to store in some state
}
async getAroma(userId, spotifyToken) {
return this.axios.get(
`${process.env.REACT_APP_WEB_SERVICE_URL}/get-tracks/${userId}/${spotifyToken}`
);
}
async updateAccessToken(userId) {
const { accessToken } = await this.axios.post(`/refresh-token/1`, {});
this.setAccessToken(accessToken);
}
async authInterceptor(error) {
error.config.retries = error.config.retries || {
count: 0,
};
if (this.isUnAuthorizedError(error) && this.shouldRetry(error.config)) {
await this.updateAccessToken(); // refresh the access token
error.config.retries.count += 1;
return this.axios.rawRequest(error.config); // if succeed re-fetch the original request with the updated accessToken
}
return Promise.reject(error);
}
isUnAuthorizedError(error) {
return error.config && error.response && error.response.status === 401;
}
shouldRetry(config) {
return config.retries.count < 3;
}
setAccessToken(accessToken) {
this.axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`; // assign all requests to use new accessToken
}
}
export const apiService = new ApiService(); // this is a single instance of the service, each import of this file will get it
然后将服务实例导入到我的组件Track.jsx
中,并按如下方式调用:
import {apiService} from '../ApiService';
....
async componentDidMount() {
if (this.props.isAuthenticated) {
const {userId, spotifyToken} = this.props;
const aromaticTracks = await apiService.getTracks(userId, spotifyToken) ;
this.setState({Tracks});
} else {
this.setState({Tracks: []});
return null
}
}
但是我得到了错误:
Unhandled Rejection (TypeError): Cannot read property 'isUnAuthorizedError' of undefined
我想念什么?
答案 0 :(得分:0)
由于authInterceptor
函数用作回调函数,因此调用它的位置将上下文设置为不确定,即this
将不确定。
要解决此问题,您可以将authInterceptor
函数更改为箭头函数。
更新
使用authInterceptor: async (error) => {
代替async authInterceptor(error) {
。
或者,您也可以使用bind方法,在this.axios.interceptors.response.use(null, this.authInterceptor.bind(this));
之类的构造函数中注册拦截器