How to set my value in input value react js - javascript

I was trying to set my value in input value but all the time I was getting undefined in the console and I wanted to set values from API in value but I could not so how to set values in input value and i also tried to remove ref and see but still value input shows undefined when I set value={2} in input.
And here it is:
this.state = {
// movie: [],
user: this.props.value,
text: "",
errors: []
};
async componentDidMount() {
try {
const res = await fetch(
`https://softbike.dev.myddp.eu/api/1/deliveries/user1/`
);
const movie = await res.json();
console.log(movie);
this.setState({
movie: movie.pk
});
} catch (e) {
console.log(e);
}
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
console.log(this.state);
}
Here is input code:
<div className="row">
<div className="col-sm-12">
<label id="p"> UZYTKOWNIK</label>
<input
type="text"
ref="user"
className="form-control"
name="user"
value={movie.id}
onChange={this.handleChange}
/>
<p>g {this.state.value}</p>
</div>
Please help me how to resolve this.

<div className="col-sm-12">
<label id="p"> UZYTKOWNIK</label>
<input
type="text"
ref="user"
className="form-control"
name="user"
value={this.state.movie && this.state.movie.id}
onChange={this.handleChange}
/>
</div>

Try this:
this.state = {
movie: {},
user: this.props.value,
text: "",
errors: []
};
componentDidMount() {
const fetchMovie = async () => {
try {
const res = await fetch(`https://softbike.dev.myddp.eu/api/1/deliveries/user1/`);
const movie = res.json();
console.log(movie);
this.setState({
...this.state,
movie: movie.pk
});
} catch (e) {
console.log(e);
}
}
fetchMovie(); // Call async fundtion
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
}, () => {
console.log(this.state);
// Because setState is async function, so you have to console.log in callback of
// setState to see the new data of this.state
});
}
Input:
<div className="row">
<div className="col-sm-12">
<label id="p"> UZYTKOWNIK</label>
<input
type="text"
ref="user"
className="form-control"
name="user"
defaultValue={this.state.movie.id}
onChange={this.handleChange}
/>
<p>g {this.state.value}</p>
</div>

Related

how to save old value to a PUT when I PUT a single value ReactJS/NodeJs

I would like to explain my problem of the day.
I map a database, then I display the result in a card
I get several results
So problem and the next one, when I modify a result, it empties all my other values, while I would like to keep the other values ​​of the other fields.
How can I fix this issue?thx all
make room for the code :)
class Chat extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
onChangegame(e) {
this.setState({ game: e.target.value })
}
onChangename(e) {
this.setState({ name: e.target.value })
}
putname = (e, chat) => {
e.preventDefault();
const config = {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ id: chat.id, name: this.state.name, game: this.state.game, }),
};
const url = "http://localhost:4242/api/putname";
fetch(url, config)
.then(res => res.json())
.then(res => {
if (res.error) {
alert(res.error);
} else {
alert(`ajouté avec l'ID ${res}!`);
}
}).catch(e => {
console.error(e);
}).finally(() => this.setState({ redirect: true }));
}
render() {
let datas = this.state.data.map(chat => {
return (
<div key={chat.id}>
<form onSubmit={(e) => this.putname(e, chat)}>
<p> {chat.name} </p>
<input type="text"
id="name"
onChange={this.handleChange}
value={this.state.name}
name="name"
/>
<input type="submit" value="modifier" />
</form>
<form onSubmit={(e) => this.putname(e, chat)}>
<p> {chat.game} </p>
<input type="text"
id="game"
onChange={this.handleChange}
value={this.state.game}
name="game"
/>
<input type="submit" value="modifier" />
</form>
</div>
return (
<div>
{datas}
</div>
)
}
}
export default Chat
My Back
putname = (e, chat) => {
e.preventDefault();
const config = {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ id: chat.id, name: this.state.name, game: this.state.game }),
};
const url = "http://localhost:4242/api/putname";
fetch(url, config)
.then(res => res.json())
.then(res => {
if (res.error) {
alert(res.error);
} else {
alert(`ajouté avec l'ID ${res}!`);
}
}).catch(e => {
console.error(e);
}).finally(() => this.setState({ redirect: true }));
}
The problem that I see is when you update the state you aren't preserving the previous values. For example:
instead of:
onChangegame(e) {
this.setState({ game: e.target.value })
}
onChangename(e) {
this.setState({ name: e.target.value })
}
, use:
onChangegame(e) {
this.setState({ ...this.state, game: e.target.value })
}
onChangename(e) {
this.setState({ ...this.state, name: e.target.value })
}
or even a better way it's using the same handler by destructing e.target object:
onChange(e) {
const { value, name } = e.target
this.setState({ ...this.state, [name]: [value] })
}
// ... and the in your inputs
render() {
let datas = this.state.data.map(chat => {
return (
<div key={chat.id}>
<form onSubmit={(e) => this.putname(e, chat)}>
<p> {chat.name} </p>
<input type="text"
id="name"
onChange={this.onChange}
value={this.state.name}
name="name"
/>
<input type="submit" value="modifier" />
</form>
<form onSubmit={(e) => this.putname(e, chat)}>
<p> {chat.game} </p>
<input type="text"
id="game"
onChange={this.onChange}
value={this.state.game}
name="game"
/>
<input type="submit" value="modifier" />
</form>
</div>
return (
<div>
{datas}
</div>
)

Cannot read property 'map' of undefined Error when using axios.get inside useEffect hook

This is my edit-exercises component given below. So in my exercises component when I am clicking
edit to update my exercises with respect to its id, it has to render to edit-exercise component
but on rendering it gives above mentioned error. This is my component for the reference. In this, in
useEffect I am fetching my exercise with given id from the URL.
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import axios from "axios";
const EditExercise = (props) => {
const [userDetails, setUserDetails] = useState({
username: "",
description: "",
duration: 0,
date: new Date(),
users: [],
});
useEffect(() => { //This is the getting from backend
axios
.get("http://localhost:5000/exercises/"+props.match.params.id)
.then(res => {
setUserDetails({
username: res.data.username,
description: res.data.description,
duration: res.data.duration,
date: new Date(res.data.date),
})
})
.catch((err) => {
console.log(err);
});
axios
.get("http://localhost:5000/users/")
.then((res) => {
if (res.data.length > 0) {
setUserDetails({
users: res.data.map((user) => user.username),
});
}
})
.catch((err) => {
console.log(err);
});
},[props.match.params.id]);
const changeUsernameHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
username: e.target.value,
};
});
};
const changeDescriptionHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
description: e.target.value,
};
});
};
const changeDurationHandler = (e) => {
setUserDetails((prevState) => {
return {
...prevState,
duration: e.target.value,
};
});
};
const changeDateHandler = (date) => {
setUserDetails((prevState) => {
return {
...prevState,
date: date,
};
});
};
const onSubmitHandler = (e) => { //On submit this code will run
e.preventDefault();
const exercise = {
username: userDetails.username,
description: userDetails.description,
duration: userDetails.duration,
date: userDetails.date,
};
console.log(exercise);
axios
.post("http://localhost:5000/exercises/update/"+props.match.params.id, exercise)
.then((res) => console.log(res.data));
window.location = "/";
};
return (
<div>
<h3>Edit Exercise log</h3>
<form onSubmit={onSubmitHandler}>
<div className="form-group">
<label>Username: </label>
<select
required
className="form-control"
onChange={changeUsernameHandler}
value={userDetails.username}
>
{userDetails.users.map((user) => {
return (
<option key={user} value={user}>
{user}
</option>
);
})}
</select>
</div>
<div className="form-group">
<label>Description: </label>
<input
type="text"
required
className="form-control"
onChange={changeDescriptionHandler}
value={userDetails.description}
/>
</div>
<div className="form-group">
<label>Duration (in minutes): </label>
<input
type="number"
className="form-control"
onChange={changeDurationHandler}
value={userDetails.duration}
/>
</div>
<div className="form-group">
<label>Date: </label>
<div>
<DatePicker
onChange={changeDateHandler}
selected={userDetails.date}
/>
</div>
</div>
<div>
<input
type="submit"
value="Edit Exercise Log"
className="btn btn-primary"
/>
</div>
</form>
</div>
);
};
export default EditExercise;```
>Please suggest what can be done to render the edit-exercise component
Cannot read property 'map' of undefined
This error is thrown because the array you are trying to map doesn't exist. Please check if the array exists before you map the array.
users: res.data ? res.data.map((user) => user.username) : [],
And
{userDetails.users && userDetails.users.map((user) => {
return (
<option key={user} value={user}>
{user}
</option>
);
})}
Since axios.get returns a promise, and setUserDetails is set after the promise is returned, you need to be careful on when useEffect is triggered. Currently useEffect is triggered when props.match.params.id is changed.
There are 2 possible solutions for it:
Either, you can remove props.match.params.id from the useEffect second parameter.
Or you can this section outside the useEffect hook:
axios
.get("http://localhost:5000/users/")
.then((res) => {
if (res.data.length > 0) {
setUserDetails({
users: res.data.map((user) => user.username),
});
}
})
.catch((err) => {
console.log(err);
});

Data from database displaying in the State but not on screen in React.js

I am new to react and designing an eCommerce website. In the admin side of the website, I have created a database to store customers information. I am able to write to the database and read from it (data is appearing in the state) but I am not able to display the data on screen. I have a function called 'displayCustomerList' to get the data from the state and format it but in the Render part, nothing is being displayed. Any help or advice is much appreciated.
import React, { Component } from "react";
import Title from "./Title";
import { Link, Redirect } from "react-router-dom";
import { ButtonContainer } from "./Button";
import axios from "axios";
export default class Admin extends Component {
constructor(props) {
super(props);
const token = localStorage.getItem("token");
let loggedIn = true;
if (token == null) {
loggedIn = false;
}
this.state = {
loggedIn,
name: "",
address: "",
postcode: "",
phone: "",
posts: [],
};
}
componentDidMount = () => {
this.getCustomerList();
};
getCustomerList = () => {
axios
.get("/api")
.then((response) => {
const data = response.data;
this.setState({ posts: data });
console.log("Data has been received");
})
.catch(() => {
alert("Error retrieving data");
});
};
handleChange = ({ target }) => {
const { name, value } = target;
this.setState({ [name]: value });
};
submit = (event) => {
event.preventDefault();
const payload = {
name: this.state.name,
address: this.state.address,
postcode: this.state.postcode,
phone: this.state.phone,
};
axios({
url: "/api/save",
method: "POST",
data: payload,
})
.then(() => {
console.log("Data has been sent to the server");
this.resetUserInputs();
this.getCustomerList();
})
.catch(() => {
console.log("Internal server error");
});
};
resetUserInputs = () => {
this.setState({
name: "",
address: "",
postcode: "",
phone: "",
});
};
//THIS IS CAUSING THE ISSUE
displayCustomerList = (posts) => {
if (!posts.length) return null;
console.log(posts) // I can see the array in the console
posts.map((post, index) => (
<div key={index} className="customer.list_display">
<h3>TEST</h3> //NOT DISPLAYING
<h3>{post.name}</h3>
<p>{post._id}</p>
<p>{post.address}</p>
<p>{post.postcode}</p>
<p>{post.phoneNumber}</p>
</div>
));
};
render() {
console.log("State: ", this.state);
if (this.state.loggedIn === false) {
return <Redirect to="/login" />;
}
return (
<React.Fragment>
<div className="py-5">
<div className="container">
<Title name="Admin" />
<Link to="/">Logout</Link>
</div>
</div>
<div className="card-footer d-flex justify-content-between">
<form onSubmit={this.submit} className="py-5">
<div className="form-input">
<input
type="text"
name="name"
placeholder="Name"
value={this.state.name}
onChange={this.handleChange}
className="nameInput"
/>
</div>
<div className="form-input">
<input
type="address"
name="address"
placeholder="Address"
value={this.state.address}
onChange={this.handleChange}
className="addressInput"
/>
</div>
<div className="form-input">
<input
type="text"
name="postcode"
placeholder="Postcode"
value={this.state.postcode}
onChange={this.handleChange}
className="postcodeInput"
/>
</div>
<div className="form-input">
<input
type="text"
name="phone"
placeholder="Phone number"
value={this.state.phone}
onChange={this.handleChange}
className="phoneInput"
/>
</div>
<ButtonContainer>submit</ButtonContainer>
</form>
</div>
<div>
{/* <CustomerList /> */}
<Title name="Customer List" />
</div>
//NOTHING IS BEING DISPLAYED
<div className="blog-">
{this.displayCustomerList(this.state.posts)}
</div>
</React.Fragment>
);
}
}
you should return JSX object from displayCustomerList like this:
displayCustomerList = (posts) => {
if (!posts.length) return null;
console.log(posts) // I can see the array in the console
return posts.map((post, index) => (
<div key={index} className="customer.list_display">
<h3>TEST</h3> //NOT DISPLAYING
<h3>{post.name}</h3>
<p>{post._id}</p>
<p>{post.address}</p>
<p>{post.postcode}</p>
<p>{post.phoneNumber}</p>
</div>
));
};

How to write a generic method to handle multiple state changes in React

I'm building an exercise tracker app in React.
Right now, I'm building the CreateExercise component to submit a form, so I need to update the states of each value. In order to do so, I created methods to handle those changes (onChangeUsername, onChangeDescription, onChangeDuration etc...) but I don't really like to repeat methods like this.
How to write a more generic method to handle this task ?
class CreateExercise extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
description: '',
duration: 0,
date: new Date(),
users: []
}
}
onChangeUsername = (e) => {
this.setState({
username: e.target.value
});
}
onChangeDescription = (e) => {
this.setState({
description: e.target.value
});
}
onChangeDuration = (e) => {
this.setState({
duration: e.target.value
});
}
onChangeDate = (date) => {
this.setState({
date: date
});
}
onSubmit = (e) => {
e.preventDefault();
const exercise = {
username: this.state.username,
description: this.state.description,
duration: this.state.duration,
date: this.state.date
}
console.log(exercise);
window.location = '/';
}
render() {
return(
<div>
<h3>Create New Exercise Log</h3>
<form onSubmit={ this.onSubmit }>
<div className='form-group'>
<label>Username:</label>
<select
ref='userInput'
required
className='form-control'
value={ this.state.username }
onChange={ this.onChangeUsername }
>
{ this.state.users.map((user) => (
<option key={user} value={user}>{user}</option>
))
}
</select>
</div>
<div className='form-group'>
<label>Description:</label>
<input
type='text'
required
className='form-control'
value={ this.state.description }
onChange={ this.onChangeDescription}
/>
</div>
<div className='form-group'>
<label>Duration:</label>
<input
type='text'
className='form-control'
value={ this.state.duration }
onChange={ this.onChangeDuration }
/>
</div>
<div className='form-group'>
<label>Date:</label>
<div>
<DatePicker
selected={ this.state.date }
onChange={ this.onChangeDate }
/>
</div>
</div>
<div className='form-groupe'>
<input
type='submit'
value='Create Exercise Log'
className='btn btn-primary'
/>
</div>
</form>
</div>
);
}
}
export default CreateExercise;
Using partial application, create a function in your component that takes a field name, and returns a function that sets the state:
onChangeValue = field => e => {
this.setState({
[field]: e.target.value
});
};
Usage:
onChangeUsername = onChangeValue('username');
onChangeDescription = onChangeValue('description');
onChangeDuration = onChangeValue('duration');
You extend the idea further to support the onChangeDate as well:
onChangeValue = (field, valueTransformer = e => e.target.value) => e => {
this.setState({
[field]: valueTransformer(e.target.value)
});
};
This doesn't change the other on functions, since the default is to get e.target.value. To use onChangeDate we can now change the valueTransformer:
onChangeDate = onChangeValue('date', v => v);
You can define name for the HTML element, and use that to set value:
onChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
corresponding JSX element:
<input
type="text"
name="description"
required
className="form-control"
value={this.state.description}
onChange={this.onChange}
/>

How to filter the data from state depending on the value of the input

I'm testing at the same page at the moment, later I will move it into other components. I have an input field that sends its value to the state, also I'm fetching data from a json to the state, and I'm displaying all the information from the state but I want to only display the information that has the same email as the input field. I'm sending it with a button.
I'm just needing like a function of a way to filter the display but i can't understand how to do it.
class Testing extends Component {
state = { data: [], value: "", filteredData: "" };
handleSubmit = this.handleSubmit.bind(this);
handleChange = this.handleChange.bind(this);
async componentDidMount() {
await fetch("http://tenjoucesar.github.io/data.json")
.then(response => response.json())
.then(data => {
this.setState({ data });
});
}
handleSubmit(e) {
e.preventDefault();
let email = this.state.value;
fetch("https://tenjoucesar.github.io/data.json")
.then(response => response.json())
.then(data => {
let result = data.filter(person => person.email === email);
this.setState({ filteredData: result });
});
}
handleChange(e) {
this.setState({ value: e.target.value });
}
Everything here works, Form "is on the same jsx
<form onSubmit={this.handleSubmit}>
<input
type="email"
value={this.state.value}
onChange={this.handleChange}
/>
<input
type="submit"
value="Submit"
/>
</div>
</form>
How do i display the data?
<ul>
{data.map(person => {
return (
<div className="result" key={person.email}>
<h3 className="heading-tertiary">
{person.name}, {person.age}
</h3>
<p className="paragraph--result">{person.notes}</p>
);
})}
I am displaying everything, also sending the value to the state, how can i only display the data with the same email? Thank you!
I hope this help you. you were calling two times api for data. I have change it for better performance.
'use strict';
class Testing extends React.Component {
state = { data: [], value: "", filteredData: [] };
handleSubmit = this.handleSubmit.bind(this);
handleChange = this.handleChange.bind(this);
async componentDidMount() {
await fetch("http://tenjoucesar.github.io/data.json",{mode: 'cors'})
.then(response => response.json())
.then(data => {
this.setState({ data });
});
}
handleSubmit(e) {
e.preventDefault();
let email = this.state.value;
const filtered = this.state.data.filter((e) => e.email == email);
this.setState({
filteredData:filtered
})
}
handleChange(e) {
this.setState({ value: e.target.value });
}
InfomData = (person) => {
return (
<div className="result" key={person.email}>
<h3 className="heading-tertiary">
{person.name}, {person.age}
</h3>
<p className="paragraph--result">{person.notes}</p>
</div>
)
}
render () {
const dataToRender = this.state.filteredData.map(
(e) => this.InfomData(e)
)
return (
<div>
<form onSubmit={this.handleSubmit}>
<input
type="email"
value={this.state.value}
onChange={this.handleChange}
/>
<input
type="submit"
value="Submit"
/>
</form>
{dataToRender}
</div>
)
}
}
ReactDOM.render(
<Testing />,
document.getElementById('root')
)
let result = []
data.forEach(person => {
if(person.email === 'targetemail#whatever.com')
{ result.push(
<div className="result" key={person.email}>
<h3 className="heading-tertiary">
{person.name}, {person.age}
</h3>
<p className="paragraph--result">{person.notes}</p>
</div>)
}
}

Categories