* This command creates several new files and updates `app.modules.ts` file to import the `NgxsModule` with the new state.
* This command creates `books.state.ts` and `books.actions.ts` files in the `src/app/books/state` folder. See the [NGXS CLI documentation](https://www.ngxs.io/plugins/cli).
#### Get books data from backend
Create data types to map the data from the backend (you can check Swagger UI or your backend API to see the data format).
Open the `books.ts` file in the `app\store\models` folder and replace the content as below:
Import the `BooksState` to the `app.module.ts` in the `src/app` folder and then add the `BooksState` to `forRoot` static method of `NgxsModule` as an array element of the first parameter of the method.
```js
export namespace Books {
export interface State {
books: Response;
}
// ...
import { BooksState } from './books/state/books.state'; //<== imported BooksState ==>
* Added `Book` interface that represents a book object and `BookType` enum which represents a book category.
#### Generate proxies
#### BooksService
ABP CLI provides `generate-proxy` command that generates client proxies for your HTTP APIs to make easy to consume your services from the client side. Before running generate-proxy command, your host must be up and running. See the [CLI documentation](../CLI.md)
Create a new service, named `BooksService` to perform `HTTP` calls to the server:
Run the following command in the `angular` folder:
* We added the `get` method to get the list of books by performing an HTTP request to the related endpoint.
Actions can either be thought of as a command which should trigger something to happen, or as the resulting event of something that has already happened. [See NGXS Actions documentation](https://www.ngxs.io/concepts/actions).
Open the`books.actions.ts` file in `app\store\actions` folder and replace the content below:
Open the `books.actions.ts` file in `app/books/state` folder and replace the content below:
```js
export class GetBooks {
@ -974,43 +931,48 @@ export class GetBooks {
#### Implement BooksState
Open the `books.state.ts` file in `app\store\states` folder and replace the content below:
Open the `books.state.ts` file in `app/books/state` folder and replace the content below:
```js
import { PagedResultDto } from '@abp/ng.core';
import { State, Action, StateContext, Selector } from '@ngxs/store';
import { GetBooks } from '../actions/books.actions';
import { Books } from '../models/books';
import { BooksService } from '../../books/shared/books.service';
import { GetBooks } from './books.actions';
import { BookService } from '../../app/shared/services';
import { tap } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { BookDto } from '../../app/shared/models';
- We added the `create` method to perform an HTTP Post request to the server.
- `restService.request` function gets generic parameters for the types sent to and received from the server. This example sends a `CreateUpdateBookInput` object and receives a `Book` object (you can set `void` for request or return type if not used).
#### State definitions
Open `books.action.ts` in `app\store\actions` folder and replace the content as below:
Open `books.action.ts` in `books\state` folder and replace the content as below:
```js
import { Books } from '../models'; //<== added this line ==>
import { CreateUpdateBookDto } from '../../app/shared/models'; //<== added this line ==>
export class GetBooks {
static readonly type = '[Books] Get';
}
//added CreateUpdateBook class
// added CreateUpdateBook class
export class CreateUpdateBook {
static readonly type = '[Books] Create Update Book';
@ -791,7 +710,7 @@ export class BookListComponent implements OnInit {
this.isModalOpen = true;
}
//added buildForm method
//added buildForm method
buildForm() {
this.form = this.fb.group({
name: ['', Validators.required],
@ -804,6 +723,7 @@ export class BookListComponent implements OnInit {
```
* We imported `FormGroup, FormBuilder and Validators`.
* We added `form: FormGroup` variable.
* We injected `fb: FormBuilder` service to the constructor. The [FormBuilder](https://angular.io/api/forms/FormBuilder) service provides convenient methods for generating controls. It reduces the amount of boilerplate needed to build complex forms.
* We added `buildForm` method to the end of the file and executed `buildForm()` in the `createBook` method. This method creates a reactive form to be able to create a new book.
* The `group` method of `FormBuilder`, `fb` creates a `FormGroup`.
@ -880,35 +800,34 @@ export class BooksModule { }
* We imported `NgbDatepickerModule` to be able to use the date picker.
Open `book-list.component.ts` file in `app\books\book-list` folder and replace the content as below:
```js
import { Component, OnInit } from '@angular/core';
import { Store, Select } from '@ngxs/store';
import { BooksState } from '../../store/states';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { Books } from '../../store/models';
import { GetBooks } from '../../store/actions';
import { finalize } from 'rxjs/operators';
import { BookDto, BookType } from '../../app/shared/models';
import { GetBooks } from '../state/books.actions';
import { BooksState } from '../state/books.state';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; //<== added this line ==>
import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; //<== added this line ==>
@Component({
selector: 'app-book-list',
templateUrl: './book-list.component.html',
styleUrls: ['./book-list.component.scss'],
providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }] //<== added this line ==>
providers: [{ provide: NgbDateAdapter, useClass: NgbDateNativeAdapter }], //<== added this line ==>
})
export class BookListComponent implements OnInit {
Open `book-list.component.ts` in `app\books\book-list` folder and inject `BooksService` dependency by adding it to the constructor and add a variable named `selectedBook`.
Open `book-list.component.ts` in `app\books\book-list` folder and inject `BookService` dependency by adding it to the constructor and add a variable named `selectedBook`.
```js
import { Component, OnInit } from '@angular/core';
import { Store, Select } from '@ngxs/store';
import { BooksState } from '../../store/states';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { Books } from '../../store/models';
import { GetBooks, CreateUpdateBook } from '../../store/actions';
import { finalize } from 'rxjs/operators';
import { BookDto, BookType } from '../../app/shared/models';
import { GetBooks, CreateUpdateBook } from '../state/books.actions';
import { BooksState } from '../state/books.state';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap';
import { BooksService } from '../shared/books.service'; //<== imported BooksService ==>
import { BookService } from '../../app/shared/services'; //<== imported BookService ==>
The `delete` method shows a confirmation popup and subscribes for the user response. `DeleteBook` action dispatched only if user clicks to the `Yes` button. The confirmation popup looks like below:
You can use the `ConfirmationService` in @abp/ng.theme.shared package to display a confirmation popup by placing at the root level in your project.
## Getting Started
You do not have to provide the `ConfirmationService` at module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components, directives, or services.
```js
import { ConfirmationService } from '@abp/ng.theme.shared';
- The `ConfirmationService` methods accept three parameters that are `message`, `title`, and `options`.
- `success`, `warn`, `error`, and `info` methods return an [RxJS Subject](https://rxjs-dev.firebaseapp.com/guide/subject) to listen to confirmation popup closing event. The type of event value is [`Confirmation.Status`](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/theme-shared/src/lib/models/confirmation.ts#L24) that is an enum.
### How to Listen Closing Event
You can subscribe to the confirmation closing event like below:
```js
import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
.warn('::WillBeDeleted', { key: '::AreYouSure', defaultValue: 'Are you sure?' })
.subscribe((status: Confirmation.Status) => {
// your code here
});
```
- The `message` and `title` parameters accept a string, localization key or localization object. See the [localization document](./Localization.md)
- `Confirmation.Status` is an enum and has three properties;
- `Confirmation.Status.confirm` is a closing event value that will be emitted when the popup is closed by the confirm button.
- `Confirmation.Status.reject` is a closing event value that will be emitted when the popup is closed by the cancel button.
- `Confirmation.Status.dismiss` is a closing event value that will be emitted when the popup is closed by pressing the escape.
If you are not interested in the confirmation status, you do not have to subscribe to the returned observable:
```js
this.confirmation.error('You are not authorized.', 'Error');
```
### How to Display a Confirmation Popup With Given Options
Options can be passed as the third parameter to `success`, `warn`, `error`, and `info` methods:
```js
const options: Partial<Confirmation.Options> = {
hideCancelBtn: false,
hideYesBtn: false,
cancelText: 'Close',
yesText: 'Confirm',
messageLocalizationParams: ['Demo'],
titleLocalizationParams: [],
};
this.confirmation.warn(
'AbpIdentity::RoleDeletionConfirmationMessage',
'Are you sure?',
options,
);
```
- `hideCancelBtn` option hides the cancellation button when `true`. Default value is `false`
- `hideYesBtn` option hides the confirmation button when `true`. Default value is `false`
- `cancelText` is the text of the cancellation button. A localization key or localization object can be passed. Default value is `AbpUi::Cancel`
- `yesText` is the text of the confirmation button. A localization key or localization object can be passed. Default value is `AbpUi::Yes`
- `messageLocalizationParams` is the interpolation parameters for the localization of the message.
- `titleLocalizationParams` is the interpolation parameters for the localization of the title.
With the options above, the confirmation popup looks like this:

### How to Remove a Confirmation Popup
The open confirmation popup can be removed manually via the `clear` method:
```js
this.confirmation.clear();
```
## API
### success
```js
success(
message: Config.LocalizationParam,
title: Config.LocalizationParam,
options?: Partial<Confirmation.Options>,
): Observable<Confirmation.Status>
```
> See the [`Config.LocalizationParam` type](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/core/src/lib/models/config.ts#L46) and [`Confirmation` namespace](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/theme-shared/src/lib/models/confirmation.ts)
You can use the `ToasterService` in @abp/ng.theme.shared package to display messages in an overlay by placing at the root level in your project.
## Getting Started
You do not have to provide the `ToasterService` at module or component level, because it is already **provided in root**. You can inject and start using it immediately in your components, directives, or services.
```js
import { ToasterService } from '@abp/ng.theme.shared';
@Component({
/* class metadata here */
})
class DemoComponent {
constructor(private toaster: ToasterService) {}
}
```
## Usage
You can use the `success`, `warn`, `error`, and `info` methods of `ToasterService` to display an overlay.
### How to Display a Toast Overlay
```js
this.toast.success('Message', 'Title');
```
- The `ToasterService` methods accept three parameters that are `message`, `title`, and `options`.
- `success`, `warn`, `error`, and `info` methods return the id of opened toast overlay. The toast can be removed with this id.
### How to Display a Toast Overlay With Given Options
Options can be passed as the third parameter to `success`, `warn`, `error`, and `info` methods:
```js
import { Toaster, ToasterService } from '@abp/ng.theme.shared';
The all open toasts can be removed manually via the `clear` method:
```js
this.toast.clear();
```
## API
### success
```js
success(
message: Config.LocalizationParam,
title: Config.LocalizationParam,
options?: Partial<Toaster.ToastOptions>,
): number
```
- `Config` namespace can be imported from `@abp/ng.core`.
- `Toaster` namespace can be imported from `@abp/ng.theme.shared`.
> See the [`Config.LocalizationParam` type](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/core/src/lib/models/config.ts#L46) and [`Toaster` namespace](https://github.com/abpframework/abp/blob/master/npm/ng-packs/packages/theme-shared/src/lib/models/toaster.ts)