Signup on reactjs using axios - reactjs

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/

Related

TypeError: Cannot read property 'validateFields' of undefined reactjs & django? how can i resolve this issue without antd?

when i try to login then i get this error (TypeError: Cannot read property 'validateFields' of undefined), i also read the documentation about antd but i don't want to use antd in my project how can i resolve this issue without antd... i have simple react-bootstrap Form... anybody know how can i solve this issue?
login.js
import React from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux';
import { Form } from 'react-bootstrap';
import * as actions from './actions/auth';
import FullPageLoader from "../components/FullPageLoader";
class NormalLoginForm extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
this.props.onAuth(values.userName, values.password);
this.props.history.push('/');
}
});
}
render() {
let errorMessage = null;
if (this.props.error) {
errorMessage = (
<p>{this.props.error.message}</p>
);
}
return (
<div className="form-flex">
{errorMessage}
{
this.props.isLoading ?
<FullPageLoader />
:
<Form onSubmit={this.handleSubmit} className="login-form form-group">
<h1 className="h4 text-center font-weight-normal">Sign in</h1>
<div className="form-group">
<input
className="form-control"
name="username"
autoComplete="off"
type="text"
required
placeholder="username" />
</div>
<div className="form-group">
<input
className="form-control"
name="password"
autoComplete="off"
type="password"
required
placeholder="password" />
</div>
<div className="form-group">
<button type="submit" className="btn btn-block btn-secondary">Login</button>
</div>
<small>
<Link to="/passwordforget">Forgot password?</Link>
</small>
</Form>
}
</div >
);
}
}
const mapStateToProps = (state) => {
return {
loading: state.loading,
error: state.error
}
}
const mapDispatchToProps = dispatch => {
return {
onAuth: (username, password) => dispatch(actions.authLogin(username, password))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(NormalLoginForm);
The error Cannot read property 'validateFields' of undefined is being caused by the code this.props.form.validateFields. You are not passing a form prop into the component so it is undefined, and throwing that error.
Either define a validator somewhere and use it, or remove that line.

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?

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');
})
//...

How do I set the value of an input after doing an Axios get request?

I have a component that represents a form for entering book data, e.g. title/author/etc.
If an ID is present, the component will make an API call to the API server, and get the book data.
What I'm trying to accomplish basically, is getting the record from the API server, and then setting the form fields to those values, so that the form is populated with data for the user to edit.
I have a method called loadBook which makes an API call to get the book data. The method works, it gets the record, it sets the state, but the form inputs do not seem to pick up that the state has changed.
What do I need to do to get the form populated with the record that was just fetched?
import React from "react";
import Axios from "axios";
import {
Redirect
} from "react-router-dom";
import FormBase from "../FormBase";
export default class BookForm extends FormBase {
constructor(props) {
super(props);
this.state = {
formFields: {
title: '',
author_id: null,
cover_image: null
},
authors: [],
};
}
componentDidMount() {
this.loadAuthors();
if (this.props.id) {
this.loadBook()
}
}
loadBook = () => {
Axios.get(`${process.env.REACT_APP_API_URL}/books/${this.props.id}`).then(response => {
this.setState(prevState => {
let formFields = Object.assign({}, prevState.formFields)
formFields['title'] = response.data['title']
formFields['author_id'] = response.data['author_id']
return {formFields}
})
})
}
loadAuthors = () => {
Axios.get(`${process.env.REACT_APP_API_URL}/authors`).then(response => {
this.setState({authors: response.data})
})
}
render() {
let authors = this.state.authors.map(author => {
return <option key={author.id} value={author.id}>{author.last_name}, {author.first_name}</option>
})
return (
<form onSubmit={(e) => {e.preventDefault(); this.props.handleSubmit(e, this.state.formFields, true)}}>
{this.state.redirect ? <Redirect to="/admin/books" /> : null}
<div className="form-group">
<label htmlFor="title">Title</label>
<input name="title" value={this.state.title} onChange={this.handleFieldChange} type="text" className="form-control" />
</div>
<div className="form-group">
<label htmlFor="author">Author</label>
<select name="author_id" onChange={this.handleFieldChange} className="custom-select" size="5">
{authors}
</select>
</div>
<div className="custom-file form-group">
<input name="cover_image" type="file" onChange={this.handleFieldChange} className="custom-file-input" id="customFile" />
<label className="custom-file-label" htmlFor="customFile">Cover Image</label>
</div>
<button style={{marginTop: '1rem'}} type="submit" className="btn btn-primary">Submit</button>
</form>
)
}
}
Try setting your state simply like so:
this.setState({formFields:
{
...this.state.formFields,
title: response.data['title'],
author_id: response.data['author_id']
}
})
I essentially followed this guide on uncontrolled components.
I added attributes for each form field using React.createRef(), and then on the form inputs you link the ref object like ref={this.author_id}. Then, you can do this.author_id.current.value = response.data.author_id and the input's value will then be set. This won't trigger onChange though, so you'll need to update the state too.
import React from "react";
import Axios from "axios";
import {
Redirect
} from "react-router-dom";
import FormBase from "../FormBase";
export default class BookForm extends FormBase {
constructor(props) {
super(props);
this.state = {
formFields: {
title: '',
author_id: null,
cover_image: null
},
authors: [],
};
this.title = React.createRef();
this.author_id = React.createRef();
}
componentDidMount() {
this.loadAuthors();
if (this.props.id) {
this.loadBook()
}
}
loadBook = () => {
Axios.get(`${process.env.REACT_APP_API_URL}/books/${this.props.id}`).then(response => {
console.log(this.author_id)
this.author_id.current.value = response.data.author_id
this.title.current.value = response.data.title
this.setState(prevState => {
let formFields = Object.assign({}, prevState.formFields)
formFields['title'] = response.data['title']
formFields['author_id'] = response.data['author_id']
return {formFields}
})
})
}
loadAuthors = () => {
Axios.get(`${process.env.REACT_APP_API_URL}/authors`).then(response => {
this.setState({authors: response.data})
})
}
render() {
let authors = this.state.authors.map(author => {
return <option key={author.id} value={author.id}>{author.last_name}, {author.first_name}</option>
})
return (
<form onSubmit={(e) => {e.preventDefault(); this.props.handleSubmit(e, this.state.formFields, true)}}>
{this.state.redirect ? <Redirect to="/admin/books" /> : null}
<div className="form-group">
<label htmlFor="title">Title</label>
<input name="title" ref={this.title} value={this.state.title} onChange={this.handleFieldChange} type="text" className="form-control" />
</div>
<div className="form-group">
<label htmlFor="author">Author</label>
<select name="author_id" ref={this.author_id} onChange={this.handleFieldChange} className="custom-select" size="5">
{authors}
</select>
</div>
<div className="custom-file form-group">
<input name="cover_image" type="file" onChange={this.handleFieldChange} className="custom-file-input" id="customFile" />

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