diff --git a/projects/todo-mvc/src/app/todo-list.component.ts b/projects/todo-mvc/src/app/todo-list.component.ts index d453adc..a09a4bf 100644 --- a/projects/todo-mvc/src/app/todo-list.component.ts +++ b/projects/todo-mvc/src/app/todo-list.component.ts @@ -7,7 +7,7 @@ import { } from '@angular/core'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { RxLet } from '@rx-angular/template/let'; -import { TodoService } from './todo-list.state.service'; +import { TodoService } from './todo-list.service'; import { TodoComponent } from './todo.component'; @Component({ @@ -29,7 +29,7 @@ import { TodoComponent } from './todo.component'; class="new-todo" placeholder="What needs to be done?" [formControl]="input" - (keyup.enter)="addTodo()" + (keyup.enter)="todoService.actions.create({ text: $event, callback: resetInput })" />
@@ -109,14 +109,5 @@ export class TodoListComponent { readonly input = new FormControl(''); readonly todoService = inject(TodoService); - - addTodo(): void { - const text = (this.input.value ?? '').trim(); - if (text.length === 0) { - return; - } - - this.todoService.actions.create({ text }); - this.input.reset(); - } + readonly resetInput = () => this.input.reset(); } diff --git a/projects/todo-mvc/src/app/todo-list.state.service.ts b/projects/todo-mvc/src/app/todo-list.service.ts similarity index 84% rename from projects/todo-mvc/src/app/todo-list.state.service.ts rename to projects/todo-mvc/src/app/todo-list.service.ts index 6252500..3b90e69 100644 --- a/projects/todo-mvc/src/app/todo-list.state.service.ts +++ b/projects/todo-mvc/src/app/todo-list.service.ts @@ -1,9 +1,15 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { inject, Injectable } from '@angular/core'; import { rxState } from '@rx-angular/state'; -import { rxActions } from '@rx-angular/state/actions'; +import { eventValue, rxActions } from '@rx-angular/state/actions'; import { merge, MonoTypeOperatorFunction } from 'rxjs'; -import { exhaustMap, map, withLatestFrom } from 'rxjs/operators'; +import { + exhaustMap, + filter, + map, + tap, + withLatestFrom, +} from 'rxjs/operators'; import { Todo, TodoFilter } from './todo.model'; import { TodoResource } from './todo.resource'; @@ -13,7 +19,7 @@ interface TodoState { } interface Actions { - create: Pick; + create: Pick & { callback: () => void }; remove: Pick; update: Todo; toggleAll: void; @@ -22,6 +28,13 @@ interface Actions { drop: CdkDragDrop; } +interface Transforms { + create: (args: { + text: Event | string; + callback: () => void; + }) => Pick & { callback: () => void }; +} + const completedTodos: MonoTypeOperatorFunction = (source) => { return source.pipe(map((todos) => todos.filter((todo) => todo.done))); }; @@ -34,7 +47,11 @@ const activeTodos: MonoTypeOperatorFunction = (source) => { export class TodoService { readonly #todoResource = inject(TodoResource); - readonly actions = rxActions(); + readonly actions = rxActions(({ transforms }) => { + transforms({ + create: (args) => ({ ...args, text: eventValue(args.text) }), + }); + }); readonly #state = rxState(({ set, connect, select }) => { set({ filter: 'all' }); @@ -46,6 +63,8 @@ export class TodoService { map((filter) => ({ filter })) ); const create$ = this.actions.create$.pipe( + filter(({ text }) => text.trim().length > 0), + tap(({ callback }) => callback()), exhaustMap((todo) => this.#todoResource.create(todo)), map((todos) => ({ todos })) ); diff --git a/projects/todo-mvc/src/app/todo.component.ts b/projects/todo-mvc/src/app/todo.component.ts index a36155f..18de1a8 100644 --- a/projects/todo-mvc/src/app/todo.component.ts +++ b/projects/todo-mvc/src/app/todo.component.ts @@ -25,8 +25,8 @@ interface Actions { } interface Transforms { - toggleDone: (e: Event) => boolean; - updateText: (e: Event | string) => string; + toggleDone: typeof eventChecked; + updateText: typeof eventValue; } interface State {