0

I have the following code:

todos$ = new BehaviorSubject<TodoInterface[]>([]);
  filter$ = new BehaviorSubject<FilterEnum>(FilterEnum.all);

  addTodo(text: string): void {
    const newTodo: TodoInterface = {
      id: Math.random().toString(16),
      text: text,
      isCompleted: false,
    };
    const updateTodos = [...this.todos$.getValue(), newTodo];
    this.todos$.next(updateTodos);
    console.log(this.todos$);
  }

  toggleAll(isCompleted: boolean): void {
    const updatedTodos = this.todos$.getValue().map((todo) => {
      //   todo.isCompleted = isCompleted;          
      return {
        ...todo,
        isCompleted,
      };
    });
    this.todos$.next(updatedTodos);        
  }

The thing I achieve with the toggleAll function is that every Todo object's isCompleted property will change from false to true. I follow along a tutorial and there the instructor changed the property's value the way seen above, however, it is totally not clear for me how after the spread operator the boolean value of the argument 'isCompleted' can overwrite the object property's value. Could someone please explain it?

The commented part is what I personally wanted to do without using the next method and I think it's a better approach and less confusing.

WillD
  • 5,170
  • 6
  • 27
  • 56
  • Does this answer your question? [Using spread operator to update an object value](https://stackoverflow.com/questions/49491393/using-spread-operator-to-update-an-object-value) – pilchard Aug 01 '22 at 18:24
  • Also shown in the docs: [Spread syntax (...)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#syntax), though in your case it is using a [shorthand property name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#new_notations_in_ecmascript_2015) – pilchard Aug 01 '22 at 18:26

1 Answers1

0

Array.map() will return a new array, with one item for every item in the original array. A function you provide decides what the new item will be, and can access the old item. It can be a transformation, or modification, or other arbitrary operation that produces a new value for the new array. In this case the thing you are doing is returning an object that is almost like the original one except that the value of isCompleted is set by the argument in the function. The spread operator ... simply copies all the props of the old item to the new item.

Then the next line isCompleted, sets the value of isCompleted to whatever is passed as the function argument. Now, we can assume that the old object also had an isCompleted already. But this line overwrites whatever that was (by including this line after the ... part).

This part uses a shorthand assignment syntax as described here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#new_notations_in_ecmascript_2015

And is the same as saying this:

return {
        ...todo,
        isCompleted: isCompleted
      };
WillD
  • 5,170
  • 6
  • 27
  • 56
  • Wow, a very quick and easy-to-understand answer, thank you very much! I was not aware of this shorthand syntax, that's why I was totally confused. Thank you again! – marcopolocs Aug 01 '22 at 18:35
  • You're welcome. There's a little checkbox you could click to accept the answer if you like. – WillD Aug 01 '22 at 18:49
  • *'we can assume that the old object also had an isCompleted already'* actually there is nothing to indicate that, but regardless it *either* sets it if it doesn't already exist, or overwrites it if it does. – pilchard Aug 01 '22 at 20:15
  • The `addTodo` function from the example code does somewhat imply that it is there on the list of todos. But I take your point. – WillD Aug 01 '22 at 20:17