diff --git a/docs/en/framework/ui/angular/images/list-service-request-status.gif b/docs/en/framework/ui/angular/images/list-service-request-status.gif new file mode 100644 index 00000000000..a387258d0ac Binary files /dev/null and b/docs/en/framework/ui/angular/images/list-service-request-status.gif differ diff --git a/docs/en/framework/ui/angular/list-service.md b/docs/en/framework/ui/angular/list-service.md index 8df8b945d7d..e7aeb7e36e3 100644 --- a/docs/en/framework/ui/angular/list-service.md +++ b/docs/en/framework/ui/angular/list-service.md @@ -139,37 +139,86 @@ You may use observables in combination with [AsyncPipe](https://angular.io/guide ``` -...or... +## Handle request status +To handle the request status `ListService` provides a `requestStatus$` observable. This observable emits the current status of a request, which can be one of the following values: `idle`, `loading`, `success` or `error`. These statuses allow you to easily manage the UI flow based on the request's state. +![RequestStatus](./images/list-service-request-status.gif) ```js - @Select(BookState.getBooks) - books$: Observable; +import { ListService } from '@abp/ng.core'; +import { AsyncPipe } from '@angular/common'; +import { Component, inject } from '@angular/core'; +import { BookDto, BooksService } from './books.service'; - @Select(BookState.getBookCount) - bookCount$: Observable; +@Component({ + standalone: true, + selector: 'app-books', + templateUrl: './books.component.html', + providers: [ListService, BooksService], + imports: [AsyncPipe], +}) +export class BooksComponent { + list = inject(ListService); + booksService = inject(BooksService); - ngOnInit() { - this.list.hookToQuery((query) => this.store.dispatch(new GetBooks(query))).subscribe(); + items = new Array(); + count = 0; + + //It's an observable variable + requestStatus$ = this.list.requestStatus$; + + ngOnInit(): void { + this.list + .hookToQuery(() => this.booksService.getList()) + .subscribe(response => { + this.items = response.items; + this.count = response.totalCount; + }); } +} ``` ```html - - - - - +
+
+ @if (requestStatus$ | async; as status) { + @switch (status) { + @case ('loading') { +
+
+ Loading... +
+
+ } + @case ('error') { +

Error occured

+ } + @default { +

Books

+ } + } + } +
+ + + + + + + + + + @for (book of items; track book.id) { + + + + + } + +
IdName
{{ book.id }}{{ book.name }}
+
``` -> We do not recommend using the NGXS store for CRUD pages unless your application needs to share list information between components or use it later on in another page. - - ## How to Refresh Table on Create/Update/Delete `ListService` exposes a `get` method to trigger a request with the current query. So, basically, whenever a create, update, or delete action resolves, you can call `this.list.get();` and it will call hooked stream creator again. @@ -183,15 +232,6 @@ You may use observables in combination with [AsyncPipe](https://angular.io/guide }); ``` -...or... - -```js - this.store.dispatch(new DeleteBook(id)).subscribe(this.list.get); -``` - -> We do not recommend using the NGXS store for CRUD pages unless your application needs to share list information between components or use it later on in another page. - - ## How to Implement Server-Side Search in a Table `ListService` exposes a `filter` property that will trigger a request with the current query and the given search string. All you need to do is to bind it to an input element with two-way binding.