robi
robi

Reputation: 15

Getting the value of local storage with Observable is not working in Angular

Hi I am trying to get the value from local storage by using observable but it is not working.

My previous code was:

const isManager= JSON.parse(localStorage.getItem('isManager'));
console.log('isManager', isManager);
this.doNavigation(isManager);

But I change it in to this for continously reading value:

of(JSON.parse(localStorage.getItem('isManager'))).pipe(
      takeWhile(() => this.alive),
      map((isManager: boolean) => {
        console.log('isManager', isManager);
        this.doNavigation(isManager);
      })
    );

The problem is that it is not going inside the map body and there is a value present in local stroage regarding this field.

Upvotes: 0

Views: 1854

Answers (2)

Jovana
Jovana

Reputation: 608

I'm not sure there is an option to continuously read value from local storage, for that to work, you'd need to be able to subscribe to local storage item's value and that's just not possible.

What you've done in your solution is created Observable containing only one value (current local storage item's value), so after you subscribe to that method you'd only get current value, but it wouldn't change no matter if local storage item's value changes.

Since there is no direct way to subscribe to local storage, you can use service with BehaviourSubject which will constantly have stored the newest local storage item's value. That way wherever you subscribe to BehaviourSubject all dependent elements will always get the newest value from stream.

This is what the service which handles local storage should look like:

@Injectable({providedIn: 'root'})
export class LocalStorageService {
 private isManager$ = new BehaviorSubject<boolean>(false);

 constructor(){
   // get current value from local storage
   isManager = localStorage.getItem('isManager');

   // set stream's last value to local storage item's value
   // this way when service is initialized, isManager$'s value will be set to current local storage value
   this.isManager$.next(isManager as boolean);
 }

 setIsManager(value):void {
   // sets isManager$'s value to new value passed as argument
   // after this line is executed, value of all subscriptions will change to the latest value
   this.isManager$.next(value); 

   // sets local storage's value to new value
   // in case user reloads page, constructor will set isManager$ to last available value
   localStorage.setItem('isManager', value);
 }

 getIsManager(): Observable<boolean> {
   // returns stream of values, which means, after you've subscribed, you'll always get the latest value from stream
   return this.isManager$;
 }
}

To learn more about BehaviourSubject check out RxJS documentation for BehaviourSubject. You can also watch this video which gives really good explanation of basics of BehaviourSubject and how to use them.

Upvotes: -1

Adrian Brand
Adrian Brand

Reputation: 21638

Why not use

const isManager = localStorage.getItem('isManager') === 'true';
// You need to convert the string stored in local storage to a boolean.

if (isManager) {
  this.doNavigation(isManager);
}

What is the point of using of to create an observable that is mapped to undefined? Very smelly code.

Upvotes: 1

Related Questions