How do I pass data to the backend using Reactjs? - reactjs

The backend is working properly with the Postman. but it not working correctly with my front end. This error occurs when I try to add a product. I used the Axios to send HTTP requests from the frontend to the backend. Please can you help me solve this error
Access to XMLHttpRequest at 'http://localhost:8070/products/' from origin 'http://localhost:1234' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is my AddProduct.js file.
import axios from "axios";
import React, { useState } from "react";
export default function AddProduct() {
const [name, setName] = useState();
const [description, setDescription] = useState();
const [qty, setQty] = useState(0);
const [price, setPrice] = useState(0);
const handleSubmit = async (e) => {
e.preventDefault();
const data = {
name,
description,
qty,
price,
};
console.log("data", data);
const insert = await axios
.post("http://localhost:8070/products/", data)
.then(() => {
alert("Product Added successfully");
e.target.reset();
})
.catch((err) => {
alert("Failed: " + err.message);
});
};
return (
<div className="p-5 m-5">
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label className="form-label">Name</label>
<input
type="text"
className="form-control"
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="mb-3">
<label className="form-label">Description</label>
<textarea
className="form-control"
onChange={(e) => setDescription(e.target.value)}
/>
</div>
<div className="mb-3">
<label className="form-label">Quantity</label>
<input
type="number"
className="form-control"
onChange={(e) => setQty(e.target.value)}
/>
</div>
<div className="mb-3">
<label className="form-label">Price</label>
<input
type="number"
className="form-control"
onChange={(e) => setPrice(e.target.value)}
/>
</div>
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
</div>
);
}
This is my AllProduct.js file.
import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
export default function AllProduct() {
const [product, setProduct] = useState();
const navigate = useNavigate();
var sum;
useEffect(() => {
axios
.get(`http://localhost:8070/products/`)
.then((res) => {
setProduct(res.data);
})
.catch((err) => {
alert("Failed: " + err.message);
});
}, []);
console.log(product);
const handleDelete = async (id) => {
let ans = window.confirm("Do you want to delete this product ?");
if (ans) {
await axios
.delete(`http://localhost:8070/products/${id}`)
.then(() => {
alert("Delete Successfully");
window.location.reload(false);
})
.catch((err) => {
alert("Failed: " + err.message);
});
}
};
const handleEdit = (product) => {
let { _id, name, description, qty, price } = product;
console.log("product", product);
localStorage.setItem("pID", _id);
localStorage.setItem("pName", name);
localStorage.setItem("pDescription", description);
localStorage.setItem("pQty", qty);
localStorage.setItem("pPrice", price);
navigate("/edit");
};
return (
<div className="p-5 m-5">
<table className="table">
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Quantity</th>
<th scope="col">Price</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{product?.map((product, index) => (
<tr key={index}>
<th scope="row">{index + 1}</th>
<td>{product.name}</td>
<td>{product.description}</td>
<td>{product.qty}</td>
<td>{product.price}</td>
<td>
<button
className="btn btn-danger"
onClick={() => handleDelete(product._id)}
>
Delete
</button>
</td>
<td>
<button
className="btn btn-warning"
onClick={() => handleEdit(product)}
>
Edit
</button>
</td>
</tr>
))}
</tbody>
</table>
{
(sum = product
?.map((product) => Number(product.price.replace("$", "")))
.reduce((prev, curr) => prev + curr, 0))
}
</div>
);
}
This is my editProduct.js
import React, { useEffect, useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
export default function EditProduct() {
const navigate = useNavigate();
const [id, setId] = useState();
const [name, setName] = useState();
const [description, setDescription] = useState();
const [qty, setQty] = useState();
const [price, setPrice] = useState();
useEffect(() => {
setId(localStorage.getItem("pID"));
setName(localStorage.getItem("pName"));
setDescription(localStorage.getItem("pDescription"));
setQty(localStorage.getItem("pQty"));
setPrice(localStorage.getItem("pPrice"));
}, []);
const handleUpdate = (e) => {
e.preventDefault();
const updateData = {
name,
description,
qty,
price,
};
console.log("id 27 ", id);
axios
.put(`http://localhost:8070/products/${id}`, updateData)
.then(() => {
alert("Product Update");
navigate("/all");
})
.catch((err) => {
alert(err);
});
};
return (
<div className="p-5 m-5">
<form onSubmit={handleUpdate}>
<div className="mb-3">
<label className="form-label">Name</label>
<input
type="text"
className="form-control"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="mb-3">
<label className="form-label">Description</label>
<textarea
className="form-control"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
</div>
<div className="mb-3">
<label className="form-label">Quantity</label>
<input
type="number"
className="form-control"
value={qty}
onChange={(e) => setQty(e.target.value)}
/>
</div>
<div className="mb-3">
<label className="form-label">Price</label>
<input
type="number"
className="form-control"
value={price}
onChange={(e) => setPrice(e.target.value)}
/>
</div>
<button type="submit" className="btn btn-warning" href="/all">
update
</button>
</form>
</div>
);
}

This error is a CORS Policy, or to be specific, Cross-Origin Resource Sharing,
What you need to do, assuming you are using nodejs express, is this couple of lines in the app.js module.
install cors
npm i cors
const cors = require("cors");
server.use(cors({ origin: "http://localhost:8070" }));
This will enable data-transfer between the FE and the BE.

you need to setup cors options on your server. If its a node server i recommend this library https://www.npmjs.com/package/cors everything is explained on the documentation.
on setup you need allow your frontend url which is http://localhost:1234

Related

React <input> value will not change when edit

I'm trying to have an edit page to update the details of the existing object. I have some input elements to contain the value. But when I rendered the page, the values displayed in the input boxes will not allow me to change in view - when I delete or type in new, the values in the boxes will never change. Can anyone help to figure out the matter?
import React, {useEffect, useState} from "react";
import Sidebar from "../components/Sidebar";
import {FontAwesomeIcon} from "#fortawesome/react-fontawesome";
import {useNavigate, useParams} from "react-router-dom";
import Axios from "axios";
import axios from "axios";
function CourseEdit() {
let navigate = useNavigate();
const [fname, setFname] = useState("");
const [lname, setLname] = useState("");
const [gender, setGender] = useState("");
const [age, setAge] = useState("");
const [description, setDescription] = useState("");
const [payment, setPayment] = useState("0");
const [student, setStudent] = useState({});
const {id} = useParams();
const editStudent = (id) => {
Axios.put('http://localhost:3001/student_edit', {
fname: fname,
lname: lname,
gender: gender,
age: age,
description: description,
payment: payment,
id: id,
}).then(() => {
alert('Student updated');
navigate(`../students/detail/${id}`);
console.log("student updated");
});
}
useEffect(() => {
axios.get(`http://localhost:3001/students/${id}`).then((response) => {
setStudent(response.data[0]);
// console.log(response.data[0].id);
})},[id]);
return (
<div className="grid-container">
<Sidebar/>
<div className="main_content grid-2">
<div className="details">
<div className="icon" style={{color: "#f7931e"}}>
<FontAwesomeIcon icon="user"/> Edit STUDENT
<div className="back-button" onClick={() => navigate(-1)}>
<FontAwesomeIcon icon="arrow-alt-circle-left"/>BACK
</div>
</div>
<div className="detail-content" style={{marginTop: "1.2em"}}>
<table>
<tbody>
<tr>
<td className="td-left" style={{width: "100%"}}>
<label htmlFor="StudentName">Student First Name:</label>
</td>
<td className="td-right" style={{width: "85%"}}>
<input className="mb" type="text" name="studentFname" id="detail_input"
value={student.fname} onChange={(event) => {
setFname(event.target.value)
}} required/>
</td>
</tr>
<tr>
<td className="td-left" style={{width: "100%"}}>
<label htmlFor="StudentName">Student Last Name:</label>
</td>
<td className="td-right" style={{width: "85%"}}>
<input className="mb" type="text" name="studentLname" id="detail_input"
onChange={(event) => {
setLname(event.target.value)
}} value={student.lname} required/>
</td>
</tr>
...
...
...
</tbody>
</table>
<div>
<button className="green_bt option_list round mr" onClick={() => {editStudent(`${id}`)}}>Save
</button>
<button className="red_bt option_list round mr" onClick={() => navigate(-1)}>Cancel
</button>
</div>
</div>
</div>
</div>
</div>
)
}
export default CourseEdit;
To set a default value for an input element in React:
1 - Pass the default value as a parameter to the useState hook for controlled fields.
2 - Set the defaultValue prop on uncontrolled input fields
in your case you're using controlled input so you have to pass the default to useState like this :
const [fname, setFname] = useState(student.fname);
const [lname, setLname] = useState(student.lname);
and change the input field like this :
<input className="mb" type="text" name="studentFname" id="detail_input"
value={fname} onChange={(event) => { setFname(event.target.value)}}
required/>
and :
<input className="mb" type="text" name="studentLname" id="detail_input"
onChange={(event) => {setLname(event.target.value)}} value={lname}
required/>

Why isnt my dropdown sending data with my onChange

So im trying to make a categories post, the backend part works but it isnt sending any data. i think it's something with my onChange. It works if I do it as a single input and manually type in said category but when I try to do it in a dropdown menu it isnt reading the value i think. My backend has an enum of "grinders" and "trays right now.
This is my front end code
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js">
import React from "react";
import axios from "axios";
import { post } from "../services/service";
const Post = () => {
const [title, setTitle] = React.useState("");
const [content, setContent] = React.useState("");
const [price, setPrice] = React.useState("");
const [postPic, setPostPic] = React.useState("");
const [category, setCategory] = React.useState(""); //THIS IS MY HOOK FOR CATEGORIES
const [status, setStatus] = React.useState("");
const createPost = async (e) => {
e.preventDefault();
if (!title || !category) {
setStatus("Please enter a title and category");
} else {
try {
const response = await post("/posts/create", {
title: title,
content: content,
price: "$" + price,
postPic: postPic,
typeOfCategory: category,
});
console.log("DATA", response.data);
} catch (err) {
console.error(err.message);
}
}
};
const handleFileUpload = async (e) => {
try {
// setLoading(true);
const uploadData = new FormData();
uploadData.append("imageUrl", e.target.files[0]);
let response = await post("/posts/add-picture", uploadData);
setPostPic(response.data.path);
// setLoading(false);
} catch (err) {
console.error(err.message);
// setLoading(false);
setStatus("Image must be .png, .jpeg, or .webp");
}
};
return (
<div className="post-page">
<form className="login-inputs" onSubmit={createPost}>
<h1 className="post-title">Create post</h1>
<input
placeholder="Title..."
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<div className="postpic-img-section">
<img
className="postpic-img"
src={
postPic ||
"https://www.freeiconspng.com/thumbs/no-image-icon/no-image-icon-15.png"
}
alt="Profile Picture"
/>
</div>
<textarea
placeholder="Content..."
type="text"
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<input
className="price-input"
placeholder="$0"
type="number"
value={price}
onChange={(e) => setPrice(e.target.value)}
/>
{/* <input
placeholder="category"
type="text"
value={category}
onChange={(e) => setCategory(e.target.value)}
/> */}
<label htmlFor="file-upload" className="custom-file-upload">
<i className="fa fa-cloud-upload">
<img
src="https://www.freeiconspng.com/thumbs/upload-icon/upload-icon-22.png"
alt="Upload"
height="20"
/>
Custom Upload
</i>
</label>
<input id="file-upload" type="file" onChange={handleFileUpload} />
{/* THIS IS WHERE IM TRYING TO MAKE THE DROPDOWN OF THE CATEGORIES */}
<select value={category} onChange={(e) => setCategory(e.target.value)}>
<option value="grinders">grinders</option>
<option value="trays">Trays</option>
</select>
<button>Submit</button>
<p className="login-status">{status}</p>
</form>
</div>
);
};
export default Post;
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
There is nothing wrong with your select handling. I've just copy-pasted your relevant code snippet and it works well.
const App = () => {
const [category, setCategory] = React.useState("")
return (
<div>
<div>typeOfCategory: {category}</div>
<select value={category} onChange={(e) => setCategory(e.target.value)}>
<option value="" disabled>Please select</option>
<option value="grinders">grinders</option>
<option value="trays">Trays</option>
</select>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Im dumb my token expired and I have a isAuth in my backend

update input of user in map function React hooks

New to react hooks...
I've brought some data of users from an API and I want to update one or more of the inputs by clicking a submit button.
I can see in the state that the user's last letter changes but I can see the new input on the screen and I can not change the entire word. And I don't know if it is supposed to change also in the whole array of users or it is impossible once I've called them from the API.
Thanks
import { useState } from 'react'
import axios from 'axios'
function UsersComp() {
const [user, setUser] = useState()
const [users, setUsers] = useState([])
const [id, setId] = useState(0)
const getUsers=async ()=>{
let resp = await axios.get("https://jsonplaceholder.typicode.com/users")
setUsers(resp.data);
}
const update = async (e) =>
{
e.preventDefault();
let resp = await axios.put("https://jsonplaceholder.typicode.com/users/" + id, user)
}
return (
<div calssname="App">
<form onSubmit={e => update(e)}>
{
users.map((item) =>
{
return <tbody key={item.id}>
<tr><td>
ID:{item.id} <br/>
Name:<input value={item.name} onChange={e => setUser({...user, name : e.target.value})} type="text" name="name" /> <br/>
Email:<input value={item.email} onChange={e => setUser({...user, email : e.target.value})} type="text" name="email" /> <br/>
<input type="button" value="Add Data"/>
<input type="submit" value="Update"/>
<input type="button" value="Delete"/><br/>
</td></tr>
</tbody>
})
}
</form>
<input type="button" value="Get users" onClick={getUsers} /> <br/>
</div>
);
}
export default UsersComp;
You can update onChange like this by using map:
onChange={(e) =>
setUser(
users.map((eachUser) =>
item.id === eachUser.id ? { ...eachUser, name: e.target.value } : eachUser,
),
)
}

React limits the number of renders to prevent an infinite loop

I am making an application and I have an error that I do not understand very well. Apparently, it is in the hook that I am using to make protected pages. I share the error and the code below.
Unhandled Runtime Error Error: Too many re-renders. React limits the
number of renders to prevent an infinite loop.
import firebase from "firebase";
const firebaseConfig = {
apiKey: "Key",
authDomain: "Domain",
databaseURL: "URL",
projectId: "Id",
storageBucket: "Bucket",
messagingSenderId: "SenderId",
appId: "appId",
measurementId: "measurementId",
};
// Initialize Firebase
!firebase.apps.length && firebase.initializeApp(firebaseConfig);
export const database = firebase.database().ref();
const mapUserFromFirebaseAuthToUser = (user) => {
const { displayName, email, uid } = user;
return {
userName: displayName,
email,
uid,
};
};
export const onAuthStateChanged = (onChange) => {
const emailProvider = new firebase.auth();
return emailProvider.onAuthStateChanged((user) => {
const normalizedUser = user ? mapUserFromFirebaseAuthToUser(user) : null;
onChange(normalizedUser);
});
};
export const loginUser = ({ email, password }) => {
const emailProvider = new firebase.auth();
return emailProvider.signInWithEmailAndPassword(email, password);
};
export const singUp = () => {
const emailProvider = new firebase.auth();
return emailProvider.signOut();
};
the page where the application breaks
import { useState, useEffect } from "react";
import styles from "styles/Countries.module.css";
import useUser, { USER_STATES } from "hooks/useUser";
import NavbarMenu from "components/navBar";
import Footer from "components/footer";
import { database } from "utils/firebase";
import {
Table,
Button,
Container,
Modal,
ModalBody,
ModalHeader,
ModalFooter,
FormGroup,
} from "reactstrap";
export default function Countries() {
const user = useUser();
const [timeLine, setTimeLine] = useState([]);
const [isOpenModalAdd, setIsOpenModalAdd] = useState(false);
const [isOpenModalEdit, setIsOpenModalEdit] = useState(false);
const [name, setName] = useState("");
const [currency, setCurrency] = useState("");
const [base, setBase] = useState("");
const [km, setKm] = useState("");
const [minute, setMinute] = useState("");
const [code, setCode] = useState("");
const [country, setCountry] = useState({
name: "",
currency_code: "",
base_fare: "",
per_km: "",
per_minute: "",
});
useEffect(() => {
database.child("Admin/Country").on("value", (snapshot) => {
setTimeLine(snapshot.val());
});
}, []);
const selectCountry = (data, id, status) => {
setCountry(data);
setCode(id);
status === "edit" && setIsOpenModalEdit(true);
};
const editCountry = () => {
database.child("Admin/Country/" + code).set(country);
resetModalAdd();
setIsOpenModalEdit(false);
};
const saveCountry = () => {
const MapCountry = {
name: name,
currency_code: currency,
base_fare: base,
per_km: km,
per_minute: minute,
};
database.child("Admin/Country/" + code).set(MapCountry);
resetModalAdd();
setIsOpenModalAdd(false);
};
const resetModalAdd = () => {
setName("");
setCurrency("");
setBase("");
setKm("");
setMinute("");
setCode("");
};
const openModalAdd = () => {
setIsOpenModalAdd(true);
};
const closeModalAdd = () => {
setIsOpenModalAdd(false);
};
const handleChangeName = (event) => {
const { value } = event.target;
setName(value);
let string = value;
let part = string.split("");
if (part.length === 2) {
let code = part[0].toUpperCase() + part[1].toUpperCase();
setCode(code);
}
};
const handleChangeData = (event) => {
const { value } = event.target;
setCountry(value);
};
const handleChangeCurrency = (event) => {
const { value } = event.target;
setCurrency(value);
};
const handleChangeBase = (event) => {
const { value } = event.target;
setBase(value);
};
const handleChangeKm = (event) => {
const { value } = event.target;
setKm(value);
};
const handleChangeMinute = (event) => {
const { value } = event.target;
setMinute(value);
};
return user ? (
<>
<div className={styles.container}>
<div className={styles.principalMenu}>
<NavbarMenu>
<div className={styles.titleHeader}>
<div className={styles.title}>Administration System</div>
<div className={styles.subtitle}>User: {user.userName}</div>
</div>
</NavbarMenu>
</div>
<div>
<h3>Country</h3>
</div>
<Container>
<Button color="primary" onClick={openModalAdd}>
New Country
</Button>
<Table>
<thead>
<tr>
<th>Name</th>
<th>Currency Code</th>
<th>Base Fare</th>
<th>Per Km</th>
<th>Per Minute</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{Object.keys(timeLine).map((i) => {
return (
<tr key={i}>
<td>{timeLine[i].name}</td>
<td>{timeLine[i].currency_code}</td>
<td>{timeLine[i].base_fare}</td>
<td>{timeLine[i].per_km}</td>
<td>{timeLine[i].per_minute}</td>
<td>
<Button
color="primary"
onClick={selectCountry(timeLine[i], i, "edit")}
>
Editar
</Button>
{" "}
<Button color="danger">Eliminar</Button>
</td>
</tr>
);
})}
</tbody>
</Table>
<Modal isOpen={isOpenModalAdd}>
<ModalHeader>Insertar Registro</ModalHeader>
<ModalBody>
<div className="form-group">
<label>Name: </label>
<br />
<input
type="text"
className="form-control"
value={name}
onChange={handleChangeName}
/>
<label>Currency Code: </label>
<br />
<input
type="text"
className="form-control"
value={currency}
onChange={handleChangeCurrency}
/>
<label>Base Fare: </label>
<br />
<input
type="text"
className="form-control"
value={base}
onChange={handleChangeBase}
/>
<label>Per Km: </label>
<br />
<input
type="text"
className="form-control"
value={km}
onChange={handleChangeKm}
/>
<label>Per Minute: </label>
<br />
<input
type="text"
className="form-control"
value={minute}
onChange={handleChangeMinute}
/>
</div>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={saveCountry}>
Guardar
</Button>
{" "}
<Button color="danger" onClick={closeModalAdd}>
Cancelar
</Button>
</ModalFooter>
</Modal>
<Modal isOpen={isOpenModalEdit}>
<ModalHeader>Editar Registro</ModalHeader>
<ModalBody>
<div className="form-group">
<label>Name: </label>
<br />
<input
type="text"
className="form-control"
name="name"
value={country.name}
onChange={handleChangeData}
/>
<label>Currency Code: </label>
<br />
<input
type="text"
className="form-control"
name="currency_code"
value={country.currency_code}
onChange={handleChangeData}
/>
<label>Base Fare: </label>
<br />
<input
type="text"
className="form-control"
name="base_fare"
value={country.base_fare}
onChange={handleChangeData}
/>
<label>Per Km: </label>
<br />
<input
type="text"
className="form-control"
name="per_km"
value={country.per_km}
onChange={handleChangeData}
/>
<label>Per Minute: </label>
<br />
<input
type="text"
className="form-control"
name="per_minute"
value={country.per_minute}
onChange={handleChangeData}
/>
</div>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={editCountry}>
Guardar
</Button>
{" "}
<Button color="danger" onClick={setIsOpenModalEdit(false)}>
Cancelar
</Button>
</ModalFooter>
</Modal>
</Container>
<Footer />
</div>
</>
) : user === USER_STATES.NOT_KNOWN ? (
<>
<div className={styles.container}>
<h1>Loading...</h1>
</div>
</>
) : (
<>
<div className={styles.container}>
<h1>Not authorized</h1>
</div>
</>
);
}
The hooks used for protected pages:
import { Router } from "next/router";
import { useState, useEffect } from "react";
import { useRouter } from "next/router";
import { onAuthStateChanged } from "utils/firebase";
export const USER_STATES = {
NOT_LOGGED: null,
NOT_KNOWN: undefined,
};
export default function useUser() {
const [user, setUser] = useState(USER_STATES.NOT_KNOWN);
const router = useRouter();
useEffect(() => {
onAuthStateChanged(setUser);
}, []);
useEffect(() => {
user === USER_STATES.NOT_LOGGED && router.push("/login");
}, [user]);
return user;
}
I hope this is enough to give me a hand. I have already tried to solve but the truth is I do not find the problem.
The logic in these lines is not correct:
useEffect(() => {
onAuthStateChanged(setUser);
}, []);
useEffect(() => {
user === USER_STATES.NOT_LOGGED && router.push("/login");
}, [user]);
I understand the first useEffect is used to update the state,
but the second useEffect watches this state and returning boolean?
Instead of user === USER_STATES.NOT_LOGGED && router.push("/login");, it should be:
if (USER_STATES.NOT_LOGGED) { router.push("/login"); }

How does react redux dependencies work with redux

I have written a code to manage users profile with JWT , I have used useState to manage the form inputs and working with redux to manage the data. The inputs are not being updated with the data we are receiving from api/action
import React, { useEffect, useState } from 'react'
import {useDispatch, useSelector} from 'react-redux'
import {getUser , updateUser} from '../actions/userActions'
import '../css/profile.css'
import {listMyOrders} from '../actions/orderActions'
import { Link } from 'react-router-dom'
const Profile = ({history}) => {
const dispatch = useDispatch();
const [name , setName] = useState('');
const [email , setEmail] = useState('');
const [password , setPassword] = useState('');
const [confirmPassword , setConfirmPassword] = useState('');
const userLogin = useSelector((state) => state.userLogin);
const userProfile = useSelector((state) => state.userProfile);
const {userData , loading , error} = userProfile;
const myOrders = useSelector(state => state.orderListMy);
const {orders , loading:loadingOrders} = myOrders;
useEffect(
async () => {
if (!userLogin.userData) {
history.push('/login')
} else {
if (!userData || !userData.name) {
dispatch(getUser());
dispatch(listMyOrders());
}
if(!myOrders.order){
dispatch(listMyOrders());
}
else {
setName(userData.name);
setEmail(userData.email);
}
}
}
, [dispatch, history , userData , userLogin.userData]);
const handleUpdate = () => {
if(password == confirmPassword) {
dispatch(updateUser( userData._id , loading , name , email , password));
}
}
return (
<section id="profile">
<div className="inside">
<div className="user-profile">
<p className="title">User Profile</p>
<div className="msg-container">
</div>
<div className="name-container">
<label className="name-label">Name</label>
<input type="name" onLoad={ (e) =>
setTimeout(console.log('hello') , 1000)
} onChange={(e) => setName(e.target.value)} value={name} placeholder="Your Name" htmlFor="name" />
</div>
<div className="email-container">
<label className="email-label">Email Address</label>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email address" htmlFor="email" />
</div>
<div className="password-container">
<label className="password-label">Password</label>
<input type="password" placeholder="Password" htmlFor="password" />
</div>
<div className="password-container">
<label className="password-label">Confirm Password</label>
<input type="password" placeholder="Confirm Password" htmlFor="password" />
</div>
<button onClick={handleUpdate} className="submit">Update</button>
</div>
<div className="my-orders">
<div className="title">My Orders</div>
<table>
<thead>
<tr>
<td>ID</td>
<td>DATE</td>
<td>TOTAL</td>
<td>PAID</td>
<td>DELIVERED</td>
<td />
</tr>
</thead>
<tbody>
{!loadingOrders && orders.map(order => (
<tr key={order._id}>
<td>{order._id}</td>
<td>{order.createdAt.substring(0, 10)}</td>
<td>{order.totalPrice}</td>
<td>{order.isPaid ? (
order.paidAt.substring(0, 10)
) : (
<i className='fas fa-times' style={{ color: 'red' }}></i>
)}</td>
<td>{order.isDelivered ? (
order.deliveredAt.substring(0, 10)
) : (
<i className='fas fa-times' style={{ color: 'red' }}></i>
)}</td>
<td><Link to={`/order/${order._id}`}><button className="details">Details</button></Link></td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</section>
)
}
export default Profile
here are the code for reducers and actions I have written
//reducer
//state - userProfile
export const userGetProfileReducer = (state = {userData : {}} , action) => {
switch(action.type) {
case USER_GET_REQUEST :
return { loading : true , state};
case USER_GET_SUCCESS :
return ({ loading : false , userData : action.payload });
case USER_GET_ERROR :
return ({ loading : false , error : action.payload });
default :
return state;
}
}
//action - getUser
export const getUser = () => async(dispatch , getState) => {
dispatch({type : USER_GET_REQUEST , loading : true })
const headers = {headers : {
'Content-Type' : 'application/json',
'AUTHORIZATION' : `Bearer ${getState().userLogin.userData.token}`
}}
try {
const {data} = await axios.get('http://localhost:5000/api/users/profile', headers);
dispatch({type : USER_GET_SUCCESS , payload : data , loading : false});
} catch (error) {
console.log(error);
dispatch({type : USER_GET_ERROR , loading : false , payload: error.response && error.response.data.message
? error.response.data.message
: error.message})
}
}
Note - Orders functionality is working perfectly fine. Inputs fields are not being updated with response data. I am sure I have messed up with useEffect dependencies. It would be good if someone can help me......

Resources