Reputation: 253
I have a component "checklist" and a component "checklist-item". The checklist component creates checklist-items via ng-for. I additionally have a menu component with a button, which is supposed to change the layout of my checklist items. I therefore have a message service with a subject, such that both can communicate with each other.
Checklist component (HTML):
<div class="checklist-wrapper">
<div *ngFor="let listItem of listItems; let i = index">
<app-checklist-item [item]="listItem" [index]="i"></app-checklist-item>
</div>
</div>
Message Service:
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MessageService {
private gridOn$ = new Subject<boolean>();
constructor() { }
onSendGridOn(gridOn: boolean) {
this.gridOn$.next(gridOn);
}
getGridOn(): Observable<boolean> {
return this.gridOn$.asObservable();
}
}
Menu Component (TS):
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../services/message.service';
@Component({
selector: 'app-menu',
templateUrl: './menu.component.html',
styleUrls: ['./menu.component.css']
})
export class MenuComponent implements OnInit {
gridOn = false;
constructor(private messageService: MessageService) { }
ngOnInit() {
}
onToggleGridMode(){
this.gridOn = !this.gridOn;
this.messageService.onSendGridOn(this.gridOn);
}
}
Checklist-item component (TS):
constructor(private messageService: MessageService) {
this.subscription = this.messageService.getGridOn().subscribe( () => console.log("works"));
}
I also have a header component. In the header component, the subscription works fine. But for the checklist-item component and the checklist component, the subscription is not doing anything. If i use a Behavior Subject instead, it works once on initialization, but not afterwards.
Upvotes: 0
Views: 624
Reputation: 253
The problem seems to be with Visual Studio Code. When I added my MessageService to my component, the auto import imported it as
import { MessageService } from '../message.service.js';
With .js at the end, it won't work.
Upvotes: 0
Reputation: 2295
You should return this.gridOn$
as is and subscribe to it instead of using .asObservable()
which basically used to prevent the stream source from being publicly available in every component and that's the opposite of what you want.
getGridOn(): Observable<boolean> {
return this.gridOn$;
}
To know more about when to use asObservalbe() check this thread.
Upvotes: 2