未处理的拒绝(TypeError):无法读取未定义的属性'isUnAuthorizedError'

时间:2020-04-25 19:42:52

标签: javascript reactjs

具有以下结构:

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

我想念什么?

1 个答案:

答案 0 :(得分:0)

由于authInterceptor函数用作回调函数,因此调用它的位置将上下文设置为不确定,即this将不确定。

要解决此问题,您可以将authInterceptor函数更改为箭头函数。

更新

使用authInterceptor: async (error) => {代替async authInterceptor(error) {

或者,您也可以使用bind方法,在this.axios.interceptors.response.use(null, this.authInterceptor.bind(this));之类的构造函数中注册拦截器