Как решить Uncaught (в обещании) TypeError в реакции аутентификации? - PullRequest
0 голосов
/ 26 июня 2019

Я довольно новичок в стеке MERN. Я пытаюсь настроить аутентификацию пользователя с помощью jwt. Проблема возникает только тогда, когда я использую интерфейс для входа в систему. Когда я использую POST man для выполнения http-запроса, вход в систему успешен Однако, когда я вхожу, используя электронную почту и пароль, я получаю следующую ошибку:

Консоль

Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
at authActions.js:40

Я знаю, что это показывает, где находится ошибка, но я все еще не могу ее исправить.

authActions.js

import axios from "axios";
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";

import { GET_ERRORS, SET_CURRENT_USER, USER_LOADING } from "./types";

// Register User
export const registerUser = (userData, history) => dispatch => {
  axios
    .post("/api/users/register", userData)
    .then(res => history.push("/login")) // re-direct to login on successful register
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

// Login - get user token
export const loginUser = userData => dispatch => {
  axios
    .post("/api/users/login", userData)
    .then(res => {
      // Save to localStorage

      // Set token to localStorage
      const { token } = res.data;
      localStorage.setItem("jwtToken", token);
      // Set token to Auth header
      setAuthToken(token);
      // Decode token to get user data
      const decoded = jwt_decode(token);
      // Set current user
      dispatch(setCurrentUser(decoded));
    })
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

// Set logged in user
export const setCurrentUser = decoded => {
  return {
    type: SET_CURRENT_USER,
    payload: decoded
  };
};

// User loading
export const setUserLoading = () => {
  return {
    type: USER_LOADING
  };
};

// Log user out
export const logoutUser = () => dispatch => {
  // Remove token from local storage
  localStorage.removeItem("jwtToken");
  // Remove auth header for future requests
  setAuthToken(false);
  // Set current user to empty object {} which will set isAuthenticated to false
  dispatch(setCurrentUser({}));
};

Ниже приведен мой код для входа в систему.

login.jsx

class Login extends Component {
  constructor(props) {
    super(props);

    this.state = {
      email: "",
      password: ""
    };
  }
  componentDidMount() {
    // If logged in and user navigates to Login page, should redirect them to dashboard
    if (this.props.auth.isAuthenticated) {
      this.props.history.push("/dashboard");
    }
  }
  validateForm() {
    return this.state.email.length > 0 && this.state.password.length > 0;
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.auth.isAuthenticated) {
      this.props.history.push("/dashboard"); // push user to dashboard when they login
    }

    if (nextProps.errors) {
      this.setState({
        errors: nextProps.errors
      });
    }
  }

  handleChange = event => {
    this.setState({
      [event.target.id]: event.target.value
    });
  };

  handleSubmit = event => {
    event.preventDefault();
    console.log("Submit called");
    const userData = {
      email: this.state.email,
      password: this.state.password
    };

    this.props.loginUser(userData);
  };

  render() {
    const errors = this.state;
    return (
      <div className="Login">
        <form onSubmit={this.handleSubmit}>
          <FormGroup controlId="email" bs="large">
            <FormLabel>Email</FormLabel>
            <span className="red-text">{errors.emailnotfound}</span>
            <FormControl
              autoFocus
              type="email"
              value={this.state.email}
              onChange={this.handleChange}
              className={classnames("", {
                invalid: errors.email || errors.emailnotfound
              })}
            />
          </FormGroup>
          <FormGroup controlId="password" bs="large">
            <FormLabel>Password</FormLabel>
            <span className="red-text">
              {errors.password}
              {errors.passwordincorrect}
            </span>
            <FormControl
              value={this.state.password}
              onChange={this.handleChange}
              type="password"
              className={classnames("", {
                invalid: errors.password || errors.passwordincorrect
              })}
            />
          </FormGroup>
          <Button
            block
            bs="large"
            disabled={!this.validateForm()}
            type="submit"
          >
            Login
          </Button>
          <br />
          <p> Dont have account ? </p>
          <Link to="/register">
            {" "}
            <p style={{ color: "blue" }}> Join Us </p>{" "}
          </Link>
        </form>
        <br />
      </div>
    );
  }
}

Я упустил некоторые операторы импорта, чтобы сократить код.

Ответы [ 3 ]

0 голосов
/ 26 июня 2019

Вам необходимо обновить код с

onSubmit={this.handleSubmit} до onSubmit={()=>this.handleSubmit()}

А

onChange={this.handleChange} до onChange={()=>this.handleChange()}

из-за этого ваш пароль и адрес электронной почты не устанавливаются в состояние, и ваш API axios.post("/api/users/login", userData) вызывает исключение.

0 голосов
/ 26 июня 2019

Похоже, что вы не переводите данные в строку перед отправкой. Требовать библиотеку qs и изменить свой код на:

axios
.post("/api/users/register", qs.stringify( userData ))
.then(res => history.push("/login")) // re-direct to login on successful register
.catch(err =>
  dispatch({
    type: GET_ERRORS,
    payload: err.response.data
  })
);

Вы также можете проверить, что данные отправлены неправильно, просмотрев вкладку Network в инструментах разработчика вашего браузера. Я ожидаю отправить данные в неправильном формате. Я надеюсь, что я прав.

0 голосов
/ 26 июня 2019

Ошибка в строке 40, которая находится в payload: err.response.data.

Если указано

Невозможно прочитать свойство 'data' из неопределенного

Это означает, что err.response - это ndefined.

Вы должны сделать некоторую проверку, прежде чем пройти это.Возможно, он возвращает другую ошибку, у которой нет .response.

Попробуйте console.log(err) проверить, что внутри нее.

...