feat(rxjs): refactor challenge 11

This commit is contained in:
thomas
2025-01-29 20:25:35 +01:00
parent 2050f7a932
commit 3cea14982e
111 changed files with 31 additions and 2787 deletions

View File

@@ -1,46 +1,44 @@
/* eslint-disable @angular-eslint/component-selector */
import { AsyncPipe, NgFor } from '@angular/common';
import { Component, Input, inject } from '@angular/core';
import { BehaviorSubject, take } from 'rxjs';
import { Component, inject, input, signal } from '@angular/core';
import { take } from 'rxjs';
import { AppService } from './app.service';
import { TopicType } from './localDB.service';
@Component({
selector: 'button-delete-topic',
imports: [AsyncPipe],
template: `
<button (click)="deleteTopic()"><ng-content></ng-content></button>
<div>{{ message$$ | async }}</div>
<button (click)="deleteTopic()"><ng-content /></button>
<div>{{ message() }}</div>
`,
})
export class ButtonDeleteComponent {
@Input() topic!: TopicType;
readonly topic = input.required<TopicType>();
message$$ = new BehaviorSubject<string>('');
message = signal('');
private service = inject(AppService);
deleteTopic() {
this.service
.deleteOldTopics(this.topic)
.deleteOldTopics(this.topic())
.pipe(take(1))
.subscribe((result) =>
this.message$$.next(
this.message.set(
result
? `All ${this.topic} have been deleted`
: `Error: deletion of some ${this.topic} failed`,
? `All ${this.topic()} have been deleted`
: `Error: deletion of some ${this.topic()} failed`,
),
);
}
}
@Component({
imports: [AsyncPipe, NgFor, ButtonDeleteComponent],
imports: [ButtonDeleteComponent],
selector: 'app-root',
template: `
<div *ngFor="let item of all$ | async">
{{ item.id }} - {{ item.topic }}
</div>
@for (info of allInfo(); track info.id) {
<div>{{ info.id }} - {{ info.topic }}</div>
}
<button-delete-topic topic="food">Delete Food</button-delete-topic>
<button-delete-topic topic="sport">Delete Sport</button-delete-topic>
@@ -50,5 +48,5 @@ export class ButtonDeleteComponent {
export class AppComponent {
private service = inject(AppService);
all$ = this.service.getAll$;
allInfo = this.service.getAllInfo;
}

View File

@@ -1,23 +1,19 @@
import { inject, Injectable } from '@angular/core';
import { merge, mergeMap, Observable, of, take } from 'rxjs';
import { merge, Observable, of } from 'rxjs';
import { LocalDBService, TopicType } from './localDB.service';
@Injectable({ providedIn: 'root' })
export class AppService {
private dbService = inject(LocalDBService);
getAll$ = this.dbService.infos$;
getAllInfo = this.dbService.infos;
deleteOldTopics(type: TopicType): Observable<boolean> {
return this.dbService.searchByType(type).pipe(
take(1),
mergeMap((topicToDelete) =>
topicToDelete.length > 0
? topicToDelete
.map((t) => this.dbService.deleteOneTopic(t.id))
.reduce((acc, curr) => merge(acc, curr), of(true))
: of(true),
),
);
const infoByType = this.dbService.searchByType(type);
return infoByType.length > 0
? infoByType
.map((t) => this.dbService.deleteOneTopic(t.id))
.reduce((acc, curr) => merge(acc, curr), of(true))
: of(true);
}
}

View File

@@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/member-ordering */
import { randomError } from '@angular-challenges/shared/utils';
import { Injectable } from '@angular/core';
import { ComponentStore } from '@ngrx/component-store';
import { computed, Injectable, signal } from '@angular/core';
import { of } from 'rxjs';
export type TopicType = 'food' | 'book' | 'sport';
@@ -31,21 +30,17 @@ const initialState: DBState = {
};
@Injectable({ providedIn: 'root' })
export class LocalDBService extends ComponentStore<DBState> {
constructor() {
super(initialState);
}
export class LocalDBService {
private state = signal(initialState);
infos$ = this.select((state) => state.infos);
infos = computed(() => this.state().infos);
searchByType = (type: TopicType) =>
this.select((state) => state.infos.filter((i) => i.topic === type));
this.infos().filter((i) => i.topic === type);
deleteOne = this.updater(
(state, id: number): DBState => ({
infos: state.infos.filter((i) => i.id !== id),
}),
);
deleteOne = (id: number) => {
this.state.set({ infos: this.state().infos.filter((i) => i.id !== id) });
};
deleteOneTopic = (id: number) =>
randomError({