I am trying to update a nested value of an object using the spread operator. This is my first time using this and I believe I am pretty close to achieving my end goal but I just can't seem to figure out what I actually need to do next.
I have an array which is structured like this:
[
{
name: "Category 1",
posts: [
{
id: 1,
published: false,
category: "Category 1"
},
{
id: 2,
published: true,
category: "Category 1"
}
]
},
{
name: "Category 2",
posts: [
{
id: 3,
published: true,
category: "Category 2"
},
{
id: 4,
published: true,
category: "Category 2"
}
]
}
]
On the click of a button I am trying to update the published value, and as I am using React I need to set the state. So it got remended to me that I update using the spread operator.
onPostClick(post) {
post.pubished = !post.published;
this.setState({...this.state.posts[post.category], post})
}
If I log out the result of {...this.state.posts[post.category], post}
I can see that the published is getting added to the parent which forms:
{
name: "Category 1",
published: false,
posts: [
...
]
}
Obviously this isn't the intended result, I want it to update the actual object within the posts
object.
I have tried to do something like this.setState({...this.state.posts[post.category].posts, post})
but I get a message that it is undefined.
I am trying to update a nested value of an object using the spread operator. This is my first time using this and I believe I am pretty close to achieving my end goal but I just can't seem to figure out what I actually need to do next.
I have an array which is structured like this:
[
{
name: "Category 1",
posts: [
{
id: 1,
published: false,
category: "Category 1"
},
{
id: 2,
published: true,
category: "Category 1"
}
]
},
{
name: "Category 2",
posts: [
{
id: 3,
published: true,
category: "Category 2"
},
{
id: 4,
published: true,
category: "Category 2"
}
]
}
]
On the click of a button I am trying to update the published value, and as I am using React I need to set the state. So it got remended to me that I update using the spread operator.
onPostClick(post) {
post.pubished = !post.published;
this.setState({...this.state.posts[post.category], post})
}
If I log out the result of {...this.state.posts[post.category], post}
I can see that the published is getting added to the parent which forms:
{
name: "Category 1",
published: false,
posts: [
...
]
}
Obviously this isn't the intended result, I want it to update the actual object within the posts
object.
I have tried to do something like this.setState({...this.state.posts[post.category].posts, post})
but I get a message that it is undefined.
-
onPostClick(post)
- what is post format, does it contain full data together with id / category etc. ? – Goran.it Commented Nov 24, 2018 at 10:47 -
The format is
{ id: 1, category: 'Category 1', published: true }
– connormiotk96 Commented Nov 24, 2018 at 10:52 - So yes @Goran.it it contains all of the data – connormiotk96 Commented Nov 24, 2018 at 10:52
2 Answers
Reset to default 1You can't access your data with this.state.posts[post.category]
. posts
data in the objects of the array.
You can make a filter to find your category object in array and change its posts value.
onPostClick(post) {
//CLONE YOUR DATA
var postArray = this.state.posts;
//FIND YOUR CATEGORY OBJECT IN ARRAY
var categoryIndex = postArray.findIndex(function(obj){
return obj.name === post.category;
});
//FIND YOUR POST AND CHANGE PUBLISHED VALUE
postArray[categoryIndex].posts.forEach(function(item){
if (item.id === post.id) {
item.published = !item.published;
}
});
//SET TO STATE TO RERENDER
this.setState({ posts: postArray});
}
This should work if your name of the state is true.
just adding, we know there are many ways to succeed, maybe you also want to try this way too..
onPostClick = post => {
let published = this.state.data.map((item, i) => {
item.posts.map((item_post, i) => {
if (item_post.category === post.category) {
item_post.published = !post.published;
}
});
});
this.setState({ ...this.state.data, published });
};