React Requests with Router in function - reactjs

Hi I am working on using react router after a request post and am having some problems.
handleSubmit = event => {
event.preventDefault();
request.post(
{
url: 'http://localhost:8080/usernamepassword',
json: true,
body: {
email: this.state.email,
password: this.state.password
}
},
function(err, httpResponse, body) {
console.log(err);
console.log(httpResponse);
console.log(body);
if (err) {
this.props.history.push('/nosuccess');
} else {
this.props.history.push('/success');
}
}
);
The problem is with
if (err) {
this.props.history.push('/nosuccess');
} else {
this.props.history.push('/success');
}
I know (atleast i think) that the problem is with the this.props is not being passed through.
The full code is below. I am working on putting the request into an arrow function (from #webdevdani). Learning that right now.
import React, {Component} from 'react';
import request from 'request';
import {Link, withRouter} from 'react-router-dom';
import '../Form.css';
class SignIn extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: ''
};
}
handleChange = event => {
this.setState({
[event.target.id]: event.target.value
});
};
handleSubmit = event => {
event.preventDefault();
request.post(
{
url: 'http://localhost:8080/signin',
json: true,
body: {
username: this.state.username,
password: this.state.password
}
},
function (err, httpResponse, body) {
console.log(err);
console.log(httpResponse);
console.log(body);
if (err) {
this.props.history.push('/nosuccess');
} else {
this.props.history.push('/success');
}
}
);
};
render() {
return (
<div>
<form id="login" className="form-content" onSubmit={this.handleSubmit}>
<h1 className="form-content-text-h1"> Sign In</h1>
<div className="padding10">
<div className="form-content-text-textbox"> EDIPI (DoD ID):</div>
<input type="text" className="input1" id="username" onChange={this.handleChange} required/>
<br/>
<br/>
<div className="form-content-text-textbox"> Password:</div>
<input type="password" className="input1" id="password" onChange={this.handleChange} required/>
</div>
<button type="submit" className="button1">
Sign In
</button>
<br/>
<Link to="/resetpassword" style={{textDecorationColor: '#26c6da'}}>
<h1 className="form-content-link-text">Sign In Assistance</h1>
</Link>
<br/>
<br/>
<h1 className="form-content-text-h1"> New Users </h1>
<Link to="/register">
<button className="button1" type="submit">
Register
</button>
</Link>
</form>
</div>
);
}
}
export default withRouter(SignIn);
Here is the full code.

It looks like the value of 'this' is not what you're expecting. If you change your function declaration in the request.post arguments to be an arrow function, it should have the 'this' value of your component. Then you'll have access to this.props

Related

Signup on reactjs using axios

so i was trying to make a signup & login features on my web. My problem here is i cant post signup data to my api.
Here is the code that i make :
import React, { Component } from 'react'
import { Container } from 'react-bootstrap'
import { API_URL } from '../utils/constant';
import axios from 'axios';
import swal from 'sweetalert';
export default class Signup extends Component {
constructor(props) {
super(props);
this.state = {
};
}
handleSubmit = e => {
e.preventDefault();
const data = {
username: this.username,
password: this.password,
};
axios
.post(API_URL + "signup", data)
.then(res => {
swal({
tittle: "sukses",
text: "sukses",
icon: "success",
button: false,
})
}
).catch(error => {
console.log(error);
}
)
};
render() {
return (
<div className="signup">
<Container>
<div className="signup-page">
<form onSubmit={this.handleSubmit}>
<div class="mb-3">
<label>Username</label>
<input type="text" name="username" placeholder="username anda" class="form-control" onChange={e=> this.username = e.target.value} />
<div class="form-text"></div>
</div>
<div class="mb-3">
<label>Password</label>
<input type="password" class="form-control" onChange={e=> this.password = e.target.value}/>
</div>
<button class="btn btn-primary">Sign Up</button>
</form>
</div>
</Container>
</div>
);
}
}
My code here is not giving me any error, but the data is not post/added to my API.
i hope there is any suggestion from anyone of you because im just new into this reactjs,
this is my github link so maybe you might check it :
https://github.com/dannyambarita/Tubes_PWL/

React form submit triggers two times

I have React login form. The problem is form submit is called two times. I dont understand it. Can somebody tell me please why? Thanks a lot.
import React from "react"
import LoginErrors from "./LoginErrors"
import LoginSuccess from "./LoginSuccess"
import axios from 'axios'
import { withRouter } from "react-router-dom";
class Login extends React.Component
{
constructor(props)
{
super(props)
this.state = {
name: '',
password: '',
errors: [],
success: []
}
}
changeName = e =>
{
this.setState({name: e.target.value});
}
changePassword = e =>
{
this.setState({password: e.target.value});
}
sendData(e)
{
e.preventDefault();
this.setState({'errors': [], 'success': []});
let formData = new FormData();
formData.set('name', this.state.name);
formData.set('password', this.state.password);
axios({
method: 'POST',
url: 'http://localhost:8000/login',
data: formData,
headers: {
'Content-Type': 'text/html',
'X-Requested-With': 'XMLHttpRequest',
}
})
.then(response => {
// ? returns undefined if variable is undefined
if( response.data?.errors?.length )
{
this.setState({errors: response.data.errors})
}
if( response.data?.success?.length )
{
let data = response.data
this.props.setAccessToken(data.token)
this.props.setUserName(data.user.name)
this.props.history.push('/')
}
})
.catch(response => {
this.setState({errors: ['Login fails. Try it again later please.']})
});
}
render() {
return (
<div className="row justify-content-md-center">
<div className="col-sm-12 col-md-6">
<div id="loginForm">
<h2 className="">Login</h2>
<LoginSuccess success={this.state.success} />
<LoginErrors errors={this.state.errors} sendParentMessage={this.handleErrorsChildMessage} />
<form onSubmit={e => {this.sendData(e)}}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input ref={this.email} name="name" className="form-control" type="text" onChange={this.changeName} />
</div>
<div className="form-group">
<label htmlFor="password">Heslo</label>
<input ref={this.password} name="password" className="form-control" type="password" onChange={this.changePassword} />
</div>
<div className="form-group">
<button name="sbmt" className="btn btn-primary" type="submit">OdoslaƄ</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
So the problem is in axios preflyght request which is related to the CORS policy. But How to stop it?

I need to pass a URL from a class component to another

here is my QR component :
import React, { Component } from "react";
class QR extends React.Component {
constructor(props) {
super(props);
}
render() {
const { catImageUrl } = this.props;
const qrUrl = `https://qrtag.net/api/qr_12.svg?url=${catImageUrl}`;
if (!catImageUrl) return <p>Oops, something went wrong!</p>;
return <img className="QR" src={qrUrl} alt="qrtag" />;
}
}
export default QR;
I need to pass the const qrURL to the next component Form.js to use it in ajax call to get its data and pass it to the next api request to send it to an email
class Form extends React.Component{
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: '',
}
}
const{qrUrl}=this.props;
FetchQRURL = () => {
fetch(`${qrUrl}`)
.then((response) => response.json())
.then((data) => {
this.setState({
message: data,
});
})
.catch((error) => console.log(error));
};
handleSubmit(e){
e.preventDefault();
axios({
method: "POST",
url:"http://localhost:3002/send",
data: this.state
}).then((response)=>{
if (response.data.status === 'success'){
alert("Message Sent.");
this.resetForm()
}else if(response.data.status === 'fail'){
alert("Message failed to send.")
}
})
}
resetForm(){
this.setState({name: '', email: '', message: ''})
}
render() {
return(
<div className="App">
<form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
<div className="form-group">
<label htmlFor="name">Name</label>
<input type="text" className="form-control" id="name" value={this.state.name} onChange={this.onNameChange.bind(this)} />
</div>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input type="email" className="form-control" id="email" aria-describedby="emailHelp" value={this.state.email} onChange={this.onEmailChange.bind(this)} />
</div>
<div className="form-group">
<label htmlFor="message">Message</label>
<textarea className="form-control" rows="5" id="message" value={this.state.message} onChange={this.onMessageChange.bind(this)} />
</div>
<button type="submit" className="btn btn-primary" onClick="">Submit</button>
</form>
</div>
);
}
onNameChange(event) {
this.setState({name: event.target.value})
}
onEmailChange(event) {
this.setState({email: event.target.value})
}
onMessageChange(event) {
this.setState({message: event.target.value})
}
}
export default Form;
you can see I tried to pass it as props but it doesn't work
here I tried to pass it as props(in my app.js)
import React, { Component } from "react";
import RandomCat from "./RandomCat.js";
import QR from "./QR.js";
import Form from "./form.js";
class BooksApp extends Component {
state = {
showCatImage: false,
showQrCode: false,
catImageUrl: "",
};
handleFetchRandomImage = () => {
fetch("https://aws.random.cat/meow")
.then((response) => response.json())
.then((data) => {
this.setState({
catImageUrl: data.file,
showCatImage: true,
});
})
.catch((error) => console.log(error));
};
handleShowQrCode = () => {
this.setState({ showQrCode: true });
};
render() {
const { showCatImage, showQrCode, catImageUrl,qrUrl } = this.state;
return (
<div className="app">
<div className="first">
{/* The time below shows cat image if showCatImage === true and returns nothing if false */}
{showCatImage && <RandomCat catImageUrl={catImageUrl} />}
<button className="catButton" onClick={this.handleFetchRandomImage}>
Generate Cat
</button>
</div>
<div className="second">
{showQrCode && <QR catImageUrl={catImageUrl} qrUrl={qrUrl}/>}
<button className="QRButton" onClick={this.handleShowQrCode}>
Geanerate QR
</button>
</div>
<div>
<Form qrUrl={qrUrl}/>
</div>
</div>
);
}
}
export default BooksApp;
any idea how can I pass it to the Form.js?
You have to pull the constant qrUrl to the parent component which is BooksApp in your case.
Set it to the state and pass it down as props.
state = {
showCatImage: false,
showQrCode: false,
catImageUrl: "",
qrUrl: ""
};
handleFetchRandomImage = () => {
fetch("https://aws.random.cat/meow")
.then((response) => response.json())
.then((data) => {
this.setState({
catImageUrl: data.file,
showCatImage: true,
qrUrl: `https://qrtag.net/api/qr_12.svg?url=${data.file}` // Set it here
});
})
.catch((error) => console.log(error));
};
handleShowQrCode = () => {
this.setState({ showQrCode: true });
};
render() {
const { showCatImage, showQrCode, catImageUrl, qrUrl } = this.state;
return (
<div className="app">
<div className="first">
{/* The time below shows cat image if showCatImage === true and returns nothing if false */}
{showCatImage && <RandomCat catImageUrl={catImageUrl} />}
<button className="catButton" onClick={this.handleFetchRandomImage}>
Generate Cat
</button>
</div>
<div className="second">
{showQrCode && <QR catImageUrl={catImageUrl} qrUrl={qrUrl}/>}
<button className="QRButton" onClick={this.handleShowQrCode}>
Geanerate QR
</button>
</div>
<div>
<Form qrUrl={qrUrl}/>
</div>
</div>
);
}
}
export default BooksApp;
The just use it with this.props.qrUrl in your other components.

Redirection to dashboard after login in react

I have a login page, and I want to redirect users to dashboard after the details are filled.
I have tried using history.push and redirect components but I couldn't redirect.
Login Page
class Login extends React.Component {
state = {
email: '',
password: '',
errors: {},
redirect: false
}
validateForm = () => {
let errors = {};
let formIsValid = true;
if(!this.state.email) {
formIsValid = false;
errors['email'] = 'Please enter email to continue';
}
if(!this.state.password) {
formIsValid = false;
errors['password'] = 'Please enter password to continue';
}
this.setState({
errors: errors
})
return formIsValid;
}
handleChange = (event) => {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit = (event) => {
event.preventDefault();
// console.log(this.state);
if(this.validateForm()) {
const loginData = {
email: this.state.email,
password: this.state.password
}
axios
.post('/users.json', loginData)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
})
}
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Login</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange} />
<p>{this.state.errors.email}</p>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange} />
<p>{this.state.errors.password}</p>
</div>
<div className="input-field">
<button onClick={this.redirectHandler} className="btn btn-primary">Login</button>
</div>
</form>
</div>
)
}
}
export default Login;
I want to redirect to other page once the form is submitted with the email and password.
I've been trying this for days but I couldn't find a solution.
import { withRouter } from 'react-router';
class Login extends React.Component {
state = {
email: '',
password: '',
errors: {},
redirect: false
}
validateForm = () => {
let errors = {};
let formIsValid = true;
if(!this.state.email) {
formIsValid = false;
errors['email'] = 'Please enter email to continue';
}
if(!this.state.password) {
formIsValid = false;
errors['password'] = 'Please enter password to continue';
}
this.setState({
errors: errors
})
return formIsValid;
}
handleChange = (event) => {
this.setState({
[event.target.id]: event.target.value
});
}
handleSubmit = (event) => {
event.preventDefault();
// console.log(this.state);
if(this.validateForm()) {
const loginData = {
email: this.state.email,
password: this.state.password
}
axios
.post('/users.json', loginData)
.then(response => {
this.props.history.push("/dashboard");
console.log(response.data);
})
.catch(error => {
console.log(error);
})
}
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Login</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange} />
<p>{this.state.errors.email}</p>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange} />
<p>{this.state.errors.password}</p>
</div>
<div className="input-field">
<button onClick={this.redirectHandler} className="btn btn-primary">Login</button>
</div>
</form>
</div>
)
}
}
export default withRouter(Login);
have some complain about your code.
first: for form validation and handling you dont need to use state,
there is a library called Formik which will help you a lot with
this.
second: if you are using redux to check user is logged in or
not you need to create a private route for routes which cannot be
accessible for public like here dashboard component.
third: to use history you need to wrap your
component inside withRouter HOC which will pass route props to your
component so you can use history or if your are using functional component you can use useHistory() hook.

how do i use <redirect/> for redirecting to a different page after login authentication?

I am doing a project on Reactjs and I'm new to it. Its just been few days since i have been working on Reactjs. I want to redirect to a new page after successfull login authentication. I am using but its not working, and being new to reactjs i cant figure out where i am going wrong. My redirect condition being if both "valid" and "proceed" = false then it will redirect it to another page. The boolean values for "valid" and "proceed" comes from a http response and its working fine but redirect it not working. The page remains as it is.
My sigin component : SignInForm.js->
import React, { Component } from "react";
import { Link, Redirect } from "react-router-dom";
import axios from "axios";
class SignInForm extends Component {
state = {
email: "",
pass: "",
proceed: false,
valid: false
};
passwordChange = event => {
this.setState({ pass: event.target.value });
};
emailChange = event => {
this.setState({ email: event.target.value });
};
handleOperation = event => {
event.preventDefault();
const user = this.state.email;
const pwd = this.state.pass;
console.log(user + "|" + pwd);
this.setState({
loading: true
});
const data = {
user,
pwd
};
axios
.post("https://some end-point where i make my request", data)
.then(res => {
console.log(res);
this.setState({
proceed: res.data.proceed,
valid: res.data.valid
});
console.log(
"res pro= " + res.data.proceed + "| res val=" + res.data.valid
);
console.log(
"state pro=" +
this.state.proceed +
"|" +
"state val = " +
this.state.valid
);
if (!this.state.proceed && !this.state.valid) {
console.log(" In condition");
return <Redirect to="/Demo" />;
}
})
.catch(err => {
console.log(err);
});
};
render() {
return (
<div className="FormCenter">
<form className="FormFields">
<div className="FormField">
<label className="FormField__Label" htmlFor="email">
E-Mail Address
</label>
<input
type="email"
id="email"
className="FormField__Input"
placeholder="Enter your e-mail address"
name="email"
onChange={this.emailChange}
/>
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="password">
Password
</label>
<input
type="password"
id="password"
className="FormField__Input"
placeholder="Enter your password"
name="password"
onChange={this.passwordChange}
/>
</div>
<div className="FormField">
<button
className="FormField__Button mr-20"
onClick={this.handleOperation}
>
Sign In
</button>
<Link to="/" className="FormField__Link">
Create a new account
</Link>
</div>
</form>
</div>
);
}
}
export default SignInForm;`
Demo Component :Demo.js ->
import React, { Component } from "react";
class Demo extends Component {
render() {
return <h1>THIS IS A DEMO</h1>;
}
}
export default Demo;
Use Redirect in render as it is a component. Also make initial state for valid & proceed as strings instead of boolean (otherwise it'll always be redirecting, as initial state will be always be false for both) and update the redirection condition also to incorporate that.
import React, { Component } from "react";
import { Link, Redirect } from "react-router-dom";
import axios from "axios";
class SignInForm extends Component {
state = {
email: "",
pass: "",
proceed: "false",
valid: "false"
};
passwordChange = event => {
this.setState({ pass: event.target.value });
};
emailChange = event => {
this.setState({ email: event.target.value });
};
handleOperation = event => {
event.preventDefault();
const user = this.state.email;
const pwd = this.state.pass;
console.log(user + "|" + pwd);
this.setState({
loading: true
});
const data = {
user,
pwd
};
axios
.post("https://some end-point where i make my request", data)
.then(res => {
this.setState({
proceed: res.data.proceed,
valid: res.data.valid
});
})
.catch(err => {
console.log(err);
});
};
render() {
if ( this.state.proceed===false && this.state.valid===false) {
return <Redirect to="/Demo" />;
}
return (
<div className="FormCenter">
<form className="FormFields">
<div className="FormField">
<label className="FormField__Label" htmlFor="email">
E-Mail Address
</label>
<input
type="email"
id="email"
className="FormField__Input"
placeholder="Enter your e-mail address"
name="email"
onChange={this.emailChange}
/>
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="password">
Password
</label>
<input
type="password"
id="password"
className="FormField__Input"
placeholder="Enter your password"
name="password"
onChange={this.passwordChange}
/>
</div>
<div className="FormField">
<button
className="FormField__Button mr-20"
onClick={this.handleOperation}
>
Sign In
</button>
<Link to="/" className="FormField__Link">
Create a new account
</Link>
</div>
</form>
</div>
);
}
}
export default SignInForm;`
Hope this helps ! Happy coding.
Redirect is a component that needs to be rendered. Also setState is async and so its value may not update immediately.
import React, { Component } from "react";
import { Link, Redirect } from "react-router-dom";
import axios from "axios";
class SignInForm extends Component {
state = {
email: "",
pass: "",
proceed: false,
valid: false
};
passwordChange = event => {
this.setState({ pass: event.target.value });
};
emailChange = event => {
this.setState({ email: event.target.value });
};
handleOperation = event => {
event.preventDefault();
const user = this.state.email;
const pwd = this.state.pass;
console.log(user + "|" + pwd);
this.setState({
loading: true
});
const data = {
user,
pwd
};
axios
.post("https://some end-point where i make my request", data)
.then(res => {
console.log(res);
this.setState({
proceed: res.data.proceed,
valid: res.data.valid
});
console.log(
"res pro= " + res.data.proceed + "| res val=" + res.data.valid
);
console.log(
"state pro=" +
this.state.proceed +
"|" +
"state val = " +
this.state.valid
);
})
.catch(err => {
console.log(err);
});
};
render() {
if (!this.state.proceed && !this.state.valid) {
console.log(" In condition");
return <Redirect to="/Demo" />;
}
return (
<div className="FormCenter">
<form className="FormFields">
<div className="FormField">
<label className="FormField__Label" htmlFor="email">
E-Mail Address
</label>
<input
type="email"
id="email"
className="FormField__Input"
placeholder="Enter your e-mail address"
name="email"
onChange={this.emailChange}
/>
</div>
<div className="FormField">
<label className="FormField__Label" htmlFor="password">
Password
</label>
<input
type="password"
id="password"
className="FormField__Input"
placeholder="Enter your password"
name="password"
onChange={this.passwordChange}
/>
</div>
<div className="FormField">
<button
className="FormField__Button mr-20"
onClick={this.handleOperation}
>
Sign In
</button>
<Link to="/" className="FormField__Link">
Create a new account
</Link>
</div>
</form>
</div>
);
}
}
export default SignInForm;

Resources