400 bad request during axios call - reactjs

Not sure why but the POST request is coming back 400. Postman says my django backend is doing fine. It all happens at the post_flashcards method any help would be great and I am willing to show any other code as requested. although there shouldnt be the need to since this component acts mostly on its own.
class CreateFlashCard extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
collection_id: '',
term: '',
definition: '',
}
this.handleSubmit = this.handleSubmit.bind(this)
}
onChange = (e) => {
this.setState({[e.target.name]: e.target.value});
}
handleSubmit(e) {
e.preventDefault();
this.post_flashcard()
}
async post_flashcard() {
const card = this.state;
const col_id = parseInt(this.state.collection_id)
try{
await axios.post(`http://127.0.0.1:8000/flashcardsapp/${col_id}`, card)
.then(response => console.log(response.status))
}catch(er){
console.log('ERROR in post_flashcard', er)
}
}
render() {
const {title, collection_id, term, definition} = this.state
return (
<form onSubmit={this.handleSubmit}>
<h2>Create a Card</h2>
<label for="title">Enter Collection Title</label>
<input type="text" name="title" value={title} onChange={this.onChange} ></input>
<label for="collection_id">Enter Collection ID</label>
<input type="number" name="collection_id" value={collection_id} onChange={this.onChange} ></input>
<label for="term">Enter Term</label>
<input type="text" name="term" value={term} onChange={this.onChange} ></input>
<label for="definition">Enter Definition</label>
<input type="text" name="definition" value={definition} onChange={this.onChange} ></input>
<input type="submit"></input>
</form>
);
}
}
export default CreateFlashCard;

If you are doing post processing, you can convert the Data to Json format and send it.
var post_data = {
your_post_name: this.state
};
axios
.post(url, JSON.stringify(post_data))
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
or
axios
.post(url,JSON.stringify({your_post_name:this.state}))
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});

I solved the issue state had typo in title needed to be collection_title.

Related

i want to show details on same page

i am developing an application i.e supply chain management application on reactJS, NodeJS and blockchain.
Frontend code:
import React, { Component } from 'react'
import { useState, useEffect } from "react";
import axios from "axios";
import { useNavigate } from 'react-router-dom';
const SignUp = () => {
const navigate = useNavigate();
const flag=0;
const [data, setData] = useState({
uname: "",
email: "",
location: "",
budget: "",
password: ""
});
const handleChange = (e) => {
const value = e.target.value;
setData({
...data,
[e.target.name]: value
});
};
const handleSubmit = (e) => {
e.preventDefault();
const userData = {
uname: data.uname,
email: data.email,
location: data.location,
budget: data.budget,
password: data.password
};
axios
.post("http://localhost:8080/api/signup/", userData)
.then((response) => {
console.log(response);
})
.catch((error) => {
if (error.response) {
console.log(error.response);
console.log("server responded");
} else if (error.request) {
console.log("network error");
} else {
console.log(error);
}
});
navigate(`/home`)
};
return (
<form>
<h3>Sign Up</h3>
<div className="mb-3">
<label>User Name</label>
<input
type="text"
name="uname"
value={data.uname}
className="form-control"
placeholder="User name"
onChange={handleChange}
/>
</div>
<div className="mb-3">
<label>Email address</label>
<input
type="email"
name="email"
value={data.email}
className="form-control"
placeholder="Enter email"
onChange={handleChange}
/>
</div>
<div className="mb-3">
<label>Location</label>
<input
type="text"
name="location"
value={data.location}
className="form-control"
placeholder="Location"
onChange={handleChange}
/>
</div>
<div className="mb-3">
<label>Budget</label>
<input
type="Number"
name="budget"
value={data.budget}
className="form-control"
placeholder="Budget"
onChange={handleChange}
/>
</div>
<div className="mb-3">
<label>Password</label>
<input
type="password"
name="password"
value={data.password}
className="form-control"
placeholder="Enter password"
onChange={handleChange}
/>
</div>
<div className="d-grid">
<button type="submit" onClick={handleSubmit}className="btn btn-primary">
Sign Up
</button>
</div>
<p className="forgot-password text-right">
Already registered sign in?
</p>
</form>
);
};
export default SignUp;
here if user successfully registered then i want to show deatils of the user on the same page. how should i do that?
i have attached the code and the screenshot of the page.
currently i am on my account page.
Inside of your handle submit
You can just navigate after the axios.then callback
Or if you want the behavior to be that user submits -> register success -> show success -> then redirect, you can setTimeout for say 1000ms and then navigate.
axios
.post("http://localhost:8080/api/signup/", userData)
.then((response) => {
console.log(response);
})
.then(() => {
setTimeout(() => navigate(`/home`), 1000);
}
.catch((error) => {
if (error.response) {
console.log(error.response);
console.log("server responded");
} else if (error.request) {
console.log("network error");
} else {
console.log(error);
}
});
If you mean, show the user data after a successful registration and assuming you're calling an api to register the user and you're getting the user details back on success, you can handle that in your handleSubmit method.
Here's an example
const showUserDetails = (userDetails) => {
// Code that shows user details
// Probably using state
};
const handleSubmit = (e) => {
e.preventDefault();
const userData = {
...
axios
.post("http://localhost:8080/api/signup/", userData)
.then((response) => {
// handle here
showUserDetails(response);
})
.catch((error) => {
if (error.response) {
...
} else {
console.log(error);
}
});
};

Extra undefined value in this.state

i am trying to post a form in reactjs, and i suspect it doesnt write to DB because i get strange undefined in my state, which looks like:
form looks like this
but in console i get:
this
my code on front is :
constructor(props) {
super(props);
this.state = { name: '', gender: '', email: '' };
}
handleChange= (event) => {
this.setState({
[event.target.name]: event.target.value,
[event.target.gender]: event.target.value,
[event.target.email]: event.target.value,
// [event.target.phone]: event.target.value,
});
}
handleSubmit = (event) => {
console.log(JSON.stringify(this.state));
alert('A form was submitted: ' + this.state);
fetch('http://localhost:3000/api/game/contacts', {
method: 'POST',
body: JSON.stringify(this.state)
}).then(function(response) {
return response.json();
});
event.preventDefault();
}
render() {
const { user } = this.props.auth;
console.log(this.state);
return(
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:</label>
<input type="text" value={this.state.value} name="name" onChange={this.handleChange} />
<label>
Gender:</label>
<input type="text" value={this.state.value} name="gender" onChange={this.handleChange} />
<label>
Email:</label>
<input type="text" value={this.state.value} name="email" onChange={this.handleChange} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
Dashboard.propTypes = {
auth: PropTypes.object.isRequired
};
const mapStateToProps = ( state ) => ({
auth: state.auth
});
export default connect( mapStateToProps )( Dashboard );
must be super simple, but i googled for 2 hours, and could not see issue. Thanks for you time

Add data to the page without refreshing it in React

I've posted this question earlier, but probably not quite clearly formulated it. I have a chat. When I add message it goes to database but not updated on page. So I need it to be updated on page after adding a msg.
Parent component Forms
export default class Forms extends Component {
constructor() {
super()
this.state = {
messages: [],
}
this.sendMessage = this.sendMessage.bind(this);
}
componentDidMount(){
client1.getEntries({limit:300, order: 'sys.createdAt',
content_type:'nameTest'}).then(response => {
this.setState({messages: response.items});
}).catch(e => {
console.log(e);
});
}
sendMessage(data) {
client2.getSpace(client2.space)
.then((space) => space.getEnvironment('master'))
.then((environment) => environment.createEntry('nameTest', {
fields: {
chatName: {
'en-US': data.get('chatName')
... some data
}
}))
.then((entry) => entry.publish())
.catch(console.error)
}
render() {
return (
<div className="chat">
<div className="container-xl">
<MessageList messages={this.state.messages}/>
<SendMsg onSendMessage={this.sendMessage}/>
</div>
</div>
);
}
}
the child component SengMsg
export default class SendMsg extends Component {
constructor() {
super()
this.state = {
message:'',
userEmail:'ddd#gmail.com',
chatName:'ggg'
}
this.sendMessage = this.sendMessage.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
this.setState({
message: e.target.value,
})
}
sendMessage(e) {
e.preventDefault();
const { onSendMessage } = this.props;
const form = e.target;
const data = new FormData(form);
// if send message handler was passed, invoke with form data
onSendMessage && onSendMessage(data);
this.setState({
message: ''
})
}
render() {
return (
<div className="send-message">
<Form className="send-msg" onSubmit={this.sendMessage}>
<FormGroup>
<Input type="hidden" name="userEmail" value={this.state.userEmail}/>
</FormGroup>
<FormGroup>
<Input type="hidden" name="chatName" value={this.state.chatName}/>
</FormGroup>
<FormGroup>
<Input
type="text"
name="text"
onChange={this.handleChange}
value={this.state.message}
placeholder="Write your message here"
required />
</FormGroup>
<FormGroup>
<Input type="hidden" name="dateCreated" value={moment().format()} onChange={this.handleChange}/>
</FormGroup>
</Form>
</div>
);
}
}

I can't type in input text using reactjs

i can't change text when typing in input text !
This is my fontend code :
constructor(props) {
super(props);
this.state = {
items: [],
acc_email: '',
acc_nom: '',
acc_prenom: '',
acc_tel: '',
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
the value of input comes from DB using fetch :
componentDidMount(){
const token = localStorage.getItem('toktok');
fetch(`${API}/api/account`,{
method: 'GET',
headers :{
'authorization': `Bearer ${token}`,
}
})
.then(results => {
return results.json();
})
.then(data => {
this.setState({ items: data.result });
console.log("account: ",data.result);
// localStorage.setItem('mymy', "fiss");
// console.log(items);
// console.log(items.length);
})
.catch(err => {
console.log("erroooor : ",err);
});
}
i don't know what's wrong in this function :
handleInputChange = e => {
const name = e.target.name;
const value = e.target.value;
this.setState({[name]: value});
this.setState({ [e.target.name]: e.target.value });
}
and finally, this's the render() that conains all inputs:
<div key={items._id}>
<input type="text" value={items.email} name="acc_email" onChange={this.handleInputChange} />
<input type="text" value={items.nom} name="acc_nom" onChange={this.handleInputChange} />
<input type="text" value={items.prenom} name="acc_prenom" onChange={this.handleInputChange} />
<input type="text" value={items.tel} name="acc_tel" onChange={this.handleInputChange} />
<a className="admin-btn-update" href={`/updateaccount/${items._id}`}>Modifier</a>
</div>
change value to defaultValue as follows.
<input type="text" defaultValue={items.email} name="acc_email" onChange={this.handleInputChange} />
You are explicitly setting the values of the inputs to be items.email, items.nom.. which makes them controlled inputs, which basically means that it's the component responsibility to control what happens to those inputs.
Since you already implemented the part that updates the component state, all you need to do is to make the inputs values reflect this state:
<input type="text" value={this.state.acc_email} name="acc_email" onChange={this.handleInputChange} />
<input type="text" value={this.state.acc_nom} name="acc_nom" onChange={this.handleInputChange} />
<input type="text" value={this.state.acc_prenom} name="acc_prenom" onChange={this.handleInputChange} />
<input type="text" value={this.state.acc_tel} name="acc_tel" onChange={this.handleInputChange} />

axios put request in react is returning empty

I'm pretty new with React and Call requests. I'm building a full stack app using React, express, MySql, and Sequelize.
Everything works fine except for the Put request to edit the client information. I'm using Axios to make those calls and I can add, see, and delete data from the app but the edit part is not working.
When hitting the submit button on the form, the Put request is returning an empty array instead of the actual modified data. My routes are Ok (I believe), as testing it with Postman work just fine. I'm almost sure that my problem is on the method being used in the axios call, but I can't just find the right way to make it work. Any help would be highly appreciated.
import React, { Component } from 'react';
import axios from 'axios';
import API from '../../utils/API';
class index extends Component {
constructor(props) {
super(props);
this.onChangeLastName = this.onChangeLastName.bind(this);
this.onChangeFirstName = this.onChangeFirstName.bind(this);
this.onChangePhone = this.onChangePhone.bind(this);
this.onChangePetName = this.onChangePetName.bind(this);
this.onChangeBreed = this.onChangeBreed.bind(this);
this.onChangeNotes = this.onChangeNotes.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
client: null
}
}
componentDidMount() {
let id = this.props.match.params.id
API.getClient(id)
.then(res => {
this.setState({
client: res.data
})
console.log(this.state.client.id)
})
.catch(error => console.log(error))
}
onChangeLastName(e) {
this.setState({
lastName: e.target.value
});
}
onChangeFirstName(e) {
this.setState({
firstName: e.target.value
});
}
onChangePhone(e) {
this.setState({
phone: e.target.value
});
}
onChangePetName(e) {
this.setState({
petName: e.target.value
});
}
onChangeBreed(e) {
this.setState({
breed: e.target.value
});
}
onChangeNotes(e) {
this.setState({
notes: e.target.value
});
}
onSubmit(e) {
e.preventDefault();
let obj = {
lastName: this.state.client.lastName.value,
firstName: this.state.client.firstName.value,
phone: this.state.client.phone.value,
petName: this.state.client.petName.value,
breed: this.state.client.breed.value,
notes: this.state.client.notes.value
};
let id = this.state.client.id
axios.put("http://localhost:3000/api/clients/" + id, obj)
// .then(alert("client Updated"))
.then(res => console.log(res))
.catch(error => console.log(error))
this.props.history.push('/admin');
}
render() {
const client = this.state.client ? (
<div className="client">
<h3 style={{ marginLeft: "60px" }}>Update Client</h3>
<form onSubmit={this.onSubmit} style={{ padding: "60px" }}>
<div className="form-group">
<label>Last Name: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.lastName}
onChange={this.onChangeLastName}
/>
</div>
<div className="form-group">
<label>First Name: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.firstName}
onChange={this.onChangeFirstName}
/>
</div>
<div className="form-group">
<label>Phone: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.phone}
onChange={this.onChangePhone}
/>
</div>
<div className="form-group">
<label>Pet Name: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.petName}
onChange={this.onChangePetName}
/>
</div>
<div className="form-group">
<label>Breed: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.breed}
onChange={this.onChangeBreed}
/>
</div>
<div className="form-group">
<label>Notes: </label>
<input type="text"
className="form-control"
defaultValue={this.state.client.notes}
onChange={this.onChangeNotes}
/>
</div>
<br />
<div className="form-group">
<input type="submit" value="Update Client"
className="btn btn-primary" />
</div>
</form>
</div>
) : (
<div className="center">Loading Client</div>
)
return (
<div className="container">
{client}
</div>
)
}
}
export default index;
I am assuming it is because of the way you are handling the onchange of your inputs. You want to set the onchange to the client value in your state. But instead you are setting it to the state itself. So then when you are building your object to send to the backend you are sending null data because you haven't set any data to the actual client value in your state and it is still null. Try console logging the state and you will see what I'm talking about. Also you are adding a .value to the end each of the state values you are trying to build your object with and this is not necessary. Finally you don't need to specify an onchange for each input just give the input a name attribute and you can set your onchange handler like so:
onChange = e => {
this.setState({
[e.target.name]: e.target.value
})
}
so your component would look something like the following:
import React, { Component } from 'react';
import axios from 'axios';
import API from '../../utils/API';
class index extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
client: null
}
}
componentDidMount() {
let id = this.props.match.params.id
API.getClient(id)
.then(res => {
this.setState({
client: res.data
})
console.log(this.state.client.id)
})
.catch(error => console.log(error))
}
onChange(e) {
this.setState({
client: {
...this.state.client,
[e.target.name]: e.target.value
}
});
}
onSubmit(e) {
e.preventDefault();
let obj = {
lastName: this.state.client.lastName,
firstName: this.state.client.firstName,
phone: this.state.client.phone,
petName: this.state.client.petName,
breed: this.state.client.breed,
notes: this.state.client.notes
};
let id = this.state.client.id
axios.put("http://localhost:3000/api/clients/" + id, obj)
// .then(alert("client Updated"))
.then(res => console.log(res))
.catch(error => console.log(error))
this.props.history.push('/admin');
}
render() {
const client = this.state.client ? (
<div className="client">
<h3 style={{ marginLeft: "60px" }}>Update Client</h3>
<form onSubmit={this.onSubmit} style={{ padding: "60px" }}>
<div className="form-group">
<label>Last Name: </label>
<input type="text"
name="lastName"
className="form-control"
defaultValue={this.state.client.lastName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>First Name: </label>
<input type="text"
name="firstName"
className="form-control"
defaultValue={this.state.client.firstName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Phone: </label>
<input type="text"
name="phone"
className="form-control"
defaultValue={this.state.client.phone}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Pet Name: </label>
<input type="text"
name="petName"
className="form-control"
defaultValue={this.state.client.petName}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Breed: </label>
<input type="text"
name="breed"
className="form-control"
defaultValue={this.state.client.breed}
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label>Notes: </label>
<input type="text"
name="notes"
className="form-control"
defaultValue={this.state.client.notes}
onChange={this.onChange}
/>
</div>
<br />
<div className="form-group">
<input type="submit" value="Update Client"
className="btn btn-primary" />
</div>
</form>
</div>
) : (
<div className="center">Loading Client</div>
)
return (
<div className="container">
{client}
</div>
)
}
}
export default index;
It could be because you're calling this.props.history.push immediately after calling axios.post, essentially redirecting before the POST request has a chance to return a response.
Try putting this.props.history.push('/admin') inside the .then().
You are doing multiple thing wrong here,
For every input you should have only 1 onChange handler, every input have name attribute to work with state. For example,
<input type="text"
className="form-control"
defaultValue={this.state.client.lastName}
name="lastName" //Like this should add name for every input like below
onChange={this.onChangeHandler} //This is a common onChangeHandler for every input should add in every input like below
/>
<input type="text"
className="form-control"
defaultValue={this.state.client.firstName}
name="firstName"
onChange={this.onChangeHandler}
/>
And onChangeHandler function should be,
onChangeHandler(e){
this.setState({
...this.state.client,
[e.target.name]:e.target.value
})
}
And finally your onSubmit function should be,
onSubmit(e) {
e.preventDefault();
let obj = {
lastName: this.state.client.lastName, //Remove `.value` as we are getting values from state and not directly from input
firstName: this.state.client.firstName,
phone: this.state.client.phone,
petName: this.state.client.petName,
breed: this.state.client.breed,
notes: this.state.client.notes
};
let id = this.state.client.id
axios.put("http://localhost:3000/api/clients/" + id, obj)
// .then(alert("client Updated"))
.then(res => console.log(res))
.catch(error => console.log(error))
this.props.history.push('/admin');
}
Note: You won't get value here in console.log,
API.getClient(id)
.then(res => {
this.setState({
client: res.data
})
console.log(this.state.client.id)
})
beacuse seState is async, you should use callback in setState to make console.log,
API.getClient(id)
.then(res => {
this.setState({
client: res.data
}, () => console.log(this.state.client.id)) //This is callback
})

Resources