1

I have a HeaderComponent which displays the header in which I have a search bar, where a user when inputs something and presses enter I take the user to SearchComponent.

I want to implement the functionality that when a user is on search page (SearchComponent), the searchBar in header should not be visible while it should be visible on all other pages.

For this, I added variable searchShow in HeaderComponent.ts and by ng-if in HeaderComponent.html, I show/hide the searchBar.

To change the value of searchShow, I implemented a Header.service.ts.

header.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class HeaderService {
  showSearch = new BehaviorSubject<boolean>(true);
  public showSearchObservable = this.showSearch.asObservable()
  constructor(){}
}

header.component.ts

import { Component, OnInit } from '@angular/core';
import { HeaderService } from './header.service';
@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
  searchShow;
  constructor(
    private headerService: HeaderService
  ) {}

  ngOnInit() {
    this.headerService.showSearchObservable.subscribe(
      value => {
        this.searchShow = value
        console.log(value) ##==> prints true first time when header is initialized but does not prints anything when search component is loaded
      }
    )
  }
}

search.component.ts

import { Component, OnInit } from '@angular/core';
import { HeaderService } from 'src/app/shared/header/header.service.js';
@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
 constructor(
    private headerService: HeaderService
  ) {}

  ngOnInit() {
    console.log(this.headerService.showSearch.value) ##==> prints true
    this.headerService.showSearch.next(false)
    console.log(this.headerService.showSearch.value) ##==> prints false, but this value is not emitted to header component
}
}

What am I missing? Please help. Thanks

Saqib Shahzad
  • 982
  • 12
  • 28
  • I suspect you are somehow getting two different instances of `HeaderService`. Could you check how many times the constructor is being called? Are you attempting to provide it through an `NgModule`? – Chris Yungmann Jul 07 '20 at 04:32
  • Usually you'd expose a different public observable using `asObservable` rather than directly subscribing to the `BehaviorSubject`. This would be similar to what is seen in the [documention](https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service) – Alexander Staroselsky Jul 07 '20 at 04:42
  • Yes this seems to be the case but I am not sure where I am instantiating the second instance of headerService. As you can see, in the constructor of SearchComponent I am instantiating headerService, could this be the case? – Saqib Shahzad Jul 07 '20 at 04:44
  • @AlexanderStaroselsky I have added asObservable (update my question code as well) but same result :( – Saqib Shahzad Jul 07 '20 at 04:51

1 Answers1

1

In search.component.ts you reference

import { HeaderService } from 'src/app/shared/header/header.service.js';

Which is causing a second headerService instance. Taking .js suffix should fix this issue.

Raz Ronen
  • 2,418
  • 2
  • 14
  • 26
  • I changed it to a getter as you suggested, but the value still not propagates to the header component from the search component. – Saqib Shahzad Jul 07 '20 at 05:07
  • Something is weird in the imports, see in `search.component.ts` you reference `import { HeaderService } from 'src/app/shared/header/header.service.js';` which includes suffix `.js`, maybe take the suffix off? – Raz Ronen Jul 07 '20 at 05:32
  • Yes, removing the suffix worked, as now the value propagated to the header component. but now I am receiving this error in the console. ` ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.` – Saqib Shahzad Jul 07 '20 at 05:50
  • Where is this error coming from? This error is related to template and change detection mechanizm. It isn't related to the subject. Maybe post another stackoverflow question for it or check this article: https://indepth.dev/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error/ – Raz Ronen Jul 07 '20 at 05:56
  • 1
    this is originating because I am changing the value of searchShow in header component whenever I receive new value for showSearchObservable. – Saqib Shahzad Jul 07 '20 at 05:58