Skip to content

All possible ways of firing a modal and controlling its visibility

Morgan Touverey Quilling edited this page Dec 28, 2020 · 2 revisions

In this guide we'll assume you are using the <swal> component, as the [swal] directive alone only offers one unique way for showing a modal. On the other hand, the <swal> component can cover more use cases concerning how and when you show up your modals.

[swal] directive

The simplest way to show a modal is to use both <swal> to declare the body of the modal, and the [swal] directive as a trigger on another element. When that element is clicked, and only on this condition, the modal will be fired.

<button [swal]="mySwal">Show modal</button>

<swal #mySwal title="Hello world!" text="How's the world going?" icon="question"></swal>

By calling SwalComponent.fire()

If you want to show up your modal in other circumstances than a click, then the [swal] directive won't be of any help. Use SwalComponent.fire() method instead (or keep reading through the section about [swalVisible]).

Given that you have such modal declared:

<swal #mySwal title="Hello world!" text="How's the world going?" icon="question"></swal>

In your HTML, you could use the #mySwal template reference, here we're showing the modal when an element is double-clicked:

<button (dblclick)="mySwal.fire()">Double click me</button>

If you wanted to call it from your TypeScript code instead, then you have to retrieve a reference to the modal through @ViewChild:

@Component({ /* ... */ })
export class MyComponent {
  @ViewChild('mySwal')
  public readonly mySwal!: SwalComponent;

  public async someOfYourMethods(): void {
    // just showing it
    this.mySwal.fire();

    // showing it and reading the result (see SweetAlertResult interface for the vailable properties in the return value)
    // however, consider using (confirm), (dimiss), etc. outputs instead
    const { isConfirmed, value, ...etc } = await this.mySwal.fire();
  }
}

Of course, there is a counterpart method to dimiss the modal, SwalComponent.close(result?). It can be passed an optional argument of type SweetAlertResult so you can still control how (confirm), (deny) or (dismiss) handlers are called. Also the promise returned by .fire() will resolve with that value.

By setting [swalVisible]

Do you like declarative and reactive patterns?

This input will help you controlling the visibility of your modal fully declaratively.

Simply put, setting swalVisible (either through HTML or TypeScript) to true will show your modal (if currently hidden), and setting it to false will immediately dismiss it (if currently shown).

This is an example where we are only setting a variable to true to show the modal (and resetting it to false when the modal is closed, no matter how):

<button (click)="isSwalVisible = true">Fire! by setting isSwalVisible = true</button>

<swal
  text="isSwalVisible = {{ isSwalVisible }}"
  [swalVisible]="isSwalVisible"
  (didClose)="isSwalVisible = false">
</swal>

Now this can be useful in many scenarios, for example, let's imagine that you'd like to show an error modal just by setting an error message to a currentError variable in your component:

<swal
  [title]="currentError"
  [swalVisible]="currentError != undefined"
  (didClose)="currentError = undefined">
</swal>

Isn't that elegant? No more modal manipulations in TypeScript, fully decoupled code!

By enabling [swalFireOnInit] srategy

This method is very similar to the [swalVisible] approach, but can serve slightly different use cases.

When you declare a <swal> component in your page, it will be immediately initialized (OnInit). However the modal visibility is controlled completely independently.

It is possible to ask that modals are immediately shown as soon as their controller <swal> component is instantiated.

This can be done at the modal level using the [swalFireOnInit] input, here is a complete example:

<button (click)="modalFireCondition = true">Fire! by setting modalFireCondition = true</button>

<swal
  *ngIf="modalFireCondition"
  text="modalFireCondition = {{ modalFireCondition }}"
  [swalFireOnInit]="true"
  (didClose)="modalFireCondition = false">
</swal>

Here we can see that the <swal> component's existence is conditioned by an ngIf directive. When the ngIf directive evaluates to true, the component is created, and the modal fires immediately as [swalFireOnInit] is true. When the modal is closed, the boolean is reset to false, allowing the modal to be opened again when the button is clicked again.

This setting can also be globally applied at module level, either in .forRoot() or .forChild():

@NgModule({
  imports: [
    SweetAlert2Module.forRoot({ fireOnInit: true })
  ]
})
export class AppModule {
}

Now, every modal created in this module will inherit the fire-on-init strategy as default. But it can still be overriden at modal level to disable it.

How to not hide a modal when <swal> is destroyed

You may notice that when a <swal> component is destroyed by Angular (by toggling an ngIf state, by navigating away to a different page when a modal is shown, etc), its modal is immediately terminated too if it was opened.

This is a configurable behaviour. It can be overriden either at modal level:

<swal [swalDismissOnDestroy]="false"></swal>

Or at module level (either with .forRoot() or .forChild()) if you want to set it for all modals at once:

@NgModule({
  imports: [
    SweetAlert2Module.forRoot({ dismissOnDestroy: false })
  ]
})
export class AppModule {
}

It can then still be overriden with <swal [swalDismissOnDestroy]> if you change your mind for an isolated modal.