React / Redux - Способ отправки - ошибка возврата - PullRequest
3 голосов
/ 14 марта 2019

В настоящее время я пытаюсь добавить и удалить свои элементы на странице, и возвращается ошибка.

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.

items api route

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 dev tools здесь:

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 ]

2 голосов
/ 14 марта 2019

База вашего изображения 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 голос
/ 14 марта 2019

Внутреннее обещание удалить элемент остается в состоянии ожидания и, как вы отметили, не возвращает никакого ответа.

Чтобы иметь представление о том, что происходит.

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)

, где P и Q являются объектами обещаний.

При выполнении P возвращается Q и Q продолжают оставаться в состоянии ожидания, ожидая его разрешения.

Вы можете разрешить Q, сгладив цепочку then для обработки после выполнения операции удаления.

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