Search code examples
npmofflineangular-directiveangular11

How can I access ngOffline directive in a component instead of html


I'm using this npm library https://www.npmjs.com/package/ng-offline to alert end user when offline.

<div class="alert alert-danger" ngOffline>You're offline. Check your connection!</div>

stackblitz here: https://stackblitz.com/edit/angular-ngoffline-npm?file=src%2Fapp%2Fapp.component.html

Works great - BUT I want to open a modal with this ngOffline directive, so I'm trying to access the directive from my angular 11 component but not sure how to approach this, any help on this would be greatly appreciated.

Is there away for me to open a ngx-bootstrap modal from the html with this directive?


Solution

  • Because the ng-offline module isn't exporting things as you might expect (i.e. you can't inject a standalone NgOfflineDirective for you to use without having it in your html file), you could add a block like this (where you've used #trigger to identify your ngOnline element):

    import { AfterContentChecked, Component, ElementRef, OnDestroy, ViewChild } from '@angular/core';
    import { BehaviorSubject, Subscription } from 'rxjs';
    import { distinctUntilChanged, filter } from 'rxjs/operators';
    
    @Component({ ... })
    export class YourClass implements AfterContentChecked, OnDestroy {
      offline$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>();
      subscription: Subscription;
    
      @ViewChild('trigger') trigger: ElementRef;
    
      constructor() {
        this.subscription = this.offline$.pipe(
          distinctUntilChanged(),
          filter((offline: boolean) => offline),
        ).subscribe(() => this.showModal());
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    
      ngAfterContentChecked() {
        if (
          this.trigger &&
          this.trigger.nativeElement
        ) {
          this.offline$.next(this.trigger.nativeElement.style.display === "none");
        }
      }
    
      showModal() {
        console.log('Show your modal here.');
      }
    }