0

I have a component that calls a REST api to get some infos. When this infos are ready, I need another component to use them. These components are siblings. To implement this, I'm using a service and subject.next to update the value. The other component needs to listen to changes. This is what I'm doing:

Component A:

    this.restService.getInfos().subscribe(i => {
        this.updatingService.profileLoadedEvent(i)
    });

Updating service:

    userInfo = new Subject<any>();
    
    public profileLoadedEvent(info: string) {
            this.userInfo.next(info);
    }

    public getProfileLoadedEvent(): Observable<string> {
        return this.userInfo.asObservable();

    }

Component B:

    this.updatingService.getProfileLoadedEvent().subscribe((info: string) => {
      this.doSomething(info);
    })

My problem is that component B never gets to doSomething(). Component A correctly calls userInfo.next but the

    return this.userInfo.asObservable();

is not called. Well, it's called only once before the profileLoadedEvent method is called by component A.
What am I doing wrong?

Chris Hamilton
  • 9,252
  • 1
  • 9
  • 26
User978438
  • 149
  • 1
  • 3
  • 13
  • 1
    Could you please check how your service gets injected? It need to be injected in root, so the singleton pattern is applied Otherwise you would have another subject. – Thomas Renger Jul 04 '22 at 15:08
  • @ThomasRenger the service has providedIn:root and is in AppModules' providers – User978438 Jul 04 '22 at 15:11
  • 1
    @MoM Everything looks good in your code, can you create a stackblitz? BTW If your service has `{providedIn: 'root'}` then you don't need to import it again in AppModules – Sameer Jul 04 '22 at 15:43
  • If the value is emitted before component B subscribes, then it will never receive the emission. with `Subject` late subscribers will not receive prior emissions. You can try using `ReplaySubject(1)` instead to see if this is your issue. – BizzyBob Jul 04 '22 at 19:14

2 Answers2

1

Your service is creating a new observable every time it calls the function, depending on the timing of sending something and the function call to get the Observable you will not receive anything. You can change it to:

@Injectable({
  providedIn: 'root'
})
export class updatingService {

  private: userInfo = new Subject<any>();
  userInfo$ = this.userInfo.asObservable();

  public profileLoadedEvent(info: string) {
        this.userInfo.next(info);
  }

  public getProfileLoadedEvent(): Observable<string> {
    return this.userInfo$;
  }
}
Charlie V
  • 980
  • 1
  • 6
  • 12
0

Try to use BehaviorSubject instead of Subject, I solved the same problem is this way.

import { BehaviorSubject } from 'rxjs';


userInfo: BehaviorSubject<any> = new BehaviorSubject({});

getUserInfo() {
  return this.userInfo.asObservable();
}

Component:

this.restService.getUserInfo().subscribe((info:any) => {
   this.doSomething(info);
});

Check this link to unterstand BehaviorSubject vs Observable?

ferhado
  • 2,363
  • 2
  • 12
  • 35