[Angular 2] Refactoring mutations to enforce immutable data in Angular 2

When a Todo property updates, you still must create a new Array of Todos and assign a new reference. This lesson walks you through refactoring from the current approach to the immutable approach.

TodoItemRender.ts:

import {Component, Input, ViewEncapsulation, EventEmitter, Output} from 'angular2/core';
@Component({
    selector: 'todo-item-renderer',
    // encapsulation:ViewEncapsulation.Emulated, //Default, (parent style pass )in and no (child style go) out
    // encapsulation:ViewEncapsulation.Native, // no in and no out
    encapsulation:ViewEncapsulation.None, // in and out
    template: `
        <style>
            .completed{
                text-decoration: line-through;
            }
        </style>
        <div>    
            <span [ngClass]="todo.status"
                  [contentEditable]="todo.isEdit">{{todo.title}}</span>
            <button (click)="toggleTodo.emit(todo)">Toggle</button>
            <button (click)="todo.edit()">Edit</button>
        </div>
    `
})

export class TodoItemRenderer{
    @Input() todo;
    @Output() toggleTodo = new EventEmitter();
}

Here we use EventEmitter to emit a event called 'toggleTodo'. Parent component (TodoList.ts) will catch the event and update the TodoService's todos array.

And todos array should be a new reference.

TodoList.ts:

import {Component} from 'angular2/core';
import {TodoService} from './TodoService';
import {TodoItemRenderer} from './TodoItemRenderer';
import {StartedPipe} from './started-pipe';

@Component({
    selector: 'todo-list',
    pipes: [StartedPipe],
    directives: [TodoItemRenderer],
    template: `
        <ul>
            <li *ngFor="#todo of todoService.todos | started">
                <todo-item-renderer [todo]="todo"
                (toggleTodo) = "todoService.toggleTodo($event)" // Contains the todoModule
                ></todo-item-renderer>
            </li>
            
        </ul>
    `
})

export class TodoList{
    constructor(public todoService: TodoService){
        
    }
}

TodoService.ts:

import {TodoModule} from './TodoModule';
export class TodoService {
    todos = [
        //init some todos
        new TodoModule("eat"),
        new TodoModule("sleep"),
        new TodoModule("code")
    ];

    addNewTodo(todo) {
        this.todos = [...this.todos, todo];
    }

    toggleTodo(todo) {

        const i = this.todos.indexOf(todo);

        todo.toggle();

        this.todos = [
            ...this.todos.slice(0, i),
            todo,
            ...this.todos.slice( i + 1)
        ];
    }
}

---------------------