Rxjs Subscription does not work in a Angular Directive

Sam

Consider the following code :

  @Component({
  selector: 'cdt-angular-loader',
  templateUrl: 'loader.component.html',
  styleUrls: ['loader.component.scss']
})
export class LoaderComponent implements OnInit, OnDestroy {

  public show = false;
  private subscription: Subscription;

  constructor(private _loaderService: LoaderService) {
  }

  ngOnInit() {
    // subscribe to the service state to hide/show the loader
    this.subscription = this._loaderService.loaderState
      .subscribe((state: LoaderState) => {
        this.show = state.show;
      });
  }

  ngOnDestroy() {
    // unsubscribe
    this.subscription.unsubscribe();
  }
}

The subscription works as expected and the subscribe is raised whenever the loaderService calls next().

However if I use the same code in a Directive instead of a Component, the subscribe is never raised :

@Directive({
  selector: '[cdtSaving]'
})
export class SavingDirective implements OnInit, OnDestroy {

  private subscription: Subscription;

  constructor(private _loaderService: LoaderService, private _elRef: ElementRef, private _renderer: Renderer) { }

  ngOnInit() {
   // this._renderer.setElementAttribute(this._elRef.nativeElement, 'disabled', 'true');
    // subscribe to the service state to hide/show the loader
    this.subscription = this._loaderService.loaderState
      .subscribe((state: LoaderState) => {
        alert('state changed:' + state.show);
      });
  }

  ngOnDestroy() {
    // unsubscribe
    this.subscription.unsubscribe();
  }
}

ngOnInit is called and the subscription is created but the subscribe is never called, although it is in the Component.

Is it not supposed to work the same way with Directives ?

[EDIT]

Following @Vikas' comment, I have changed my LoaderService to use BehaviorSubject instead of Subject. Now the subscribe gets called the very first time the directive is loaded. But whenever the service does a next(), the subscribe does not get called. I'm not sure why... Here's the code of the loaderService for what it's worth....

@Injectable()
export class LoaderService {
  private loaderSubject = new BehaviorSubject<LoaderState>({ show: false});

  public loaderState = this.loaderSubject.asObservable();

  constructor() { }

  show() {
    this.loaderSubject.next(<LoaderState>{ show: true });
  }

  hide() {
    this.loaderSubject.next(<LoaderState>{ show: false });
  }
}
Sam

I have noticed that, as long as I use the directive in a top-level module, my code works absolutely fine, even with the directive. If I use it in a lazy-loaded module, it does not work.

This is strange because the service is provided to the lazy-loaded module, so in theory this should work. Any idea why this occur ?

[EDIT]
ANSWER see Lazy loading : Observable not subscribed

It turned out that subscriber does not work well with lazy-loaded modules. I had to move up my service to the app module. Now it works.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related