Q.uestion
Q.uestion

Reputation: 253

Angular subject is not working for all components

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

Answers (2)

Q.uestion
Q.uestion

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

MEDZ
MEDZ

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

Related Questions