I am creating a registration functionality with redux. I have setup the store and reducer and the function register()
.
However, when I call the endpoint for the registration api it just doesnt register the user and from the redux actions file i get undefined for all of my data.
whenever i go to my redux dev tools i see that it says "Name is Required", "Username is Required", which are backend validation i have set up from my nodejs api, meaning that no values are reaching the api and everything i enter is undefined. Why is that?
I am new to redux so i don't know how to debug the issue or understand what is going wrong.
Here is my code:
actions/auth.js file:
export const register = ({ name, uniID, username, email, phoneNumber, uniIDImage, password }) => async dispatch => {
console.log(name, email, phoneNumber, uniIDImage, password);//logs undefined
const body = JSON.stringify({ name, uniID, username, email, phoneNumber, uniIDImage, password });
const emailBody = JSON.stringify({ name, email });
try {
const res = await axios.post('/register', body);
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
});
} catch (err) {
dispatch({
type:REGISTER_FAIL,
});
}
}
reducers/auth.js:
import {
REGISTER_SUCCESS,
REGISTER_FAIL,
} from "../actions/types";
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
loading: true,
user: null
};
export default function (state = initialState, action) {
const { type, payload } = action;
switch (type) {
case REGISTER_SUCCESS:
localStorage.setItem('token', payload.token);
return {
...state,
...payload,
isAuthenticated: true,
loading: false
}
case REGISTER_FAIL:
localStorage.removeItem('token');
return {
...state,
token: null,
isAuthenticated: false,
loading: false
}
default:
return state;
}
}
Register.js:
import React, {useEffect, useReducer, useState} from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import axios from "axios"
import { register } from '../../actions/auth';
const Register = ({ register }) => {
const [data, setData] = useState({
name: '',
uniID: '',
username: '',
email: '',
phoneNumber: '',
password: '',
});
const [uniIDImage, setUniIDImage] = useState([]);
const [success, setSuccess] = useState(false);
const handleChange = (e) => {
setData({ ...data, [e.target.name]: e.target.value });
}
const handleImage = (e) => {
e.persist()
setUniIDImage({ pic: e.target.files[0] });
}
const onRegister = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("name", data.name);
formData.append("uniID", data.uniID);
formData.append("username", data.username);
formData.append("email", data.email);
formData.append("phoneNumber", data.phoneNumber);
formData.append("uniIDImage", uniIDImage.pic);
formData.append("password", data.password);
register({formData});
}
Register.propTypes = {
register: PropTypes.func.isRequired,
};
export default connect(null, {register})(Register);
CodePudding user response:
you are passing "formData" type
// this is correct
register(formData);
but you are destructuring like a regular object
export const register = ({ name, uniID, username, email, phoneNumber, uniIDImage, password }) => async dispatch => {
If you check this mdn formData
const formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
// Display the values
for (const value of formData.values()) {
console.log(value);
}
when you received the formData
inside register
convert it to an object
export const register =(formData) => async(dispatch)=> {
let jsonObject = {};
for (let key of FormData.keys()) {
jsonObject[key] = formData.get(key);
}
// in axios post jsonObject
const res = await axios.post('/register', jsonObject);
};