user4270323
user4270323

Reputation:

Subscribe Value of *ngIf is not Updating

This is the Basic Idea of what i'm trying to Do..!

I Have a Navigation Bar that is global For all the Modules in my Application. But when i go to specific component i want to hide the search bar from my Navbar. To do this i used the method of Creating a Global variable and subscribe to it ( Subscribe from Navbar)

location.service.ts is my global variable service

import { Injectable } from '@angular/core';
import { Observable ,of as observableOf} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LocationService {
  private createnewproject: boolean = false;
  constructor() { }

public getcurrentlocation(): Observable<boolean>
{
  return  observableOf( this.createnewproject);
}

public setcurrentlocation(status:boolean)
{
  this.createnewproject = status ;
}

public checkvalue():boolean
{
  return this.createnewproject;
}

}

//createnewproject is Initially false and once it goes to specific module i'll set it to true

this is my Navbar class and this is how i Subscribe to it

import { Component, OnInit } from '@angular/core';
import { ConstantsService } from '../common/services/constants.service';
import { LocationService} from '../common/services/location.service';
import { observable } from 'rxjs';

@Component({
  selector: 'app-ibrainmart-header',
  templateUrl: './ibrainmart-header.component.html',
  styleUrls: ['./ibrainmart-header.component.css']
})
export class IbrainmartHeaderComponent implements OnInit {
  oncreateproject: boolean;
  constructor( private projectloaction: LocationService) { }

  ngOnInit()
  {


    const oncreate = this.projectloaction.getcurrentlocation().subscribe(observable => { this.oncreateproject = observable;});

  }

}

this is how i planned to Hide Search-bar from code using *ngIf

 <div class="row" *ngIf = "!oncreateproject">
      <div class="col-md-12">
          <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
                  <div class="input-group mb-3">
                  <input type="text" class="form-control"  placeholder="Search anything ..!" aria-label="Searchbar" aria-describedby="">
                      <div class="input-group-append">
                      <button class="btn btn-outline-light" type="button" id="btnsearch" ><i class="fa fa-search"></i>{{oncreateproject}}</button>
                      </div>


                  </div>
          </nav>
      </div>
  </div>

this is how i set global variable to true once in reach to specific page

import { Component, OnInit } from '@angular/core';
import { ConstantsService } from 'src/app/common/services/constants.service';
import { LocationService } from 'src/app/common/services/location.service';

@Component({
  selector: 'app-createnewproject',
  templateUrl: './createnewproject.component.html',
  styleUrls: ['./createnewproject.component.css']
})
export class CreatenewprojectComponent implements OnInit {

  createnewproject: boolean;

  constructor( private oncreateproject: LocationService) {

   this.oncreateproject.setcurrentlocation(true);
   console.log('Globle Value:' + this.oncreateproject.checkvalue());
   }

  ngOnInit()
  {

  }


}

but when i goto this page global value is updating but Serach bar is not hiding can someone help me to find where i was doing Wrong ..?

Upvotes: 1

Views: 1729

Answers (2)

SGalea
SGalea

Reputation: 722

I would use BehaviorSubject so it holds an initial value and can use async in view so it resolves the value.

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LocationService {
  private searchBarVisibility$ = new BehaviorSubject(true);
  constructor() { }

  public getcurrentlocation(): Observable<boolean> {
    return from(this.searchBarVisibility$);
  }

  public setcurrentlocation(status: boolean) {
    this.searchBarVisibility$.next(status);
  }

}

Then Hide Search-bar

 <div class="row" *ngIf = "oncreateproject | async">
      <div class="col-md-12">
          <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
                  <div class="input-group mb-3">
                  <input type="text" class="form-control"  placeholder="Search anything ..!" aria-label="Searchbar" aria-describedby="">
                      <div class="input-group-append">
                      <button class="btn btn-outline-light" type="button" id="btnsearch" ><i class="fa fa-search"></i>{{oncreateproject | async}}</button>
                      </div>
                  </div>
          </nav>
      </div>
  </div>

IbrainmartheaderComponent

import { Component, OnInit } from '@angular/core';
// import { ConstantsService } from '../constants.service';
import { LocationService} from '../location.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-ibrainmart-header',
  templateUrl: './ibrainmart-header.component.html',
  styleUrls: ['./ibrainmart-header.component.css']
})
export class IbrainmartheaderComponent implements OnInit {
  oncreateproject: Observable<boolean>;
  constructor( private projectlocation: LocationService) { }

  ngOnInit()
  {
    this.oncreateproject = this.projectlocation.getcurrentlocation();
  }

}

CreatenewprojectComponent

import { Component, OnInit } from '@angular/core';
// import { ConstantsService } from 'src/app/common/services/constants.service';
import { LocationService } from '../location.service';

@Component({
  selector: 'app-createnewproject',
  templateUrl: './createnew-project.component.html',
  styleUrls: ['./createnew-project.component.css']
})
export class CreatenewprojectComponent {

  createnewproject: boolean;

  constructor(private projectlocation: LocationService) {
    this.projectlocation.getcurrentlocation().subscribe(value =>
          console.log('Globle Value:' + value)
    );
    this.projectlocation.setcurrentlocation(true);
  }

}

Upvotes: 0

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24414

you need to use a rxjs subject the of function just create an observable base of the value but will not sync the any change to the property that why I thing is the best case to use Subject

import { Injectable } from '@angular/core';
import { Observable ,Subject , from} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LocationService {
  private createnewproject: Subject<boolean>= new Subject();
  constructor() { }


public getcurrentlocation(): Observable<boolean>
{
  return  from(this.createnewproject);
}

public setcurrentlocation(status:boolean)
{
  this.createnewproject.next(status);
}


}

IbrainmartHeaderComponent

export class IbrainmartHeaderComponent implements OnInit {

  // set initial value in case you want to see the search bar by default 
  oncreateproject: boolean = true;

  constructor( private projectloaction: LocationService) { }

  ngOnInit()
  {
    this.projectloaction.getcurrentlocation().subscribe(state => { 
      this.oncreateproject = state;
    });

  }

}

subjects

Upvotes: 2

Related Questions