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;
});