Why won't my form submit user info to the database? - javascript

I'd like to know what's wrong in my code in terms of why it's not sending username, email and password to my database via an Axios POST request. My Laravel endpoint works fine because I verified via PostMan. I'm just struggling with the front end portion of this. What am I doing wrong and how can I fix this?
There error I'm getting on my browser says: Cannot POST /register
import React, {Component} from 'react';
import axios from "axios";
class Register extends Component {
constructor(props) {
super(props);
this.state = {
username: "",
email: "",
password: ""
};
this.userNameHandler = this.userNameHandler.bind(this);
this.emailHandler = this.emailHandler.bind(this);
this.passwordHandler = this.passwordHandler.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
userNameHandler(e) {
this.setState({
username: e.target.value,
});
console.log(this.state.username);
}
emailHandler(e) {
this.setState({
username: e.target.value,
});
console.log(this.state.email);
}
passwordHandler(e) {
this.setState({
username: e.target.value,
});
console.log(this.state.password);
}
handleSubmit(e) {
const user = {
name: this.state.name,
email: this.state.email,
password: this.state.password
}
this.setState({
username: e.target.value
});
axios.post('http://127.0.0.1:8000/api/auth/signup', user)
.then(response => {
console.log(response);
console.log(response.data);
});
}
render() {
return (
<div className="container">
<div id="login-row" className="row justify-content-center align-items-center">
<div id="login-column" className="col-md-6">
<div id="login-box" className="col-md-12">
<form id="login-form" className="form" method="post" onSubmit={this.handleSubmit}>
<div className="form-group">
<label htmlFor="username" className="text-info">Username:</label><br/>
<input type="text" name="username" id="username" className="form-control" onChange={this.userNameHandler}/>
</div>
<div className="form-group">
<label htmlFor="username" className="text-info">Email:</label><br/>
<input type="text" name="username" id="username" className="form-control" onChange={this.emailHandler}/>
</div>
<div className="form-group">
<label htmlFor="password" className="text-info">Password:</label><br/>
<input type="text" name="password" id="password" className="form-control" onChange={this.passwordHandler}/>
</div>
<div className="form-group">
<input type="submit" name="submit" className="btn btn-info btn-md"
value="Submit"/>
</div>
</form>
</div>
</div>
</div>
</div>
);
}
}
export default Register;

You haven't called e.preventDefault(), so you get a regular form submission to the URL specified in the action attribute. You don't have one of those, but the default URL to submit to is the current URL.
The Ajax request gets cancelled as the browser navigates away from the current page to load a new one (which is the server saying it doesn't support POST requests to that URL).

Related

why giving Axios error-404 in react and laravel api

I am trying to submit data from a form on my page to a react.js api using axios but i get the following error.
import axios from 'axios';
import React, { Component } from 'react'
import { Link } from 'react-router-dom';
class AddStudent extends Component {
state = {
name:'',
course:'',
email:'',
phone:'',
}
handleInput = (e) => {
this.setState
({
[e.target.name]:e.target.value
});
}
saveStudent = async (e) =>{
e.preventDefault();
const res = await axios.post('http://127.0.0.1:8000//api/add-student',this.state);
if(res.data.status === 200)
{
console.log(res.data.message);
this.setState({
name:'',
course:'',
email:'',
phone:'',
});
}
}
render()
{
return (
<div className="container">
<div className="row">
<div className="col-md-6">
<div className="card">
<div className="card-holder">
<h4>
Add Student
<Link to={'/'} className="btn btn-primary btn-sm float-end"> Back </Link>
</h4>
</div>
<div className='card-body'>
<form onSubmit={this.saveStudent} >
<div className="form-group mb-3">
<label>Student Name</label>
<input type="text" name="name" onChange={this.handleInput} value={this.state.name} className="form-control" />
</div>
<div className="form-group mb-3">
<label>Student Course</label>
<input type="text" name="course" onChange={this.handleInput} value={this.state.course} className="form-control" />
</div>
<div className="form-group mb-3">
<label>Student Email</label>
<input type="text" name="email" onChange={this.handleInput} value={this.state.email} className="form-control" />
</div>
<div className="form-group mb-3">
<label>Student Phone</label>
<input type="text" name="phone" onChange={this.handleInput} value={this.state.phone} className="form-control" />
</div>
<div className="form-group mb-3">
<button type="submit" className="btn btn-primary">Save Student</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default AddStudent
this is my student controller data which I want to send in my dtabase but it giving error --> "AxiosError {message: 'Request failed with status code 404', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
code: "ERR_BAD_REQUEST" "
<?php
namespace App\Http\Controllers\Api;
use App\Models\Student;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class StudentController extends Controller
{
public function store(Request $request)
{
$student= new Student;
$student->name= $request-> input('name');
$student->course= $request-> input('course');
$student->email= $request-> input('email');
$student->phone= $request-> input('phone');
$student ->save();
return response()->json([
'status'=> 200,
'message'=>'Student added Successfully',
]);
}
}
here it is my .env file
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:08iFPF3lcJqA98M9d9+lUeYi88nVtkHCWk2XIV6dKBU=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelreactjs
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello#example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
I hope the mistake is in the url "http://127.0.0.1:8000//api/add-student". You have provided // after port number "8000". It has to be /. The 404 error is "Page not found" error. In case, If you get this error. You need to check whether the url is properly configured axios react or check whether the url is found in api.php in laravel.
I was using something like this
axios.get(https://jsonplaceholder.typicode.com/posts/${id})
Initially I used ('https://jsonplaceholder.typicode.com/posts/${id}'). See the changes at (' with ). I am not sure at all if this could be valid here but you can give it a try and change ' with in your Api link and try if it works.

how to redirect to home page after login: ReactJS?

How to redirect to homepage after successful login in ReactJS? and also how to show error message whenever user enter wrong credential?
I tried something like below, but it not redirect to homepage after successful login and also not showing login failed prompt whenever user hit wrong credential.
It would be great if anybody could figure out where i did mistake.
./src/Login.js
import React, {Component} from "react";
import {Form} from 'antd';
import { Redirect } from "react-router-dom";
export default class App extends Component{
constructor(props) {
super(props);
this.state ={
username: "",
password: "",
}
this.onFormSubmit = this.onFormSubmit.bind(this)
}
onFormSubmit(values){
console.log(values);
const formData = new FormData();
formData.append("username", values.username);
formData.append("password", values.password);
const options = {
method: 'POST',
body: formData
};
fetch('http://localhost:8000/api/login', options).then(() => {
<Redirect to="/home" />
}).catch((error) => {
console.log(this.props.state)
})
};
render(){
return(
<div>
<Form onFinish={this.onFormSubmit}>
<div class="col-md-12 form-group p_star">
<Form.Item name="username">
<input type="text" class="form-control" placeholder="Username"/>
</Form.Item>
</div>
<div class="col-md-12 form-group p_star">
<Form.Item name="password">
<input type="password" class="form-control"
placeholder="Password"/>
</Form.Item>
</div>
<div class="col-md-12 form-group">
<button type="submit" value="submit" class="btn_3">
log in
</button>
</div>
</Form>
</div>
You can use
window.location = "/home";
OR
this.props.history.push("/home");
go with any of it.
OR
you can go through Programmatically navigate using react router
Well I recommend you to use this.props.history.replace('/home'). Since it prevent the user to navigate back.

Conditionally render empty div or error with React & Bootstrap

I'm setting up a signup form that displays errors below the input fields if the user makes a mistake. The way I have it setup right now, the form will add a div with the error below when the user tries to submit their info. My issue is that when there's an error, it adds the div and messes up the layout of the form because it has to move everything to make space for each error. Is there a way to just have an empty div there if there isn't any errors so that it doesn't mess with the layout when there is one? So like, instead of having margin for spacing between fields, it's an empty div for the errors.
import React, { Component } from "react";
import axios from "axios";
import classnames from "classnames";
import "./Signup.css";
class Signup extends Component {
constructor() {
super();
this.state = {
username: "",
email: "",
password: "",
errors: {}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
onSubmit(e) {
e.preventDefault();
const newUser = {
username: this.state.username,
email: this.state.email,
password: this.state.password
};
axios
.post("api/users/register", newUser)
.then(res => console.log(res.data))
.catch(err => this.setState({ errors: err.response.data }));
}
render() {
const { errors } = this.state;
return (
<div className="signup-form">
<form noValidate onSubmit={this.onSubmit}>
<h2>Sign Up</h2>
<p>It's free and only takes a minute.</p>
<hr />
<div className="form-group">
<label>Username</label>
<input
type="text"
name="username"
className={classnames("form-control form-control-md", {
"is-invalid": errors.username
})}
value={this.state.username}
onChange={this.onChange}
/>
{errors.username && (
<div className="invalid-feedback">{errors.username}</div>
)}
</div>
<div className="form-group">
<label>Email</label>
<input
type="text"
name="email"
className={classnames("form-control form-control-md", {
"is-invalid": errors.email
})}
value={this.state.email}
onChange={this.onChange}
/>
{errors.email && (
<div className="invalid-feedback">{errors.email}</div>
)}
</div>
<div className="form-group">
<label>Password</label>
<input
type="text"
name="password"
className={classnames("form-control form-control-md", {
"is-invalid": errors.password
})}
value={this.state.password}
onChange={this.onChange}
/>
{errors.password && (
<div className="invalid-feedback">{errors.password}</div>
)}
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary btn-block btn-lg">
Sign Up
</button>
</div>
<p className="small text-center">
By clicking the Sign Up button, you agree to our <br />
Terms & Conditions, and{" "}
Privacy Policy
</p>
<div className="text-center">
Already have an account? Login here
</div>
</form>
</div>
);
}
}
export default Signup;
Yes, you can use visibility:hidden property of css.
<div style={{ visibility: error.email? 'visible': 'hidden'}}></div>
since visibility always takes up space, in both cases it is visible as well as hidden. so it won't mess with the layout.

Having issues with my onClick on a registration form

New to react so I apologize if the solution obvious. Working on a registration form that should create a new account on submit using ajax. I know that I'm supposed to use onChange to gather the information is submitted. After seeing a number of examples I am still unable to get my code to work.
I know that the ajax call for POST works because I put in information myself on vscode to test if on submit it will create which it did. I am having issues with the transition from onChange to my submit form. Hope that was clear. Thank you
I've tried creating a onChange function for my registration template. I am unable to get the results that I've been hoping for
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
payload: {
firstName: "",
lastName: "",
email: "",
password: "",
passwordConfirm: ""
}
};
}
handleChange = event => {
let name = event.target.name;
let value = event.target.value;
this.setState({
[name]: value,
[name]: value,
[name]: value,
[name]: value,
[name]: value
});
};
onClickHandler = evt => {
evt.preventDefault();
let payload = this.state;
console.log(payload);
debugger;
registerService
.register(payload)
.then(this.onActionSuccess)
.catch(this.onActionError);
};
onActionSuccess = response => {
console.log(response);
};
onActionError = errResponse => {
console.log(errResponse);
};
<!-- -->
render() {
return (
<main role="main">
<div className="container">
<h1 id="title" align="center">
Register User
</h1>
</div>
<div className="container">
<div className="col-sm-4 col-sm offset-4">
<form className="form">
<div className="form-group">
<label htmlFor="this.state.firstName">First Name</label>
<input
placeholder="First Name"
type="text"
id="this.state.firstName"
className="form-control"
name="firstName"
value={this.state.firstName}
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="this.state.lastName">Last Name</label>
<input
placeholder="last Name"
type="text"
id="this.state. lastName"
className="form-control"
value={this.state.lastName}
onChange={this.handleChange}
/>
<div className="form-group">
<label htmlFor="register-email">Email</label>
<input
placeholder="Enter Email"
type="text"
className="form-control"
id="register-email"
value={this.state.email}
onChange={this.handleChange}
/>
</div>
</div>
<div className="form-group">
<label htmlFor="register-password">Password</label>
<input
placeholder="Password"
type="password"
id="register-password"
`enter code here`className="form-control"
value={this.state.password}
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="register-passwordConfirm">
Confirm Password
</label>
<input
placeholder="Confirm Password"
type="password"
id="register-passwordConfirm"
className="form-control"
value={this.state.passwordConfirm}
onChange={this.handleChange}
/>
</div>
<button onClick={this.onClickHandler} className="btn btn-
primary">
Submit Form
</button>
I am expecting to create a new profile when clicking submit via POST ajax call
Your handleChange function should be
handleChange = event => {
let { name, value } = event.target;
this.setState({
[name]: value,
});
};
You always call your handleChange once at a time. Every time you change something on the input, the function gets different name and different value, which is suffice to add/update the your state.
And I noticed that you also have payload object in state. Modify the state like
this.state = {
firstname: '',
....
}
If you really want to use like
this.state = {
payload: {
firstName: '',
....
}
};
Your onChange function should look like,
handleChange = event => {
let { name, value } = event.target;
this.setState({
payload: {
...this.state.payload, // don't forget to copy all the other values
[name]: value,
}
});
};

Make Invalid Validation Disappear After 5 Seconds --ReactJS--

I'm trying to make the invalid feedback validation disappear after being on the screen for 5 seconds. in my state i have an empty errors object, when the form is submitted, the api call catches any errors from the backend, and they are placed in the errors object, the inputs use conditionals based on the errors object to show the validation. I've tried creating a setTimeout function that sets the state to an empty object after 5 seconds, but this causes breaking glitches if the form is submitted again incorrectly. Any insights how I can do this?
Register.js
import React, { Component } from "react";
import axios from 'axios';
import classnames from 'classnames';
class Register extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
password: "",
password2: "",
errors: {}
};
this.onChange = this.onChange.bind(this);
}
onChange(e) {
// THIS FUNCTION MUST BE BOUND -SEE ABOVE BIND
this.setState({
[e.target.name]: e.target.value
});
}
onSubmit = e => {
// ARROW FUNCTIONS DO NOT NEED TO BE BOUND
e.preventDefault();
const newUser = {
name: this.state.name,
email: this.state.email,
password: this.state.password,
password2: this.state.password2
};
this.setState({
email: "",
name: "",
password: "",
password2: ""
});
axios
.post("/api/users/register", newUser)
.then(res => console.log(res.data))
.catch(err => this.setState({ errors: err.response.data }));
};
render() {
const { errors } = this.state;
return (
<div>
<div className="register">
<div className="container">
<div className="row">
<div className="col-md-8 m-auto">
<h1 className="display-4 text-center text-dark">Sign Up</h1>
<p className="lead text-center">Create your DevMuse account</p>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<input
type="text"
className={classnames("form-control form-control-lg", {
"is-invalid": errors.name
})}
placeholder="Name"
name="name"
value={this.state.name}
onChange={this.onChange}
/>
{errors.name && (
<div className="invalid-feedback">{errors.name}</div>
)}
</div>
<div className="form-group">
<input
type="email"
className={classnames("form-control form-control-lg", {
"is-invalid": errors.email
})}
placeholder="Email Address"
name="email"
value={this.state.email}
onChange={this.onChange}
/>
{errors.email ? (
<div className="invalid-feedback">{errors.email}</div>
) : (
<small className="form-text text-muted text-center">
This site uses Gravatar so if you want a profile image,
use a Gravatar email
</small>
)}
</div>
<div className="form-group">
<input
type="password"
className={classnames("form-control form-control-lg", {
"is-invalid": errors.password
})}
placeholder="Password"
name="password"
value={this.state.password}
onChange={this.onChange}
/>
{errors.password && (
<div className="invalid-feedback">{errors.password}</div>
)}
</div>
<div className="form-group">
<input
type="password"
className={classnames("form-control form-control-lg", {
"is-invalid": errors.password2
})}
placeholder="Confirm Password"
name="password2"
value={this.state.password2}
onChange={this.onChange}
/>
{errors.password2 && (
<div className="invalid-feedback">{errors.password2}</div>
)}
</div>
<input
type="submit"
className="btn btn-info btn-block mt-4"
/>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Register;
Just clear any existing timeout before you initiate a new timeout:
componentWillUnmount() {
clearTimeout(this.clearError);
}
...
.catch((err) => {
this.setState({ errors: err.response.data });
clearTimeout(this.clearError); // clear previous timeout, if exists
this.clearError = setTimeout(() => {
this.setState({ errors: {} });
}, 5000);
});

Categories

Resources