AskYous
AskYous

Reputation: 4730

Nested Angular Subscriptions not Firing

I have 3 subscriptions I need to subscribe to. But when I run it, only 1 or 2 of them fire out of 3. I even tried swapping the order of the subscriptions and the last one still doesn't get fired. I also tried running these in the constructor of my angular component and in ngOnInit(). I get the same response.

Attempt 1:

this.n.authorizations.subscribe(x => {
    alert("1"); // ✅
    this.n.pages.subscribe(y => {
        alert("2"); // ❌
        this.n.user.subscribe(user => {
            alert("3"); // ❌
        });
    });
});

Attempt 2:

this.n.pages.subscribe(y => {
    alert("1"); // ✅
    this.n.authorizations.subscribe(x => {
        alert("2"); // ✅
        this.n.user.subscribe(user => {
            alert("3"); // ❌
        });
    });
});

Attempt 3:

this.n.user.subscribe(user => {
    alert("1"); // ✅
    this.n.authorizations.subscribe(x => {
        alert("2"); // ✅
        this.n.pages.subscribe(y => {
            alert("3"); // ❌
        });
    });
});

I do have the code for these services, but they're long and complicated. Probably not related to the problem.

Upvotes: 4

Views: 604

Answers (3)

AskYous
AskYous

Reputation: 4730

I figured out the problem (kind of). On the first attempt, the subscription to pages occured after the pages observable resolved. So I changed the return object in that service function to a ReplaySubject instead of a Subject, which causes late subscribers to get the most recent value emitted. I don't know how all this happened but this resolved my problem. It doesn't make sense though.

Edit: As another user suggested, BehaviorSubject would be better in this case.

Upvotes: 1

Ian MacDonald
Ian MacDonald

Reputation: 14030

It looks to me like you are chaining things that shouldn't be chained.

this.n.user.subscribe(user => {
    alert("1");
});
this.n.authorizations.subscribe(x => {
    alert("2");
});
this.n.pages.subscribe(y => {
    alert("3");
});

When you subscribe like you have, your inner subscriptions aren't even attached until your outer subscriptions receive their first value.

Upvotes: 0

SiddAjmera
SiddAjmera

Reputation: 39432

Judging from the approaches you're following, looks like any subscription doesn't depend on the other subscriptions.

So in that case, why not forkJoin them and then subscribe to the joined Observable.

import { forkJoin } from 'rxjs';
...
const combined = forkJoin(
  this.n.user,
  this.n.authorizations,
  this.n.pages
);
...
combined.subscribe(
  [user, auths, pages] => console.log(user, auths, pages),
  error => console.log(error),
  () => console.log('Combined Completed')
);

Upvotes: 1

Related Questions