mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-12 05:43:03 -05:00
feat(challenge11): creation
This commit is contained in:
56
apps/rxjs-pipe-bug/src/app/app.component.ts
Normal file
56
apps/rxjs-pipe-bug/src/app/app.component.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
import { AsyncPipe, NgFor } from '@angular/common';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { BehaviorSubject, take } from 'rxjs';
|
||||
import { AppService } from './app.service';
|
||||
import { TopicType } from './localDB.service';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'button-delete-topic',
|
||||
imports: [AsyncPipe],
|
||||
template: `
|
||||
<button (click)="deleteTopic()"><ng-content></ng-content></button>
|
||||
<div>{{ message$$ | async }}</div>
|
||||
`,
|
||||
})
|
||||
export class ButtonDeleteComponent {
|
||||
@Input() topic!: TopicType;
|
||||
|
||||
message$$ = new BehaviorSubject<string>('');
|
||||
|
||||
private service = inject(AppService);
|
||||
|
||||
deleteTopic() {
|
||||
this.service
|
||||
.deleteOldTopics(this.topic)
|
||||
.pipe(take(1))
|
||||
.subscribe((result) =>
|
||||
this.message$$.next(
|
||||
result
|
||||
? `All ${this.topic} have been deleted`
|
||||
: `Error: deletion of some ${this.topic} failed`
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [AsyncPipe, NgFor, ButtonDeleteComponent],
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<div *ngFor="let item of all$ | async">
|
||||
{{ item.id }} - {{ item.topic }}
|
||||
</div>
|
||||
|
||||
<button-delete-topic topic="food">Delete Food</button-delete-topic>
|
||||
<button-delete-topic topic="sport">Delete Sport</button-delete-topic>
|
||||
<button-delete-topic topic="book">Delete Book</button-delete-topic>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {
|
||||
private service = inject(AppService);
|
||||
|
||||
all$ = this.service.getAll$;
|
||||
}
|
||||
23
apps/rxjs-pipe-bug/src/app/app.service.ts
Normal file
23
apps/rxjs-pipe-bug/src/app/app.service.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { merge, mergeMap, Observable, of, take } from 'rxjs';
|
||||
import { LocalDBService, TopicType } from './localDB.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AppService {
|
||||
private dbService = inject(LocalDBService);
|
||||
|
||||
getAll$ = 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)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
58
apps/rxjs-pipe-bug/src/app/localDB.service.ts
Normal file
58
apps/rxjs-pipe-bug/src/app/localDB.service.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { randNumber } from '@ngneat/falso';
|
||||
import { ComponentStore } from '@ngrx/component-store';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
export type TopicType = 'food' | 'book' | 'sport';
|
||||
|
||||
interface Info {
|
||||
id: number;
|
||||
topic: TopicType;
|
||||
}
|
||||
|
||||
interface DBState {
|
||||
infos: Info[];
|
||||
}
|
||||
|
||||
const initialState: DBState = {
|
||||
infos: [
|
||||
{ id: 1, topic: 'book' },
|
||||
{ id: 2, topic: 'book' },
|
||||
{ id: 3, topic: 'book' },
|
||||
{ id: 4, topic: 'book' },
|
||||
{ id: 5, topic: 'food' },
|
||||
{ id: 6, topic: 'food' },
|
||||
{ id: 7, topic: 'book' },
|
||||
{ id: 8, topic: 'book' },
|
||||
{ id: 9, topic: 'book' },
|
||||
{ id: 10, topic: 'sport' },
|
||||
],
|
||||
};
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class LocalDBService extends ComponentStore<DBState> {
|
||||
constructor() {
|
||||
super(initialState);
|
||||
}
|
||||
|
||||
infos$ = this.select((state) => state.infos);
|
||||
|
||||
searchByType = (type: TopicType) =>
|
||||
this.select((state) => state.infos.filter((i) => i.topic === type));
|
||||
|
||||
deleteOne = this.updater(
|
||||
(state, id: number): DBState => ({
|
||||
infos: state.infos.filter((i) => i.id !== id),
|
||||
})
|
||||
);
|
||||
|
||||
deleteOneTopic = (id: number) => {
|
||||
const randomNumber = randNumber({ min: 0.1, max: 1, fraction: 2 });
|
||||
if (randomNumber > 0.5) {
|
||||
this.deleteOne(id);
|
||||
return of(true);
|
||||
}
|
||||
return of(false);
|
||||
};
|
||||
}
|
||||
0
apps/rxjs-pipe-bug/src/assets/.gitkeep
Normal file
0
apps/rxjs-pipe-bug/src/assets/.gitkeep
Normal file
BIN
apps/rxjs-pipe-bug/src/favicon.ico
Normal file
BIN
apps/rxjs-pipe-bug/src/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
13
apps/rxjs-pipe-bug/src/index.html
Normal file
13
apps/rxjs-pipe-bug/src/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>RxjsPipeBug</title>
|
||||
<base href="/" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
||||
4
apps/rxjs-pipe-bug/src/main.ts
Normal file
4
apps/rxjs-pipe-bug/src/main.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { AppComponent } from './app/app.component';
|
||||
|
||||
bootstrapApplication(AppComponent).catch((err) => console.error(err));
|
||||
1
apps/rxjs-pipe-bug/src/styles.scss
Normal file
1
apps/rxjs-pipe-bug/src/styles.scss
Normal file
@@ -0,0 +1 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
Reference in New Issue
Block a user