Reputation: 566
I have a simple list that I get from an API using axios. Every element is a modifiable input, with it own update button.
After changing the data of an input, and while performing PUT request, console.log(test);
returns empty values.
I checked console.log(newList);
which is the array of the list, and the changing data are indeed happening in the list, but it seems they can't be sent to the server.
Note : The API is just for testing, the PUT method may not work, but atleast the values in the console should be sent.
Note2 : I don't know how to place the id
of an item of the list in the url so you may encounter an error. / You can try with 1,2 or 3 instead for testing.
https://codesandbox.io/s/quizzical-snowflake-dw1xr?file=/src/App.js:1809-1834
import React, { useState, useEffect } from "react";
import axios from "axios";
export default () => {
const [list, setList] = React.useState([]);
const [name, setName] = React.useState("");
const [description, setDescription] = React.useState("");
const [city, setCity] = React.useState("");
// Getting initial list from API
useEffect(() => {
axios
.get("https://6092374385ff5100172122c8.mockapi.io/api/test/users")
.then((response) => {
setList(response.data);
console.log(response);
})
.catch((err) => console.log(err));
}, []);
// onUpdate to update the data in the API
const onUpdate = (e) => {
e.preventDefault();
const test = {
name: name,
description: description,
city: city
};
console.log(test);
// axios request PUT data on API
axios
.put(
"https://6092374385ff5100172122c8.mockapi.io/api/test/users" + id,
test
)
.then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
// axios request GET to get the new modified list from the database, after the update
axios
.get("https://6092374385ff5100172122c8.mockapi.io/api/test/users")
.then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
};
// Handler for changing values of each input
function handleChangeUpdate(id, event) {
const { name, value } = event.target;
const newList = list.map((item) => {
if (item.id === id) {
const updatedItem = {
...item,
[name]: value
};
return updatedItem;
}
return item;
});
setList(newList);
console.log(newList);
}
return (
<div>
<ul>
<div>
{list.map((item) => (
<li key={item.id}>
<input
className="form-control"
name="name"
onChange={(event) => handleChangeUpdate(item.id, event)}
defaultValue={item.name}
></input>
<input
className="form-control"
name="description"
onChange={(event) => handleChangeUpdate(item.id, event)}
defaultValue={item.description}
></input>
<input
className="form-control"
name="city"
onChange={(event) => handleChangeUpdate(item.id, event)}
defaultValue={item.city}
></input>
<button onClick={onUpdate}>Update</button>
</li>
))}
</div>
</ul>
</div>
);
};
Upvotes: 0
Views: 893
Reputation: 444
It's because you never set the values of the props. That is why they never change from their initial values. You just update the list
prop in handleChangeUpdate. There are two steps you need to take with the existing file structure:
To realize the first step, you can change the input tag like the following:
{/* attention to the first argument of handleChangeUpdate */}
<input
className="form-control"
name="name"
onChange={(event) => handleChangeUpdate("name", item.id, event)}
defaultValue={item.name}
></input>
Then, you need to adjust the handleChangeUpdate:
if (name === "name") {
setName(value);
} else if (name === "description") {
setDescription(value);
} else if (name === "city") {
setCity(value);
}
By the way, list is not a good name for a variable.
Without creating new parameters, you can also use only the event to set the props
// Handler for changing values of each input
function handleChangeUpdate(id, event) {
const { name, value } = event.target;
const newList = list.map((item) => {
if (item.id === id) {
const updatedItem = {
...item,
[name]: value
};
return updatedItem;
}
return item;
});
setList(newList);
console.log(newList);
if (name === "name") {
setName(value);
} else if (name === "description") {
setDescription(value);
} else if (name === "city") {
setCity(value);
}
}
Upvotes: 1
Reputation: 21
I think you have 3 errors in the onUpdate
function.
id
of the item from the onClick
eventput
method should be changeget
request as soon as after the put
request, because sometimes the backend will not updated yet.You can update your code as below,
1.Pass the id
of the item when the button is clicked.
<button onClick={onUpdate(item.id)}>Update</button>
put
method, passing the id
axios
.put(
`https://6092374385ff5100172122c8.mockapi.io/api/test/users/${e}`,
test
).then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
3.Perform the get
request after the response of the put
request
const onUpdate = (e) => {
const test = {
name: name,
description: description,
city: city
};
console.log(test);
// axios request PUT data on API
axios
.put(
`https://6092374385ff5100172122c8.mockapi.io/api/test/users/${e}`,
test
)
.then((res) => {
console.log(res);
// axios request GET to get the new modified list from the database, after the update
axios
.get("https://6092374385ff5100172122c8.mockapi.io/api/test/users")
.then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
})
.catch((error) => {
console.log(error);
});
};
Upvotes: 0