Skip to content

Commit 5b03fcd

Browse files
committedNov 1, 2023
updated readme
1 parent 89351e0 commit 5b03fcd

File tree

1 file changed

+5
-135
lines changed

1 file changed

+5
-135
lines changed
 

‎README.md

+5-135
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,17 @@
1-
# NgRx Component Store Crud
1+
# Angular CRUD implementation with different state management libraries
22
[![Netlify Status](https://api.netlify.com/api/v1/badges/6b9b71d8-a9b1-49e9-9afa-19a47c7bfa59/deploy-status)](https://app.netlify.com/sites/component-store-crud/deploys)
33

44
### Features
5-
- Component Store for CRUD state
5+
- rxState / NgRx Component-Store for CRUD state
66
- Smart / Dumb component architecture
77
- Angular Material components
88
- Table animations (on add, update, remove)
99
- Error, Loading state handling
1010

1111

12-
### Code parts
13-
14-
#### TodosStore
15-
```ts
16-
17-
@Injectable({ providedIn: 'root' })
18-
export class TodosStore extends ComponentStore<TodosState> {
19-
20-
constructor(private todosService: TodosService) {
21-
super(initialState);
22-
}
23-
24-
loadTodos = this.effect((payload$: Observable<Partial<GetTodosPayload>>) => payload$.pipe(
25-
tap(() => this.patchState({ loading: true, loaded: false, error: null })),
26-
switchMap(payload => {
27-
const currentPayload = this.get(s => s.params);
28-
const newPayload = { ...currentPayload, ...payload };
29-
return this.todosService.get(newPayload).pipe(
30-
tap((data: Todo[]) =>
31-
this.patchState({
32-
data, error: null, loading: false, loaded: true, params: newPayload,
33-
total: 100 // this should be retrieved from headers, or most of the time will come with the response body
34-
})
35-
),
36-
catchError(error => {
37-
this.patchState({
38-
error, data: [], loading: false, loaded: false, params: initialState.params
39-
});
40-
return EMPTY; // we return EMPTY in order to keep the effect observable alive
41-
})
42-
);
43-
})
44-
));
45-
46-
addTodo = this.effect((title$: Observable<string>) => title$.pipe(
47-
concatMap(todoTitle => this.todosService.add(todoTitle).pipe(
48-
tap(todo => {
49-
const todos = this.get(s => s.data);
50-
todos.unshift(todo);
51-
this.patchState({ data: [ ...todos ] })
52-
}),
53-
catchError(error => {
54-
console.error('Cannot add todo with title: ' + todoTitle, error);
55-
return EMPTY;
56-
})
57-
))
58-
));
59-
60-
updateTodo = this.effect((todo$: Observable<Todo>) => todo$.pipe(
61-
concatMap(todo => this.todosService.toggle(todo).pipe(
62-
tap(todo => {
63-
const todos = this.get(s => s.data);
64-
this.patchState({
65-
// data: todos.map(x => x.id === todo.id ? { ...x, ...todo } : x)
66-
// in order to not loose the reference of the item and reanimate the enter transition
67-
// we dont change the reference of the item but only the needed key
68-
data: todos.map(item => {
69-
if (item.id === todo.id) {
70-
item.completed = todo.completed;
71-
}
72-
return item;
73-
})
74-
})
75-
}),
76-
catchError(error => {
77-
console.error('Cannot update todo with ID: ' + todo.id, error);
78-
return EMPTY;
79-
})
80-
))
81-
));
82-
83-
removeTodo = this.effect((todoId$: Observable<number>) => todoId$.pipe(
84-
concatMap(todoId => this.todosService.remove(todoId).pipe(
85-
tap(todoId => {
86-
const todos = this.get(s => s.data);
87-
this.patchState({
88-
data: todos.filter(x => x.id !== todoId)
89-
})
90-
}),
91-
catchError(error => {
92-
console.error('Cannot delete todo with ID: ' + todoId, error);
93-
return EMPTY;
94-
})
95-
))
96-
));
97-
98-
}
99-
100-
```
101-
102-
103-
104-
#### Todos component
105-
```html
106-
<ng-container *ngIf="store.state$ | async as vm">
107-
108-
<todos-filter
109-
(filtered)="store.loadTodos({ searchQuery: $event })">
110-
</todos-filter>
111-
112-
<todos-table
113-
[todos]="vm.data"
114-
[totalRows]="vm.total"
115-
[loading]="vm.loading"
116-
(pageChanged)="store.loadTodos($event)"
117-
(sorted)="store.loadTodos({ sort: $event })"
118-
(todoToggled)="store.updateTodo($event)"
119-
(todoRemoved)="store.removeTodo($event)">
120-
</todos-table>
121-
122-
<div *ngIf="vm.error">
123-
Error: {{ vm.error }}
124-
</div>
125-
126-
</ng-container>
127-
```
128-
129-
```ts
130-
@Component({
131-
selector: 'todos',
132-
template: `...`,
133-
changeDetection: ChangeDetectionStrategy.OnPush
134-
})
135-
export class TodosComponent implements OnInit {
136-
137-
constructor(public store: TodosStore) {}
138-
139-
ngOnInit() {
140-
this.store.loadTodos({ pageSize: 10, pageIndex: 1 });
141-
}
142-
143-
}
144-
```
12+
### Included state management libraries
13+
- RxState
14+
- NgRx Component-Store
14515

14616

14717
![image](https://user-images.githubusercontent.com/25394362/136675191-71680362-0e3e-4d09-91fd-103dd9dfd715.png)

0 commit comments

Comments
 (0)
Please sign in to comment.