Reputation: 17
I've been facing a problem. I already tried to solve it. But, I don't know how to get it to work. I know my problem is that I don't reupdate the Lists New state after I push or delete to the API? How can I fix this? So, I don't have to manually refresh the page?
I have 2 components but in this post, I will only show the one I use for delete and read from API this post, which is called "Products". The PostForm component is a separate component that is imported into the Create/Delete component.
I added this code in the setState for delete. I guess I need a function to reupdate the state but don't know-how. would appreciate help // productList: filter((item) => item.id !== productId),
class Products extends Component {
state = {
productList: [],
statusMsg: "",
};
// READ
getDataFromProductsApi() {
axios
.get("https://localhost:44366/api/Products/")
.then((res) => {
console.log(res.data);
this.setState({
productList: res.data,
});
})
.catch((error) => {
console.log(error);
this.setState({ statusMsg: "Error retreiving data" });
if (axios.isCancel(error)) return;
});
}
componentDidMount() {
this.getDataFromProductsApi();
}
// DELETE
deleteProduct = (productId, productName) => {
if (window.confirm("Are you sure? you want to delete")) {
axios
.delete(`https://localhost:44366/api/Products/${productId}`)
.then((response) => {
console.log(response);
this.setState({
statusMsg: `Product name: ${productName} With the ID: ${productId} was removed!`,
// productList: filter((item) => item.id !== productId),
});
});
}
};
showProducts = () => {
return (
<table className="customers">
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Delete</th>
</tr>
{this.state.productList.map((product) => {
return (
<tr key={product.id}>
<td>{product.id}</td>
<td>{product.name}</td>
<td>{product.category}</td>
<td>{product.price}</td>
<td>
<button
onClick={() => this.deleteProduct(product.id, product.name)}
>
X
</button>
</td>
</tr>
);
})}
</tbody>
</table>
);
};
render() {
return (
<header className="App-header">
<div>
<h1>Products</h1>
<Postform /> {/*Adding the post Component to the view */}
<div> {this.state.statusMsg}</div>
{this.showProducts()} {/*running function to show data view */}
</div>
</header>
);
}
}
Upvotes: 0
Views: 86
Reputation: 722
Is something like this what you mean?
https://jsfiddle.net/bq8h7ns9/
class Products extends React.Component {
state = {
productList : [],
statusMsg: "",
};
// READ
getDataFromProductsApi() {
this.setState({
productList: [{ id : 0, name: 'blah1', price: 12.3, category : 'blah' }, { id : 1, name: 'blah2', price: 32.1, category : 'blah' }],
});
}
componentDidMount() {
this.getDataFromProductsApi();
}
// DELETE
deleteProduct = (productId, productName) => {
if (window.confirm("Are you sure? you want to delete")) {
this.setState({
statusMsg: `Product name: ${productName} With the ID: ${productId} was removed!`,
productList: this.state.productList.filter((item) => item.id !== productId),
});
}
};
showProducts = () => {
return (
<table className="customers">
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Delete</th>
</tr>
{this.state.productList.map((product) => {
return (
<tr key={product.id}>
<td>{product.id}</td>
<td>{product.name}</td>
<td>{product.category}</td>
<td>{product.price}</td>
<td>
<button
onClick={() => this.deleteProduct(product.id, product.name)}
>
X
</button>
</td>
</tr>
);
})}
</tbody>
</table>
);
};
render() {
return (
<header className="App-header">
<div>
<h1>Products</h1>
<div> {this.state.statusMsg}</div>
{this.showProducts()} {/*running function to show data view */}
</div>
</header>
);
}
}
You are already updating the component's state; that is what setState
does. Your commented out line should be something like this.state.productList.filter((item) => item.id !== productId)
, filter
is not a global function.
If you mean you want your component to stay in sync with your api, then you will need to use something like websockets or long polling. Http is a stateless protocol.
Upvotes: 1