React form submit triggers two times - reactjs

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?

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/

authentication log in form with jwt and react

I have made and fetched a Login form with JWT and react. I managed to fetched the data for the username and password and everything works perfectly but then I want to redirect the user to a new page when he clicks on submit and I have no idea how to do that. I'm also using react router. Any help will be welcome
import React, { Component } from "react";
import axios from "axios";
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: "test",
password: "test",
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
})
}
login = () => {
const {username, password} = this.state;
axios(`/users/login`, {
method: "POST",
data: {
username,
password,
}
})
.then(response => {
localStorage.setItem('token', response.data.token);
console.log(response);
})
.catch(error => {
console.log(error)
})
}
render() {
return (
<div className="log">
<h3>Sign In</h3>
<div className="form-group">
<label>Username</label>
<input type="username" className="form-control" placeholder="Enter username" name="username" value={this.state.username} onChange={this.handleChange} />
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" placeholder="Enter password" name="password" value={this.state.password} onChange={this.handleChange} />
</div>
<div className="form-group">
<div className="custom-control custom-checkbox">
<input type="checkbox" className="custom-control-input" id="customCheck1" />
<label className="custom-control-label" htmlFor="customCheck1">Remember me</label>
</div>
</div>
<button type="submit" className="btn btn-primary btn-block" onClick={this.login}>Submit</button>
<p className="forgot-password text-right">
Forgot password?
</p>
</div>
);
}
}
import withRouter import {withRouter} from 'react-router-dom';
remove export before class Login class Login extends Component {...
export class at the end of the file: export default withRouter(Login);
and use react-router-dom:
axios(`/users/login`, {
//...
})
.then(response => {
localStorage.setItem('token', response.data.token);
console.log(response);
this.props.history.push('/url');
})
//...

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.

How do I redirect to another page on form submit?

I'm trying to redirect to a certain page once I post my form but it doesn't redirect, it only posts the form data and does not redirect to the stated page
I've tried appending the && operator in order for onSubmit to do both functions but to no avail. I also tried having both "onSubmit" and "onClick" but it's only "onSubmit" that works
//./userspost.js
import React, { Component } from "react";
import { Redirect, Link } from "react-router-dom";
import Form1 from "./form1";
import { createUsers } from "./actions/appactions";
class userspost extends Component {
state = {
redirect: false
};
setRedirect = () => {
this.setState({
redirect: true
});
};
renderRedirect = () => {
if (this.state.redirect) {
return <Redirect to="/users" />;
}
};
handleSubmit(data) {
console.log("form submission data", data);
createUsers(data);
}
render() {
return (
<div>
{this.renderRedirect()}
<Form1 onSubmit={this.handleSubmit && this.setRedirect} />
</div>
);
}
}
export default userspost;
for the posting the form data
//./form1.js
import React from "react";
import { Link } from "react-router-dom";
var createReactClass = require("create-react-class");
const Form1 = createReactClass({
//setting initial state
getInitialState() {
return {
firstName: this.props.firstName,
lastName: this.props.lastName,
userName: this.props.userName,
role: this.props.role
};
},
handleFirstChange(e) {
this.setState({
firstName: e.target.value
});
},
handleLastChange(e) {
this.setState({
lastName: e.target.value
});
},
handleUserChange(e) {
this.setState({
userName: e.target.value
});
},
handleRoleChange(e) {
this.setState({
role: e.target.value
});
},
handleSubmit(e) {
e.preventDefault();
this.props.onSubmit(this.state);
},
render() {
return (
<form
name="categories_post"
className="form-horizontal"
onSubmit={this.handleSubmit}
>
<div id="categories_post">
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="firstName"
>
First Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.firstName}
onChange={this.handleFirstChange}
id="firstName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="lastName"
>
Last Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.lastName}
onChange={this.handleLastChange}
id="lastName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="userName"
>
UserName
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.userName}
onChange={this.handleUserChange}
id="userName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="role">
Role
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.role}
onChange={this.handleRoleChange}
id="role"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button
type="submit"
id="categoriesSubmit"
className="btn-default btn"
>
submit
</button>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button className="btn btn-danger">
<Link to="/users">Home</Link>
</button>
</div>
</div>
</div>
</form>
);
}
});
export default Form1;
for posting using the fetch API
//./actions/appactions.js
import fetch from "isomorphic-fetch";
export function createCategories(data) {
return fetch("https://localhost:44341/api/categories", {
method: "POST",
mode: "cors",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
return res;
})
.catch(err => err);
}
export function createUsers(data) {
return fetch("https://localhost:44341/api/users/create", {
method: "POST",
mode: "cors",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
return res;
})
.catch(err => err);
}
export function createBusiness(data) {
return fetch("https://localhost:44341/api/businesslistings/create", {
method: "POST",
mode: "cors",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
return res;
})
.catch(err => console.log(err));
}
The issue is that you are rendering the Redirect component along with the rest of your JSX everytime. Rendering only <Redirect to="" /> should solve your problem.
class userspost extends Component {
state = {
redirect: false
};
setRedirect = () => {
this.setState({
redirect: true
});
};
handleSubmit(data) {
console.log("form submission data", data);
createUsers(data);
}
render() {
if( this.state.redirect ){
return <Redirect to="users/" />
}
return (
<div>
{this.renderRedirect()}
<Form1 onSubmit={this.handleSubmit} />
</div>
);
}
}
Also, use only the handleSubmit function in your form onSubmit event. Since adding two functions with && could cause unexpected results. And when everything is ready to redirect, just call your function setRedirect.
There is someone that already answered something similar, so I took a bit of help from there. Check it out:
https://stackoverflow.com/a/43230829/5568741

React Requests with Router in function

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

Resources