From 97e75b7fceea1bf7d5db8a15cd2f0b69efe35095 Mon Sep 17 00:00:00 2001 From: Edouard Bozon Date: Wed, 1 Nov 2023 20:27:37 +0100 Subject: [PATCH] refactor: connect in setup fn --- package.json | 4 +- projects/todo-mvc/src/app/todo.service.ts | 57 +++++++++++------------ yarn.lock | 16 +++---- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 089c575..c1afab5 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "@angular/platform-browser": "^17.0.0-rc.0", "@angular/ssr": "^17.0.0-rc.0", "@rx-angular/cdk": "16.0.0", - "@rx-angular/state": "16.1.0", - "@rx-angular/template": "16.1.0", + "@rx-angular/state": "16.3.0", + "@rx-angular/template": "16.1.1", "body-parser": "^1.20.1", "cors": "^2.8.5", "rxjs": "~7.4.0", diff --git a/projects/todo-mvc/src/app/todo.service.ts b/projects/todo-mvc/src/app/todo.service.ts index b88e0bc..2fbb539 100644 --- a/projects/todo-mvc/src/app/todo.service.ts +++ b/projects/todo-mvc/src/app/todo.service.ts @@ -1,5 +1,5 @@ import { inject, Injectable } from '@angular/core'; -import { forkJoin, merge } from 'rxjs'; +import { forkJoin, merge, Observable } from 'rxjs'; import { exhaustMap, map, withLatestFrom } from 'rxjs/operators'; import { rxState } from '@rx-angular/state'; import { rxActions } from '@rx-angular/state/actions'; @@ -27,36 +27,21 @@ export interface Actions { setFilter: TodoFilter; } -export const INITIAL_STATE: Partial = { - filter: 'all', -}; +const completedTodos = (source: Observable): Observable => + source.pipe(map((todos) => todos.filter((todo) => todo.done))); + +const activeTodos = (source: Observable): Observable => + source.pipe(map((todos) => todos.filter((todo) => !todo.done))); @Injectable() export class TodoService { readonly #todoResource = inject(TodoResource); - readonly #state = rxState(({ set }) => { - set(INITIAL_STATE); - }); + readonly actions = rxActions(); - readonly filter$ = this.#state.select('filter'); - readonly allTodos$ = this.#state.select('todos'); - readonly completedTodos$ = this.allTodos$.pipe( - map((todos) => todos.filter((todo) => todo.done)) - ); - readonly activeTodos$ = this.allTodos$.pipe( - map((todos) => todos.filter((todo) => !todo.done)) - ); - readonly filteredTodos$ = this.#state.select( - ['filter', 'todos'], - ({ todos, filter }) => - todos.filter(({ done }) => { - if (filter === 'active') return !done; - if (filter === 'completed') return done; - return true; - }) - ); - constructor() { + readonly #state = rxState(({ set, connect, select }) => { + set({ filter: 'all' }); + const getAll$ = this.#todoResource .getAll() .pipe(map((todos) => ({ todos }))); @@ -76,7 +61,7 @@ export class TodoService { map((todos) => ({ todos })) ); const toggleAll$ = this.actions.toggleAll$.pipe( - withLatestFrom(this.allTodos$), + withLatestFrom(select('todos')), exhaustMap(([, todos]) => forkJoin( todos.map((todo) => @@ -90,14 +75,14 @@ export class TodoService { map((updates) => ({ todos: updates.at(-1) })) ); const clearCompleted$ = this.actions.clearCompleted$.pipe( - withLatestFrom(this.completedTodos$), + withLatestFrom(select('todos').pipe(completedTodos)), exhaustMap(([, todos]) => forkJoin(todos.map((todo) => this.#todoResource.remove(todo))) ), map((updates) => ({ todos: updates.at(-1) })) ); - this.#state.connect( + connect( merge( getAll$, setFilter$, @@ -108,5 +93,19 @@ export class TodoService { clearCompleted$ ) ); - } + }); + + readonly filter$ = this.#state.select('filter'); + readonly allTodos$ = this.#state.select('todos'); + readonly completedTodos$ = this.allTodos$.pipe(completedTodos); + readonly activeTodos$ = this.allTodos$.pipe(activeTodos); + readonly filteredTodos$ = this.#state.select( + ['filter', 'todos'], + ({ todos, filter }) => + todos.filter(({ done }) => { + if (filter === 'active') return !done; + if (filter === 'completed') return done; + return true; + }) + ); } diff --git a/yarn.lock b/yarn.lock index a342209..7719b4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2281,18 +2281,18 @@ dependencies: "@typescript-eslint/experimental-utils" "^5.4.0" -"@rx-angular/state@16.1.0": - version "16.1.0" - resolved "https://registry.yarnpkg.com/@rx-angular/state/-/state-16.1.0.tgz#a1a2ab781c6951eb47da33b61acba4f6c7616be9" - integrity sha512-WBIyanxI7xUPE/aK4LG2IpH80ej6jl4bVluGNWwbnzwsxDH1YpetlvU1QvbAmQkZlgg/moI10XOADWaxy7UsVQ== +"@rx-angular/state@16.3.0": + version "16.3.0" + resolved "https://registry.yarnpkg.com/@rx-angular/state/-/state-16.3.0.tgz#90617610099e66eb4c25d9e320ac3569da86fb3b" + integrity sha512-bdV71umTRIximfTAlBOrL4m5fflInjK2O/kYj6mmAvKig0+F/NxF11psa8AyEXCieZFzKlukvGuUV//ulKAn9A== dependencies: ng-morph "^3.0.0" tslib "^2.4.1" -"@rx-angular/template@16.1.0": - version "16.1.0" - resolved "https://registry.npmjs.org/@rx-angular/template/-/template-16.1.0.tgz" - integrity sha512-Q394edxYdA3ZPMaDVBtt51KY9lhfGYnMiLyMaf/sWKlLubj8Hn5PCgfz1nZFGD1f3NEU5Q5pTwT3Sk++qG5Ogw== +"@rx-angular/template@16.1.1": + version "16.1.1" + resolved "https://registry.yarnpkg.com/@rx-angular/template/-/template-16.1.1.tgz#6b2a8d632629659b0a36b1ee1d9b438bd4f21f01" + integrity sha512-Jhe53Bcwuv0xDNIGNvJzro2Uer9LJg0F7OwNH0a3SkSKaeNOVLJTwI0fdkY8hjeoVCLpoX1xTH/FoYWaX/m70w== dependencies: ng-morph "^3.0.0" tslib "^2.4.1"