diff --git a/package.json b/package.json index c35669b..c0165ac 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@angular/platform-browser": "5.2.3", "@angular/platform-browser-dynamic": "5.2.3", "@angular/router": "5.2.3", + "@ngrx/effects": "5.0.1", "@ngrx/store": "5.0.0", "@ngrx/store-devtools": "5.0.1", "core-js": "2.5.3", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7c7e30c..5e230e0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,10 +3,12 @@ import { ReactiveFormsModule } from '@angular/forms'; import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { StoreModule } from '@ngrx/store'; +import { EffectsModule } from '@ngrx/effects'; import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { environment } from '../environments/environment'; import * as fromApp from './store'; +import { TodosEffects } from './todos/store/effects'; import { AppComponent } from './app.component'; import { TodoComponent, @@ -37,6 +39,7 @@ const routes: Routes = [ StoreModule.forRoot(fromApp.reducers, { metaReducers: fromApp.metaReducers, }), + EffectsModule.forRoot([TodosEffects]), !environment.production ? StoreDevtoolsModule.instrument({ maxAge: 50 }) : [], diff --git a/src/app/todos/components/todo/todo.component.ts b/src/app/todos/components/todo/todo.component.ts index 5772e27..983c148 100644 --- a/src/app/todos/components/todo/todo.component.ts +++ b/src/app/todos/components/todo/todo.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs/Observable'; @@ -9,7 +9,7 @@ import * as fromTodos from '../../store'; selector: 'app-todo', templateUrl: './todo.component.html', }) -export class TodoComponent { +export class TodoComponent implements OnInit { hasTodos$: Observable; undoneTodosCount$: Observable; currentFilter$: Observable; @@ -22,6 +22,10 @@ export class TodoComponent { this.filteredTodos$ = this.store.select(fromTodos.getFilteredTodos); } + ngOnInit() { + this.store.dispatch(new fromTodos.LoadAction()); + } + onAddTodo(text: string) { this.store.dispatch(new fromTodos.AddAction(text)); } diff --git a/src/app/todos/store/actions.ts b/src/app/todos/store/actions.ts index e4c4616..d58cb67 100644 --- a/src/app/todos/store/actions.ts +++ b/src/app/todos/store/actions.ts @@ -6,6 +6,8 @@ export const ADD_TODO = '[TODO] add'; export const DELETE_TODO = '[TODO] delete'; export const TOGGLE_TODO = '[TODO] toggle'; export const UPDATE_TODO = '[TODO] update'; +export const LOAD_TODOS = '[TODO] load'; +export const LOAD_TODOS_COMPLETED = '[TODO] load completed'; export const CLEAR_COMPLETED_TODO = '[TODO] clear completed'; export const SET_TODO_FILTER = '[TODO] Set filter'; @@ -18,6 +20,16 @@ export class AddAction implements Action { } } +export class LoadAction implements Action { + readonly type = LOAD_TODOS; +} + +export class LoadCompletedAction implements Action { + readonly type = LOAD_TODOS_COMPLETED; + + constructor(public todos: Todo[]) {} +} + export class DeleteAction implements Action { readonly type = DELETE_TODO; @@ -48,6 +60,8 @@ export class SetFilterAction implements Action { export type TodoActionType = | AddAction + | LoadAction + | LoadCompletedAction | ToggleAction | DeleteAction | UpdateAction diff --git a/src/app/todos/store/effects.ts b/src/app/todos/store/effects.ts new file mode 100644 index 0000000..92ac493 --- /dev/null +++ b/src/app/todos/store/effects.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@angular/core'; +import { Actions, Effect } from '@ngrx/effects'; +import { Action, Store } from '@ngrx/store'; +import { Observable } from 'rxjs/Observable'; + +import { Todo } from '../models'; +import * as fromTodos from '../store'; + +@Injectable() +export class TodosEffects { + @Effect() + loadTodos$: Observable = this.actions$ + .ofType(fromTodos.LOAD_TODOS) + .switchMap(action => + // Simulate network call + Observable.of( + new fromTodos.LoadCompletedAction([ + { + id: 0.123456789, + text: 'Remove before flight!', + completed: false, + }, + ]), + ).delay(1000), + ); + + constructor( + private actions$: Actions, + private todosStore: Store, + ) {} +} diff --git a/src/app/todos/store/reducers.ts b/src/app/todos/store/reducers.ts index a898528..f725641 100644 --- a/src/app/todos/store/reducers.ts +++ b/src/app/todos/store/reducers.ts @@ -30,6 +30,13 @@ export function reducer( }; } + case fromTodos.LOAD_TODOS_COMPLETED: { + return { + ...state, + todos: action.todos, + }; + } + case fromTodos.TOGGLE_TODO: { return { ...state,