1

I am new to Javascript so probably I am lacking the fundamentals to solve this issue. I am trying different things, and reading tutorials, but so far no luck.

The objective is to modify the state, just by addding a new keyword to the array "keywords" that is contained inside the "blockOptions" object. I add a key/value for then using .map() or deleting the keyword if needing. I am also trying to use ES6 recommendations.

Here is the constructor:

      blockOptions: {
          ...
          keywords: [],

And here is the function I call from the component

 onAddKeyword(e) {
    if (e.key === "Enter") {
      var newKeyword = {
        text: e.target.value,
        key: Date.now()
      };

      this.setState({
        blockOptions.keywords: [...this.state.blockOptions.keywords, newKeyword]
      });

      console.log(this.blockOptions.keywords);
      e.target.value = "";
      e.preventDefault();
    }
  }

If I use this same code with an array that is not nested inside "blockOptions", everything works fine. Any suggestion about the code itself would be valuable as I am still new to JS.

Thanks for your help

2
  • 3
    As soon as this.state.blockOptions is an object - you need to setState the object as well: this.setState({ blockOptions: { keywords: ... } }) Commented Apr 16, 2019 at 21:18
  • try changing your function declaration to onAddKeyword = (e) => { since it is an event function you might want to check what this is equal to. You might be setting the event.state to something and not the component. Commented Apr 16, 2019 at 21:19

3 Answers 3

2

The first issue in your code is that you supposse

{
    blockOptions.keywords: []
}

works as a sort of shortcut for

{
     blockOptions: {
          keywords: []
     }
}

The left-side on a literal object creation must be only a String or a Symbol, your example should throw an Uncaught SyntaxError: Unexpected token :.

Besides that, you'll need to do something like:

this.setState({
    blockOptions: {
        ...this.state.blockOptions, //copy all the properties
        keywords: [...this.state.blockOptions.keywords, newKeyword]
    }
})

The gather / ... operator on Objects, is not an ES2015 feature, but its available through babel.

A native ES2015 alternative is

const blockOptionsCopy = Object.assign(
   {},
   this.state.blockOptions,
   { keywords: [...this.state.blockOptions.keywords, newKeyword] }
);
this.setState({
   blockOptions: blockOptionsCopy
})
Sign up to request clarification or add additional context in comments.

Comments

0
    const { blockOptions } = this.state;
    blockOptions.keywords.push(newKeyword);
    this.setState({ blockOptions });

1 Comment

A few words explaining your answer would be helpful.
0

You have to do it immutably and copy the whole object and inner array.

First copy the blockOptions using the spread operator. Then overwrite the keywords property with a new array:

this.setState({
  blockOptions: {
    ...this.state.blockOptions, // copy blockOptions
    keywords: [...this.state.blockOptions.keywords, newKeyword] // overwrite keywords
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.