React - history.push not working after data fetch - node.js

I have some code coming back from my database and i want to redirect in the .then - when and if there is a res , but when i put the history.push in the .then- it doesn't render anything of inside the .then
here is some code:
import React, { useState } from 'react'
import { connect } from "react-redux";
import { CreateAccount as createAccountService } from '../services/user'
import { actions } from '../store/actions';
import { Redirect, withRouter } from "react-router-dom";
import { useHistory } from 'react-router-dom';
const mapStateToProps = (state) => {
return { ...state, user: state.userReducer.user || [] }
}
const mapDispatchToProps = (dispatch) => ({
setUser: (loggedUser) => dispatch(actions.setUser(loggedUser))
})
const CreateAccount = withRouter(function CreateAccount(props) {
const history = useHistory();
const [nameI, setName] = useState('');
const [emailI, setEmail] = useState('');
const [passwordI, setPassword] = useState('');
function createAccountHandler() {
createAccountService({ name: nameI, email: emailI, password: passwordI })
.then(res => {
alert(res.name) //brings the res.name but when the history.push is here it doens't show the alert
history.push('/posts') // <= the problem!
})
.catch((err) => {
alert('err in createAccount' + err)
})
}
return (<>
<div className="wrapper fadeInDown">
<div id="formContent">
<form>
<input type="text" id="name" class="fadeIn first" name="name" placeholder="name" onChange={e => setName(e.target.value)} />
<input type="text" id="email" class="fadeIn second" name="email" placeholder="email" onChange={e => setEmail(e.target.value)} />
<input type="text" id="password" class="fadeIn third" name="createAccount" placeholder="password" onChange={e => setPassword(e.target.value)} />
<input onClick={createAccountHandler} type="submit" class="fadeIn fourth" value="Create Account" />
</form>
</div>
</div>
</>)
}
)
export default connect(
mapStateToProps,
mapDispatchToProps
)(CreateAccount);

You Should try the following:
<form onSubmit={createAccountHandler}>
<input type="text" id="name" class="fadeIn first" name="name" placeholder="name" onChange={e => setName(e.target.value)} />
<input type="text" id="email" class="fadeIn second" name="email" placeholder="email" onChange={e => setEmail(e.target.value)} />
<input type="text" id="password" class="fadeIn third" name="createAccount" placeholder="password" onChange={e => setPassword(e.target.value)} />
<input type="submit" class="fadeIn fourth" value="Create Account" />
</form>
const createAccountHandler = (e) => {
e. preventDefault();
createAccountService({ name: nameI, email: emailI, password: passwordI })
.then(res => {
alert(res.name) //brings the res.name but when the history.push is here it doens't show the alert
history.push('/posts') // <= the problem!
})
.catch((err) => {
alert('err in createAccount' + err)
});
}

Related

filereader using react and cloudinary

when I try to upload an image , i get these 2 errors :
(reader.onloadend is not a function at privewFile) and (Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.)
this is the code :
export default function Register() {
const [user, setUser] = useState({
username:"",
email:"",
password:"",
age:0,
gender:"",
})
const [file, setFile] = useState(null)
const [img,setImg] = useState("")
const handleChange = (event) => {
setUser({
...user,
[event.target.id]: event.target.value,
});
}
function privewFile(file) {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onloadend(() => {
setImg(reader.result)
})
console.log(img);
}
const handleFile = (event) => {
if (event.target.files && event.target.files[0]) {
const pic = event.target.files[0]
setFile(pic)
privewFile(file)
}}
const handleSubmit = (event) => {
event.preventDefault()
console.log(user);
console.log(file);
}
return (
<div className='container'>
<div className='left'>
<div className='logo'>
<DatabaseNetworkPoint theme="outline" size="150" fill="#333"/>
<h1>WonderHit</h1>
</div>
<form className='form' onSubmit={handleSubmit}>
<input placeholder='Username' id='username' value={user.username} className='field' type="text" onChange={handleChange} />
<input placeholder='Email' id='email' value={user.email} className='field' type="email" onChange={handleChange} />
<input placeholder='Password' id='password' value={user.password} className='field' type="password" onChange={handleChange} />
<input placeholder='Age' id='age' value={user.age} className='field' type="number" onChange={handleChange} />
<input placeholder='Gender' id='gender' value={user.gender} className='field' type="text" onChange={handleChange} />
<div className='profilePic'>
<div className='Photo'>
<img className='Photo' src={img} />
</div>
<input className='field2' id='file' type="file" accept=".png, .jpg, .jpeg" onChange={(e) => handleFile(e)} />
<label htmlFor = "file" className='uploadPic' >+</label>
</div>
<button className='submit' type="submit">Register</button>
<h3 className='routing'>You already have an account ? <Link className='rot' to="/">Login</Link></h3>
</form>
</div>
<img className='right' src='https://images.unsplash.com/photo-1562577309-4932fdd64cd1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074&q=80' />
</div>
)
}
what is the problem here guys ? can you help ?????
It should be working just fine , I have no idea what is wrong
In your handleFile function. You are creating a constant of pic. You need to send this constant to the priviewFile function I think....like this:
const handleFile = (event) => {
if (event.target.files && event.target.files[0]) {
const pic = event.target.files[0]
setFile(pic)
privewFile(pic)
}}

How to pass my data in the backend in my axios reactjs

I have a problem and I am ensure this is my problem setusername(res.data[0].username)
So basically I watch MERN stack tutorial and I was at my this part 1:27:30. Basically It means to I want to pass my data username based on my list of users in creating exercises. Everything is fine but not only this setusername(res.data[0].username)
Here is the full code.. for Create_exercises()
NOTE I CONVERTED THE CLASS COMPONENT INTO REACT HOOKS SINCE IT KINDA LOOKS UGLY IN MY EYE
function Create_exercise() {
const [username,setusername] = useState()
const [description,setdescription] = useState()
const [duration,setduration] = useState()
const [date,setdate] = useState( new Date() )
const [users, setusers] = useState([])
const handleChangeUsername = e => {
setusername(e.target.value)
}
const handleChangeDesciption = e => {
setdescription(e.target.value)
}
const handleChangeDuration = e => {
setduration(e.target.value)
}
const handleChangeDate = date_new => {
setdate(date_new)
}
const handleSubmit = e => {
e.preventDefault()
const exercise = {
username: username,
description: description,
duration:duration,
date:date
}
console.log(exercise);
axios.post('http://localhost:4500/exercises/add',exercise)
.then(res => console.log(res.data))
.catch(err => console.log(err));
// window.location = '/';
}
useEffect(() => {
// setusers(['test user'])
// setusername('test user')
axios.get('http://localhost:4500/users/')
.then(res => {
if (res.data.length > 0) {
// console.log(users)
// console.log(res.data)
setusers(res.data.map((user => user.username)))
setusername(res.data[0].username)
// console.log(res.data[0].username)
}
})
},[])
return (
<div className='form-container'>
<form action="" onSubmit={e => handleSubmit(e)}>
<div className="title"><h1> Create New Exercise Log</h1></div>
<div className="form-group">
<label htmlFor="">Username: </label>
<select name="" id="">
{
users.map((user,idx) => {
return(
<option
key={user}
value={user}
>
{user}
</option>
)
})
}
</select>
</div>
<div className="form-group">
<label htmlFor="">Description: </label>
<input type="text"
required
className='form-control'
value={description}
onChange={e => handleChangeDesciption(e)}
/>
</div>
<div className="form-group">
<label htmlFor="">Duration (in minutes): </label>
<input type="text"
required
className='form-control'
value={duration}
onChange={e => handleChangeDuration(e)}
/>
</div>
<div className="form-group">
<label htmlFor="">Date: </label>
<div>
<DatePicker
selected= {date}
onChange= {e => handleChangeDate(e)}
>
</DatePicker>
</div>
</div>
<div className="form-group">
<input type="submit" value="Create Exercise Log"/>
</div>
</form>
</div>
)
}
export default Create_exercise
Let say I have 3 items in data that in my mongoDB.. Let say data = [{username:"Johnny",_id:"613fagadafa43d",description:"Egg"},{username:"Lamby",_id:"613dasnaafaF",description:"Betlog"},{username:"Bummby",_id:"613d66naafaF",description:"Betlog"}]
when I am trying to create a exercise that I will choose based on this three.. I always create the first item in data list. So it has something to with this setusername(res.data[0].username) since it is the first index.. I want to create a exercise wherein I can choose whose name should I create the data but I always get this thingy "Johnny" name in the data.. I wanna badly done this so I could understand how mern stack works..I'm so confused..help.
This is also same with Edit_exercise() based on the tutorial of MERN stack at part of MERN 1:45:06
Sorry I'm so bad at this explaining but this is just how I will imagined and describe the problem..I know its kinda simple but I don't know if I ask the right question.
function Edit_exercise() {
const { id } = useParams()
const [username,setusername] = useState()
const [description,setdescription] = useState()
const [duration,setduration] = useState()
const [date,setdate] = useState( new Date() )
const [users, setusers] = useState([])
const handleChangeUsername = e => {
setusername(e.target.value)
}
const handleChangeDesciption = e => {
setdescription(e.target.value)
}
const handleChangeDuration = e => {
setduration(e.target.value)
}
const handleChangeDate = date_new => {
setdate(date_new)
}
const handleSubmit = e => {
e.preventDefault()
const exercise = {
username: username,
description: description,
duration:duration,
date:date
}
console.log(exercise);
axios.put('http://localhost:4500/exercises/update/'+id,exercise)
.then(res => console.log(res.data))
.catch(err => console.log(err));
// window.location = '/';
}
useEffect(() => {
axios.get('http://localhost:4500/exercises/'+id)
.then(res => {
setusername(res.data.username)
setdescription(res.data.description)
setduration(res.data.duration)
setdate(new Date(res.data.date))
})
setusers(['test user'])
setusername('test user')
axios.get('http://localhost:4500/users')
.then(res => {
if (res.data.length > 0) {
setusers(res.data.map((user => user.username)))
setusername(res.data[0].username)
}
})
},[])
return (
<div className='form-container'>
<form action="" onSubmit={e => handleSubmit(e)}>
<div className="title"><h1> Edit Exercise Log</h1></div>
<div className="form-group">
<label htmlFor="">Username: </label>
<select name="" id="">
{
users.map((user,idx) => {
return(
<option
key={user}
value={user}
>
{user}
</option>
)
})
}
</select>
</div>
<div className="form-group">
<label htmlFor="">Description: </label>
<input type="text"
required
className='form-control'
value={description}
onChange={e => handleChangeDesciption(e)}
/>
</div>
<div className="form-group">
<label htmlFor="">Duration (in minutes): </label>
<input type="text"
required
className='form-control'
value={duration}
onChange={e => handleChangeDuration(e)}
/>
</div>
<div className="form-group">
<label htmlFor="">Date: </label>
<div>
<DatePicker
selected= {date}
onChange= {e => handleChangeDate(e)}
>
</DatePicker>
</div>
</div>
<div className="form-group">
<input type="submit" value="Edit Exercise Log"/>
</div>
</form>
</div>
)
}
export default Edit_exercise

Proxy error: Could not proxy request /send from localhost:3000 to http://localhost:3001/

I'm sending some data from my ReactJS front-end application to my node/express backend, however, whenever I send the data, I get the error message mentioned in the title.
https://ibb.co/KbpwqZv
contact.js
This is my react js code where i declare my react from those who communicate with backend via axios
import React, { useState } from 'react'
import "./Contact.css";
import Axios from 'axios';
import {API} from '../backend';
const Contact = () => {
const [state,setState]= useState({
name:'',
lastname:'',
email:'',
message:'',
})
const [result,setResult] = useState(null);
const sendMail = e =>{
e.preventDefault();
Axios.post('/send',{...state})
.then(response => {
setResult(response.data);
setState({
name:'',
lastname:'',
email:'',
message:''
})
})
.catch(()=>{
setResult({
success:false,
message:"Something went wrong. Try again later"
})
setState("");
})
}
const onInputChange = e =>{
const {name,value} = e.target;
setState({
...state,
[name]: value
})
}
console.log("API is",API);
return (
<>
{result && (
<p className={`${result.success ? 'success' : 'error'}`}>
{result.message}
</p>
)}
<section className='contactus'>
<div className="container">
<h1 className='title'>CONTACT US</h1>
<form >
<div className="singleItem">
<label htmlFor="name">Name</label>
<input type="text"
name="name"
className="name"
placeholder="Your Name..."
value={state.name}
onChange={onInputChange}
/>
</div>
{/* <div className="singleItem">
<label htmlFor="Lastname">LastName</label>
<input type="text"
name="LastName"
className="LastName"
placeholder="Your Last Name..."
value={state.lastname}
onChange={onInputChange}
/>
</div> */}
<div className="singleItem">
<label htmlFor="email">Email</label>
<input type="email"
name="email"
className="email"
placeholder="Your Email..."
value={state.email}
onChange={onInputChange}
/>
</div>
<div className='textArea singleItem'>
<label htmlFor="message">Message</label>
<textarea name="message"
id=""
col="30"
rows="5"
placeholder="Your Message..."
value={state.message}
onChange={onInputChange}
>
</textarea>
</div>
<div className="msg">Message has been Sent</div>
<button type="button" className='btn btn-primary' onClick={sendMail}>Submit</button>
</form>
</div>
</section>
</>
)
}
export default Contact;

using React can I prevent sending empty strings from my inputs to my mongodb database during update?

I have inputs that take in information that is set to the state. The states initial values is set to empty strings. none of the inputs are required inputs so some may remain blank I then send the inputted information to the the API but that may send possible empty strings which would replaces information that I don't want to update.
I tried setting the initial states to undefined but i got the uncontrolled inputs error because I know undefined values would not be accepted in my database.
I have thought about maybe creating an array and pushing only the values that aren't equal to an empty string into it and then sending the array to the API.
import React from "react";
import API from "../../utils/API";
import { Link } from "react-router-dom";
import { storage } from "../../config/fire";
class ProfileEditor extends React.Component {
state = {
image: null,
url: "",
isActive: false,
emailaddress: "",
password: "",
confirm: "",
screenName: "",
securityQuestion: "",
securityAnswer: "",
birthDate: "",
gender: "",
phoneNumber: "",
cityState: "",
userPic: "",
}
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
updateProfile = id => {
if (this.state.password.length > 0 && this.state.password.length < 6) {
alert(
`Choose a more secure password `
);
} else if (this.state.password !== this.state.confirm) {
alert("You Passwords do not match");
} else {
API.updateEditProfile(id, {
password: this.state.password,
screenName: this.state.screenName,
securityQuestion: this.state.securityQuestion,
securityAnswer: this.state.securityAnswer,
birthDate: this.state.birthDate,
gender: this.state.gender,
phoneNumber: this.state.phoneNumber,
cityState: this.state.cityState,
userPic: this.state.url
})
.then(function (response) {
console.log(response);
})
.catch(err => console.log(err));
document.getElementById("profileForm").reset();
}
}
handleImageSelected = event => {
this.uploadClick()
if (event.target.files[0]) {
const image = event.target.files[0];
this.setState(() => ({ image }));
}
}
handleUpload = () => {
const fullName = this.props.userInfo.firstname + "_" + this.props.userInfo.lastname;
const { image } = this.state;
const uploadTask = storage.ref(fullName + "/" + image.name).put(image);
uploadTask.on("state_changed",
(snapshot) => {
const progress = Math.round((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
this.setState({ progress: progress })
},
(error) => {
console.log(error);
},
() => {
storage.ref(fullName).child(image.name).getDownloadURL()
.then(url => {
this.setState({ url: url });
console.log(url)
})
});
}
uploadClick = () => {
this.setState({ isActive: !this.state.isActive })
};
render() {
const fullName = this.props.userInfo.firstname + " " + this.props.userInfo.lastname
const user = this.props.userInfo
console.log(this.props.userInfo.userPic)
return (
<div className="contentArea ">
<div className="profile-container">
<div className="profile-image">
<img src={this.props.userInfo.userPic} />
</div>
<div className="profile-info">
{fullName}
</div>
<section className="editProfile">
<div className="unchangeable">Name: {fullName} </div>
<div className="unchangeable">Email: {this.props.userInfo.emailaddress}</div>
<form id="profileForm">
<div className="profileInputs">
<input value={this.state.password} onChange={this.handleChange} type="password" placeholder="Password" name="password" ref="password" className="editInput" />
</div>
<div className="profileInputs">
<input value={this.state.confirm} onChange={this.handleChange} type="password" placeholder="confirm password" name="confirm" ref="confirmPassword" className="editInput" />
</div>
<div className="profileInputs">
<input value={this.state.securityQuestion} onChange={this.handleChange} type="text" placeholder="security question" name="securityQuestion" ref="securityQuestion" className="editInput" />
</div>
<div className="profileInputs">
<input value={this.state.securityAnswer} onChange={this.handleChange} type="text" placeholder="Answer to security question" name="securityAnswer" ref="securityAnswer" className="editInput" />
</div>
<div className="profileInputs">
<input value={this.state.screenName} onChange={this.handleChange} placeholder="screen name" name="screenName" className="editInput" />
</div>
<div className="profileInputs">
<input value={this.state.birthDate} onChange={this.handleChange} type="text" placeholder="birth date" name="birthDate" className="editInput" />
</div>
<div className="profileInputs">
<input value={this.state.Gender} onChange={this.handleChange} type="text" placeholder="gender" name="gender" className=" editInput" />
</div>
<div className="profileInputs">
<input value={this.state.phoneNumber} onChange={this.handleChange} type="text" placeholder="phone number" name="phoneNumber" className=" editInput" />
</div>
<div className="profileInputs">
<input value={this.state.cityState} onChange={this.handleChange} type="text" placeholder="city/state" name="cityState" className=" editInput" />
</div>
<div className="profileInputs"> Are you in a Relationship?
<input value={this.state.Gender} onChange={this.handleChange} type="text" placeholder="" name="gender" className=" editInput" />
</div>
</form>
</section>
<section className="feed ">
<div className="avatar">
<div className="avatarsect">
Upload Avatar
</div>
<input type="file" style={{ display: "none" }} onChange={this.handleImageSelected} ref={fileInput => this.fileInput = fileInput} />
<img className={this.state.isActive ? "uploadReady active" : "uploadReady"} src={this.state.url} alt="previewupload" height="40" width="50" />
<progress className={this.state.isActive ? "uploadReady active" : "uploadReady"} value={this.state.progress} max="100" />
<button className={this.state.isActive ? "uploadReady active" : "uploadReady"} onClick={this.handleUpload}>Upload</button>
<span className={this.state.isActive ? "uploadReady active" : "uploadReady"}></span>
<button type="button" className="button photo" onClick={() => this.fileInput.click()}><i class="fas fa-camera-retro"></i></button>
</div>
<br></br>
<br></br>
<div className="btnDiv">
<button onClick={() => this.updateProfile(this.props.userInfo.user_ID)} className="updateProfileBtn"> Update Profile</button>
</div>
<br></br>
<br></br>
<br></br>
<br></br>
</section>
</div>
</div>
);
}
}
export default ProfileEditor;
my Api
updateEditProfile:function(id,userData) {
console.log(userData)
console.log(id)
return axios.put("/api/usersData/" +id, userData);
},
my route and controller
router.route("/")
.post(usersDataController.findUserinfo)
.put(usersDataController.update)
router.route("/:id")
.put(usersDataController.updateByID);
updateByID: function(req, res) {
console.log(res)
db.usersData
.findByIdAndUpdate({ _id: req.params.id }, req.body,{new:true})
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},

React Onclick button change forms

I need help to change the pages of my app.
I searched a lot but still don't know how to do that.
Here is my index file:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Here is my App file:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Login from "./Login";
class App extends Component {
render() {
return (
<div className="App">
<Login />
</div>
);
}
}
export default App;
Here is my Login file:
import React from 'react';
import CreateUser from "./CreateUser";
export default class Login extends React.Component {
state = {
email: '',
password: '',
};
change = e => {
this.setState({
[e.target.name]: e.target.value
});
};
onSubmit = (e) => {
e.preventDefault();
console.log(this.state);
};
render() {
return (
<form>
<br />
Login
<br />
<br />
<input
name="email"
placeholder='email'
value={this.state.email}
onChange={e => this.change(e)}
/>
<br />
<br />
<input
name="password"
type='password'
placeholder='password'
value={this.state.password}
onChange={e => this.change(e)}
/>
<br/>
<br/>
<button onClick={e => this.onSubmit(e)}>Login</button>
<br/>
<br/>
<button onClick={e => this.onSubmit(e)}>Sign Up</button>
</form>
);
}
}
Here is my Create user file:
import React from 'react';
export default class CreateUser extends React.Component {
state = {
email: '',
FirstName: '',
LastName: '',
personalphone: '',
password: '',
retypepassword: '',
};
change = e => {
this.setState({
[e.target.name]: e.target.value
});
};
onSubmit = (e) => {
e.preventDefault();
console.log(this.state);
};
render() {
return (
<form>
<br />
Create User
<br />
<br />
<input
name="email"
placeholder='email'
value={this.state.email}
onChange={e => this.change(e)}
/>
<br />
<br />
<input
name="FirstName"
placeholder='FirstName'
value={this.state.FirstName}
onChange={e => this.change(e)}
/>
<br />
<br />
<input
name="LastName"
placeholder='LastName'
value={this.state.LastName}
onChange={e => this.change(e)}
/>
<br />
<br />
<input
name="personalphone"
placeholder='personalphone'
value={this.state.personalphone}
onChange={e => this.change(e)}
/>
<br />
<br />
<input
name="retypepassword"
type='retypepassword'
placeholder='retypepassword'
value={this.state.retypepassword}
onChange={e => this.change(e)}
/>
<br />
<br />
<input
name="password"
type='password'
placeholder='password'
value={this.state.password}
onChange={e => this.change(e)}
/>
<br/ >
<br/ >
<button onClick={e => this.onSubmit(e)}>Submit</button>
</form>
);
}
}
I want to change the page of login to createuser when I click the button Sign Up.
Thx a lot,
Eduardo Gris
You could just keep state of which screen it should show.
Quick example which you can make a lot nicer
constructor() {
super()
this.state = {
screen: 'login'
}
}
handleButtonClick(page) {
this.setState({ screen: page })
}
render() {
return(
<div>
{
this.state.screen === 'login' ?
<Login />
:
<SignUp />
}
<button onClick={(e) => this.handleButtonClick(e.target.value)} value='signup' />
</div>
)
}

Resources