0

I have this funcion on the component calls navbar:

getAddUsuario(){
if(window.localStorage.getItem('addUsuario') == 'false'){
  window.localStorage.setItem('addUsuario','true');

}else{
  window.localStorage.setItem('addUsuario','false');      
}
return window.localStorage.getItem('addUsuario');

So, when i click the variable addUsuario change to false if is true and to true if is false.

The problem is i wqant to detect that changes from another component and pass it into HTML. if is true take a div class and if is false take another div class.

I tried with addEventlistener but doesnt work.

Thanks

2 Answers2

2

You could move the functions to a singleton service and monitor the value using observables. Try the following

Shared service

import { BehaviorSubject, Observable } from 'rxjs';  // <-- included 'Observable' here - with capital 'O'

@Injectable()
export class SharedService {
  private addUsuarioSource = new BehaviorSubject<string>('false');
  public addUsuario$ = this.addUsuarioSource.asObservable();

  constructor() {
    this.addUsuario$.subscribe(status => window.localStorage.setItem('addUsuario', status));   // <-- changed 'userStatus' to 'status'
  }

  getAddUsuario(): Observable<string> {   // <-- capital 'O' instead of small 'o'
    let userStatus = window.localStorage.getItem('addUsuario');
    userStatus = (userStatus === 'false' || userStatus == null) ? 'true' : 'false';
    this.addUsuarioSource.next(userStatus);
    return this.addUsuario$;
  }
}

Navbar component

import { pipe } from 'rxjs';
import { map, take } from 'rxjs/operators';

export class NavbarComponent implements OnInit() {
  subscription: any;

  ngOnInit() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
    this.subscription = this.sharedService.getAddUsuario().pipe(take(1)).subscribe(status => {
      // this callback will be called only once due to `pipe(take(1))`
      // `status` variable with value 'true' or 'false' as string
    });
  }
}

Another component

this.sharedService.addUsuario$.subscribe(status => {
  // this callback will be called each time a new user status is pushed
  // `status` variable with value 'true' or 'false' as string
})

I am using BehaviorSubject to provide a default value. You could use Rxjs Subject if you do not wish to provide a default value. Explanation for pipe(take(1)) can be found here.

Note: Storing boolean in local storage isn't a good idea. Because you can only store strings and it returns the values as strings. So you cannot do something like *ngIf==="status" or *ngIf==="!status". It would be *ngIf="status === 'true'" and *ngIf="status === 'false'".

Working example: Stackblitz

ruth
  • 29,535
  • 4
  • 30
  • 57
  • I have a error with take? what i need to import? Thanks – Razvan Andrei lismanu Apr 08 '20 at 14:21
  • Doesnt work. I mean when i click the variable change from true to false and if i press that button again didnt change to true. – Razvan Andrei lismanu Apr 08 '20 at 15:38
  • There were some minor typos and errors in the service code. I've modified it and added relevant comments. Please check if it still doesn't work for you. – ruth Apr 08 '20 at 15:44
  • It works now, i maked the same like u. When i press click, cheking localStorage the variable change, but didnt change into html. U know why? – Razvan Andrei lismanu Apr 08 '20 at 15:53
  • 1
    I've made a working Stackblitz [here](https://stackblitz.com/edit/angular-gubjbl). There were few other tweaks required. Since we subscribe on every button press, we need to make sure the previous subscription is unsubscribed. Please see if it works for you. – ruth Apr 08 '20 at 15:55
  • What u do work, but in my child component html y have something like this:
    yes
    no
    . And didnt work
    – Razvan Andrei lismanu Apr 08 '20 at 16:01
  • That will not work. Because the data returned from the local storage is of the type `string`. So you need to check for conditions `*ngIf="status === 'true'"` and `*ngIf="status === 'false'"`. I've modified the [Stackblitz](https://stackblitz.com/edit/angular-zmwcdk). Storing boolean in local storage isn't a good idea. – ruth Apr 08 '20 at 16:06
0

You can do this in your typescript

create a global variable like this:

addUsuario:boolean;

getAddUsuario(){ 
if(window.localStorage.getItem('addUsuario') == 'false'){
window.localStorage.setItem('addUsuario','true');
//and do this one
addUsuario = true;
}else{
window.localStorage.setItem('addUsuario','false');    
addUsuario = false;  
}
return window.localStorage.getItem('addUsuario');

and in your HTML you can use *ngIf for example:

<div *ngIf="addUsuario == true">
<!--Your div-->
</div>
<div *ngIf="addUsuario == false">
<!--your div-->
</div>