NGXS loading spinners and actions executing
Tags: angular, ngxs, loading, spinners
Published: 2019-10-30 13:59:20

---
title: NGXS loading spinners and actions executing
published: true
description: Did you ever need to show a spinner while an action was being executed? Or disable a button? If you use Ngxs as your State Management library now it's super easy. Follow this quick tutorial to implement it.
tags: #angular #ngxs #loading #spinners
---

In our web-apps, we deal with async communication to our servers every day, and in order to give our users a better UX we usually display spinners or disable certain pieces of UI while an operation is being executed.

Although this is a very common feature to build, it is never as trivial as one may think so.

If you are using NGXS as your state management library, now you can use a new plugin to know when an action is being executed and control UI elements accordingly.

## Async actions

One of the nice things about NGXS is that supports async actions (observables or promises) out of the box, and you can easily implement them like this:

```typescript
@Action(MyAction)
myAction(ctx: StateContext<StateModel>){
  // ... asyncMethod
  return this.service.get();
}

```

Now, if we want to display a loading spinner, the preferred way to implement this is to use a `loading` property in the state, and set it true when the action is executed, and set it false once the async method returns the response.

```typescript
@Action(MyAction)
myAction(ctx: StateContext<StateModel>){
  // ... asyncMethod
  ctx.patchState({loading: true});
  return this.service.get().pipe(
    tap(response => {
      //...
      ctx.patchState({loading: false});
    })
  );
}
```

## New @ngxs-labs/actions-executing plugin

`actions-executing` is a new plugin that provides the state of an action being executed. It works by leveraging the actions lifecycle from the `Actions` stream class, and provides a very easy way to know when an action is being executed.

So, instead of manually setting loading to true or false, we just select the action we can to listen to via `@Select`

```typescript
@Select(actionsExecuting([MyAction])) myActionIsExecuting$;
```

and we can use it on our templates like this:

```html
<span *ngIf="myActionIsExecuting$ | async">
  Loading...
</span>
```

## How to use it

First we need to install the package:

```bash
npm install --save @ngxs-labs/actions-executing
```

Then, we import it in our module:

```typescript
//...
import { NgxsModule } from '@ngxs/store';
import { NgxsActionsExecutingModule } from '@ngxs-labs/actions-executing';

@NgModule({
    //...
    imports: [
        //...
        NgxsModule.forRoot([
          //... your states
        ]),
        NgxsActionsExecutingModule.forRoot(),
    ],
    //...
})
export class AppModule { }
```

Finally, as shown before, we just call `@Select` on the actions we want to listen, and bind it to our template, i.e.:

```typescript
//...
import { actionsExecuting, ActionsExecuting } from '@ngxs-labs/actions-executing';

//...
export class SingleComponent {

  @Select(actionsExecuting([MyAction])) myActionIsExecuting$: Observable<ActionsExecuting>;

}
```

```html
<button [disabled]="myActionIsExecuting$ | async"
        (click)="doSomething()">
  My Action
</button>

<span *ngIf="myActionIsExecuting$ | async">
  Loading...
</span>
```

If you want to see `@ngxs-labs/actions-executing`  you can check out a demo [here](https://relaxed-wright-ebefdf.netlify.com/single)

---

Hope you enjoyed this post, and if you did, please show some ❤️. I often write about Angular, Firebase and Google Cloud platform services. If you’re interested on more content, you can follow me on [dev.to](https://dev.to/joaqcid), [medium](https://medium.com/@joaqcid) and [twitter](https://twitter.com/joaqcid).