abrahamlinkedin abrahamlinkedin - 1 month ago 17
AngularJS Question

Using subjects in Angular 2

My main.service.ts

@Injectable()
export class AppService{
private mainSource = new Subject<boolean>();
main$ = this.mainSource.asObservable();
}


My app.component.ts

constructor(private appService: AppService){
this.appService.main$.subscribe(
working => {this.appService.main$(false);}
}

ngOnInit(){
if (this.appService.main$){alert("Tio");}
}


My app.component returns a
Cannot invoke an expression whose type lacks a call signature
error. And my OnInit alert fires regardless of whether or not the conditions have actually been met. In this case they have not.

Subscriptions are still quite foreign to me, so I'm not clear on exactly what I should be doing here. I want to set my
main$
to an initial value of false. And when my page is loaded, I would like it to alert only if it is true.

Answer

If you want to change values on a Subject it is best to create a seperate method for that. In this case I added a setWorking method to change the Subjects boolean value.

Next, the component subscribes to the Subject (which is returned as an Observable) and listens to changes to the value.

If the value changes, the callback function inside the subscribe block will be invoked.

Service

@Injectable()
export class AppService{
  private mainSource = new Subject<boolean>();
  main$ = this.mainSource.asObservable();

  setWorking(isWorking: boolean) {
    this.mainSource.next(isWorking);
  }
}

Component

private subscription: Subscription

constructor(private appService: AppService){ }

ngOnInit(){

  this.appService.setWorking(false);

  this.subscription = this.appService.main$.subscribe(isWorking => {
    if (isWorking) { alert("Tio"); }
  }
}

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

At last, you could add a this.appService.setWorking(true); function call after the subscription, to have the alert show up.

PS: I have added the ngOnDestroy part, since the subscription is not automatically cleared when navigating away and thus would create a memory leak. You need to import Subscription from rxjs/Subscription

Comments