Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

angular 2 rxjs subscribe to observable code not executing

I have an angular app using rxjs to subscribe to an observable which is instantiated from a subject.

below is my app.service.ts

private subjectGreeting: Subject<Greeting>;  //Subject declared
resGreeting: Observable<Greeting>;  //Observable declared

authenticate(credentials, callback) {
const headers = new HttpHeaders({ Authorization : 'Basic ' + btoa(credentials.username + ':' + credentials.password)
});

return this.http.get<Greeting>('http://localhost:8080/user', {headers},).subscribe(response => {
    console.log('Inside app service authenticate');
    if (response) {
        this.subjectGreeting = new Subject(); //subjectGreeting being instantiated
        this.resGreeting = this.subjectGreeting.asObservable();  //resGreeting being assigned asObservable()

        this.subjectGreeting.next(response);   //next response being assigned to subjectGreeting
    } 
    callback();
});

On the component side, I have a login component which calls the authenticate function from above service:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

following is the component code:

    login() {
    console.log('inside login');
    this.app.authenticate(this.credentials, () => {
      this.app.authenticated = true;
      this.childComponent.refreshFromParent();  //refresh child component (do a subscription after authentication)
      // Redirect the user
      this.router.navigate(['../home']);
    } );
    
    return false;
  }

the login() function also calls the refreshFromParent() as below:

  refreshFromParent(): void{
    console.log('home component refresh from parent'); 
    if(this.app.resGreeting){
      this.subscriptionGreeting = this.app.resGreeting.subscribe(r => { ***//This subscription code is not executing despite the fact that it is being called after authentication***
        console.log('inside greeting subscription');
        if(r){
          this.greeting = r;
          this.authenticated = true;
        }
      });
    }
  }

finally, component’s html is as below:

<a routerLink="./" routerLinkActive="active"
    [routerLinkActiveOptions]="{ exact: true }">Welcome Home!</a>
<div [hidden]="(authenticated)">
    <p *ngIf="greeting">The ID is {{greeting.id}}</p>
    <p *ngIf="greeting">The content is {{greeting.content}}</p>
</div>
<div [hidden]="!(authenticated)">
    <p>Login to see your greeting</p>
</div>

<router-outlet></router-outlet>

for some reason, I am not getting any output {{greeting.id}} and {{greeding.content}}

>Solution :

Use a BehaviorSubject instead of a Subject.

private subjectGreeting: BehaviorSubject<Greeting> = new BehaviorSubject<Greeting>(null);
resGreeting: Observable<Greeting> = this.subjectGreeting.asObservable();

A subscription to a Subject will receive the next value after the subscription. So if you subscribe to a Subject after this.subjectGreeting.next(..) is called, the subscription wont run to next is called again since you subscribed after.

By switching to a BehaviorSubject you always get the latest when subscribing.

https://devsuhas.com/2019/12/09/difference-between-subject-and-behaviour-subject-in-rxjs/

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading