Search code examples
angularangular8angular-servicesangular-ng-if

*ngIf not hiding/showing component as expected


I am calling this modal.service.ts from a component

export class ModalService {
  serviceText: boolean = true;

  toggleServices() {
    this.serviceText = !this.serviceText;
    console.log('test', this.serviceText);
  }
}

It is injected into options.component.ts below...

import { Component, OnInit, Input } from '@angular/core';
import { ModalService } from '../modal.service';

@Component({
  selector: 'app-options',
  templateUrl: './options.component.html',
  styleUrls: ['./options.component.css'],
  providers: [ModalService]
})
export class OptionsComponent implements OnInit {
  serviceText: boolean = false;
  constructor(private modalService: ModalService) { }

  ngOnInit() {
  }

  services() {
    this.modalService.toggleServices();
  }
}

The HTML for the options component is as follows, and has a click listener...

    <div class="tooth" >
      <img src="../../assets/tooth-brush.png" alt="tooth-brush" (click)='services()' style='cursor: pointer;'>
      <h5 (click)='services()' style='cursor: pointer;'>Services</h5>
      <app-services *ngIf="serviceText"></app-services>
    </div>

The services() in the options.component.ts is called, which in turn calls the toggleServices() in the modal.service.ts

The console does log 'test' and also True or False, which is the expected behavior.

BUT,

The <app-services *ngIf="serviceText"></app-services> in the options.component.html is not toggling between showing or hiding as I expected.

Can anybody see why this is not working?

Thanks in advance.


Solution

  • You need to initialize serviceText in your component with this.modalService.serviceText which is something that you probably forgot doing.

    Also, since this is a boolean in your service which you're updating which is primitive, it would be passed by value.

    So you'll have to re-assing the serviceText in your Component with serviceText in your service every time you toggle serviceText on your service.

    Do that in your Component like this:

    import { Component, OnInit, Input } from '@angular/core';
    import { ModalService } from '../modal.service';
    
    @Component({
      selector: 'app-options',
      templateUrl: './options.component.html',
      styleUrls: ['./options.component.css'],
      providers: [ModalService]
    })
    export class OptionsComponent implements OnInit {
      serviceText: boolean = false;
      constructor(private modalService: ModalService) { }
    
      ngOnInit() {
        this.serviceText = this.modalService.serviceText;
      }
    
      services() {
        this.modalService.toggleServices();
        this.serviceText = this.modalService.serviceText;
      }
    }
    

    And this should all work as expected.


    Here's a Sample Demo for your ref.