DarioN1
DarioN1

Reputation: 2552

Angular2 - Subscribe not firing

I'm trying to implement a shared service in order to share information between components.

In this moment, the subscribe doesn't work and I don't know why...

This is the service:

service

private subject = new Subject<any>();

getCurrentUser(): Observable<any> 
    {

        this.subject.next({data:"test"});
        return this.subject.asObservable();
    }

component

subscription: Subscription;

ngOnInit() {


    this.subscription = this.authService.getCurrentUser().subscribe(data => { 

      this.message = data;
      alert('I called the method');

    });    
  }

In this moment the execution didn't go inside the procedure that set the message and do the alert...

Thanks to support

Upvotes: 0

Views: 5620

Answers (3)

jLee
jLee

Reputation: 483

In your example/test try changing the Subject to a BehaviorSubject

private subject = new BehaviorSubject<any>({date: "test"});

then change your getCurrentUser to

getCurrentUser(): Observable<any> {
   return this.subject.asObservable();
}

One big difference between a subject and behaviorSubject is that you have to provide a start value for the behaviorSubject, and it also emits the current value to you when you subscribe to it. A Subject will not emit its last set value to you when you subscribe, it will only start "watching" at the point you subscribe and pick up on subsequent changes.

Upvotes: 2

Robin Dijkhof
Robin Dijkhof

Reputation: 19278

Your subject emits the value before you are subscribing. That's is how a subject works. You could use a BehaviorSubject. A BehanvoirSubject re-sends the value, but takes a default value:

private subject = new BehaviorSubject<any>(undefined);

If that's is not what you want you could use a map:

return this.subject.asObservable().map(value => !isNullOrUndefined(value))

Upvotes: 1

Supamiu
Supamiu

Reputation: 8731

That's because you don't use the Observable the way it's meant to be used, an Observable is basically a data stream, and you're emitting the data before you subscribe to the stream.

private subject = new Subject<any>();

getUserObservable(): Observable<any> 
{
    return this.subject.asObservable();
}

setUser(user:any):void{
    this.subject.next(user);
}

In your tests:

subscription: Subscription;

  ngOnInit() {
    this.subscription = this.authService.getCurrentUserObservable().subscribe(data => { 
      this.message = data;
      alert('I called the method');
    });
    // The subscription will be called right here.
    this.authService.setUser({data:"test"});
  }

Then, if you call setUser from another component, service or whatever, your subscription will be called.

Upvotes: 4

Related Questions