I'm learning Angular from the very beginning, and coming from React, I can't find a way to manage a simple state in Angular. It's a simple todo app, and my strategy is to create a Todos array in todo.service.ts
@Injectable()
export class TodoService {
todos: Todo[] = [
{ id: 0, title: 'Cooking', completed: false }
]
nextId: number = 1;
constructor() { }
public getTodos(): Todo[] {
return this.todos;
}
public addTodo(title: string): any {
this.newTodo = new Todo({ id: this.nextId, title, completed: false })
this.todos.push(this.newTodo);
this.newTodo = new Todo();
this.nextId++
}
public deleteTodo(chosenTodo: Todo): any {
this.todos = this.todos.filter(todo => todo.id !== chosenTodo.id)
}
}
Now on the ListingComponent, I want to get all Todos, and then pass it down to ListingItemComponent, as such
todos: Todo[] = []
todoTitle: string = '';
constructor(private todoService: TodoService) { }
ngOnInit(): void {
this.todos = this.todoService.getTodos();
this.todoTitle = 'Do Something';
}
addTodo() {
this.todoService.addTodo(this.todoTitle);
}
<div *ngFor="let todo of todos">
<todo-listing-item [todo]="todo"></todo-listing-item>
</div>
/* This just adds a todo with title 'Do Something' for testing */
<button (click)="addTodo()">Add Todo</button>
Finally in ListingItemComponent
@Input() todo: Todo
constructor(private todoService: TodoService) { }
ngOnInit(): void {
}
deleteTodo(): void {
this.todoService.deleteTodo(this.todo)
}
<h1>{{todo.title}}</h1>
<button (click)="deleteTodo()">Delete Todo</button>
Now the component has no error, and I made sure to declare everything, but it's not working. Clicking the button won't change anything. After digging in, I changed the ListingComponent into "let todo of todoService.getTodos()", and remove the todos in the ts file along with the ngOnInit, and somehow it works. My guessing is that the ListingComponent doesn't know that the todos array has changed, and so it's not rerendering?
- So if I was to initialize the todos in the ngOnInit like I did before, do I need some other life-cycle to listen to the change of todos?
If many components need the todos array, should I write
ngOnInit(): void { this.todos = this.todoService.getTodos();}on every single one of them? And if one component changes their todos, can other components listen and rerender as well?Thank you for reading. In React I would just create a global state, along with the functions, and pass it as props down to every child. But I can't wrap my head around managing state in Angular. Is it because I'm thinking in React, while I should not?
