Home > Net >  BehaviorSubject emits only initial value on other angular component
BehaviorSubject emits only initial value on other angular component

Time:10-15

I'm having a weird problem, I created a service to emit the value of the item clicked on the navbar, so I could fire a modal .

import { EventEmitter, Injectable } from "@angular/core";
import { BehaviorSubject, Subject } from "rxjs";
@Injectable({
    providedIn: 'root',
})
export class HeaderService {
modalShowObservable = new BehaviorSubject<string>('');

private modal$ = new BehaviorSubject<any>({});
selectedModal$ = this.modal$.asObservable();


changeModalDisplay(modal: string): void {
    this.modalShowObservable.next(modal)
    this.modal$.next(modal)
}

Both approaches works well for the component itself, and I can display on the screen the value emitted by BehaviorSubject, subscribing and assigning the value to a property in the component

But when I try to subscribe from another component I only get the initial value

ngOnInit(): void {
this.headerService.modalShowObservable.subscribe({ valor => {
    console.log("test") //runs when starting componet
    console.log(valor) // ''
})
  
  this.headerService.selectedModal$.subscribe(valor => {
    console.log("test") //runs when starting componet
    console.log(valor) //{}
})

}

I can't understand what's wrong, everything I've read seems to indicate doing it this way

Why can't I subscribe it from another component?

CodePudding user response:

I managed to find the problem, I provided the service inside the component in which it worked by the Components providers array, apparently this creates some bind, I'm not sure, I just removed the annotation and it worked correctly in others components

@Component({


 selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css'],
  //providers: [HeaderService]
})

CodePudding user response:

What is wrong is that your modalShowObservable variable is not an observable but a BehaviorSubject, if you want to transform it to an observable you would have to do the same as your have done for modal$ and selectedModal$ with this.modal$.asObservable(), this way you have allowed components that can access to HeaderService to subscribe to changes.

I have tried to reproduced what you want to do with a simple counter service shared across two components.

// in first.component.html
<button (click)="increaseCounter(counter)">Increase Count</button>

// in first.component.ts
increaseCounter() {
  this.counter = this.counter   1;
  this.headerService.setCounterValue(this.counter);
}

// in header.service.ts
private count$$ = new BehaviorSubject<number>(0);
count$ = this.count$$.asObservable();

setCounterValue(count: number): void {
  this.count$$.next(count);
}

// in second.component.html
<h1>Count = {{ counter }}</h1>

// in second.component.ts 
const sub = this.headerService.selectedModal$.subscribe((count) => {
  this.counter = count;
});
  • Related