React / Redux-调度方法-返回错误

时间:2019-03-14 01:32:08

标签: javascript reactjs redux promise axios

我当前正在尝试添加和删除页面上的项目,并且返回错误。

Unhandled rejection (TypeError): Cannot read property data of undefined在下面的代码中都指向.catch

export const addItem = (item) => (dispatch, 
getState) => {
 axios
  .post('/api/items', item, tokenConfig(getState))
  .then(res => dispatch({
    type: ADD_ITEM,
    payload: res.data
}))
  .catch(err => dispatch(returnErrors(err.response.data, err.response.status))
 );
};

export const deleteItem = (id) => (dispatch, getState) => {
axios
 .delete(`/api/items/${id}`, tokenConfig(getState))
 .then(res => dispatch({
    type: DELETE_ITEM,
    payload: id
}))
 .catch(err => dispatch(returnErrors(err.response.data, err.response.status))
 );
};

///////////////////////////////////////////////// //

上面引用的returnErrors方法来自另一个文件,位于此处:

import { GET_ERRORS, CLEAR_ERRORS } from './types';

// RETURN ERRORS

export const returnErrors = (msg, status, id = null) => {
 return {
   type: GET_ERRORS,
payload: { msg, status, id }
 };
};


// CLEAR ERRORS

export const clearErrors = () => {
 return {
   type: CLEAR_ERRORS
 };
};

我将console.log(err.response)console.log(err.response.data)放在dispatch(returnErrors(err.response.data, err.response.data));的正上方,并返回了undefined作为第一个和uncaught (in promise) cannot read property of undefined

有人告诉我

This essentially means your error object doesn't have correct data. Please look into the error object returned. It could be an issue with items/user api, it should return correct error object.

项api路线

router.post('/', auth, (req, res) => {
 const newItem = new Item({
   name: req.body.name
 })

   newItem.save().then(item => res.json(item));
});

// DELETE api/items/:id
// Delete an item
// Private

router.delete('/:id', auth, (req, res) => {
  Item.findById(req.params.id)
   .then(item => item.remove().then(() => res.json({ deleted: true 
})))
   .catch(err => res.status(404).json({ deleted: false }));
})

不确定数据在哪里未定义。有人看到什么丢失了吗?

您可以查看chrome开发工具网络标签在此处返回的内容:

https://imgur.com/D5OGLpf

authActions

// Check token & Load User
// Want to check routes/auth.js for user by id that's included with token
// Going to use asynchronous request, use dispatch
export const loadUser = () => (dispatch, getState) => {

// User loading
 dispatch({ type: USER_LOADING });


// Fetch user
 axios.get('/api/auth/user', tokenConfig(getState))
  .then(res => dispatch({
     type: USER_LOADED,
  payload: res.data
 }))
  .catch(err => {
    dispatch(returnErrors(err.response.data, err.response.status));
  dispatch({
     type: AUTH_ERROR
   });
  });
 };

// Register User

export const register = ({ name, email, password }) => dispatch => {
// Headers
 const config = {
   headers: {
    'Content-Type': 'application/json'
  }
}

// Request body

const body = JSON.stringify({ name, email, password });

axios.post('/api/users', body, config)
 .then(res => dispatch({
     type: REGISTER_SUCCESS,
  payload: res.data
 }))
 .catch(err => {
  dispatch(returnErrors(err.response.data, err.response.status, 'REGISTER_FAIL'));
  dispatch({
  type: REGISTER_FAIL
  });
 });
};

// LogIn

export const login = ({ email, password }) => dispatch => {
// Headers
const config = {
  headers: {
    'Content-Type': 'application/json'
   }
 }

 // Request body

 const body = JSON.stringify({ email, password });

 axios.post('/api/auth', body, config)
  .then(res => dispatch({
     type: LOGIN_SUCCESS,
  payload: res.data
 }))
  .catch(err => {
  dispatch(returnErrors(err.response.data, err.response.status, 
 'LOGIN_FAIL'));
  dispatch({
    type: LOGIN_FAIL
  });
 });
};


// LogOut

export const logout = () => {
  return {
   type: LOGOUT_SUCCESS
 };
};


// Setup config/headers and Token

export const tokenConfig = (getState) => {

// Get token from localstorage
const token = getState().auth.token;

// Headers
const config = {
   headers: {
    "Content-type": "application/json"
  }
 }

 // Check if token exists, add to Headers
  if(token) {
    config.headers['x-auth=token'] = token;
  }

  return config;
 }

2 个答案:

答案 0 :(得分:2)

以您的图片https://imgur.com/D5OGLpf为基础,您对axios.delete('/api/items/${id}的请求未达到路线/api/items/:id

我为什么这么说?

响应状态为401(https://imgur.com/D5OGLpf),表示未授权。路由router.delete('/:id'的端点可能受到身份验证中间件或类似东西的保护。

要解决它,

第一

您需要使用为api设置的方式进行身份验证请求,即基本身份验证,oauth [2]或您自定义的请求。

然后

在发送dispatch(returnErrors...之前,您需要检查数据是否存在。

axios
 .delete(`/api/items/${id}`, tokenConfig(getState))
 .then(res => dispatch({
    type: DELETE_ITEM,
    payload: id
 }))
 .catch(err => {
   if(error.status === 404) {
      // here, you are sure that error.response.data exists
      dispatch(returnErrors(err.response.data, err.response.status)   
   }
   else {
      // do something else to handle the error
   }

 })

**请记住,**捕获的错误可以是您的错误状态400、500 ...到.then(...)内未捕获的错误。

答案 1 :(得分:1)

删除项目的内在承诺仍处于待处理状态,并且您已经注意到没有返回任何答复。

了解发生了什么。

Item.findById(req.params.id)
   .then(item => item.remove().then(() => res.json({ deleted: true 
})))
   .catch(err => res.status(404).json({ deleted: false }));
})

可以简化为

P.then(p => Q)

其中PQ是promise对象。

完成P后,它返回QQ继续保持待处理状态,等待其解决。

您可以通过展平Q链来解决then,以便在完成删除操作时进行处理。

Item.findById(req.params.id)
   .then(item => item.remove())
   .then(() => res.json({ deleted: true }))
   .catch(err => res.status(404).json({ deleted: false }));