Home > database >  Dont return value with observable, from the service layer to the component
Dont return value with observable, from the service layer to the component

Time:11-05

I'm trying to pass the return of a service layer with subject to the components.

My service that connects with api:

 public getPerfilNew$(): Observable<PerfilInvestidor> {
            return this.http.get<PerfilInvestidor>(`${environment.api.basePosicaoConsolidada}/consolidado`)
              .pipe(
                map(res => res),
                shareReplay(1),
                catchError(err => {
                    console.log('Error in perfil', err);
                    return throwError(err);
                })
            )
        }

Layer responsible for logic, I use it when several components depend on this information:

perfilFailed$ = this.api.getPerfilNew$().pipe(
    map(perfil => {
      this.perfilInvestidor = perfil
      this.perfilFailed = this.perfilInvestidor.status ? true : false;
    })
  )

In my component: I tried it in two ways:

 public loadData() {
            this.coreState.perfilCliente$.subscribe(res => {
        console.log(res)
    })
    }

enter image description here

Several components need to know if the this.perfilFailed is false or true, so I don’t want to do this in the component but in the core-state service

With that amount of observables I compromise the memory? I'm open to suggestions

CodePudding user response:

1. Questions

There is no enough code here to see exactly what is happening. But at first glance it looks like a race condition from my point of view:

You have to realise how Subject works.

const sub = new Subject();
sub.next(1);

// If you subscribe here like:
   sub.subscribe(a => console.log(a))
// Nothing will happen because Subject does not preserve the old values

But if you do this:

const sub = new Subject();

// If you subscribe here like:
sub.subscribe(a => console.log(a))

sub.next(1);

// You will get a print in a console since you emitted the value after you subscribed on the stream.

In your case it looks like that you are subscribing to a subject after subject already emitted values.

Also:

 this.perfilClient$.subscribe(res => {

You are subscribing to this.perfilClient$, but i dont see where you are emitting values on that stream?

So if you cannot sync things that you subscribe to the Subject before it emits the value, you can use ReplaySubject or BehaviourSubject

2. Questions You have just a few observables, its not much. But there are are some antipatterns such as:

  1. Nesting subscribing
  2. Subscribe callback function is empty etc..

The main thing in RXJs is to avoid side effects as much as possible.

CodePudding user response:

I don't know what this.perfilClient$ is that you are using in your getPerfilFailed(), but I don't see why you couldn't do everything needed and assign it to an observable directly? So something like this in your service:

constructor(private api: HomeGuardService....) { }

perfilFailed$ = this.api.getPerfilNew$().pipe(
  map(perfil => perfil.status)
);

Then you can subscribe to perfilFailed$ variable in your components.

Like...

public loadData() {
  this.coreState.perfilFailed$.subscribe(res => {
    console.log(res)
  })
}

Remember to unsubscribe!

  • Related