3

EDIT: This is NOT a duplicate of how to retrieve the value from localstorage. My case was completely different, in fact, it was not an issue with the localstorage but with the way Angular works.

I'm working on an Angular7 application.

I have a component that sets a token to localStorage: window.localStorage.setItem("oauth_token", oauth_token) and then redirect to the home page: this.router.navigate(['/'])

The root component now should be able to read from the localStorage window.localStorage.getItem("oauth_token"), but the value is null unless i manually refresh the page.

When I inspect the Chrome dev tool I can see the token in the local storage, so why do I need to refresh the page? What can I do to overcome this?

Sergio
  • 250
  • 1
  • 4
  • 18
  • @weegee nope, it looks different. I want the value to be available without refreshing the page. – Sergio Aug 15 '19 at 15:32
  • Have you investigated using a timer to perform housekeeping functions and perhaps update your page for you? – SPlatten Aug 15 '19 at 15:37
  • @SPlatten I have tried using setTimeout before redirecting to the home page, but it didn't work – Sergio Aug 15 '19 at 15:38
  • could you share some of your code ? – Alfian Busyro Aug 15 '19 at 15:40
  • @Sergio, use setInterval instead, setTimeout gives you a one shot timer. – SPlatten Aug 15 '19 at 15:41
  • Items in local storage should be retrievable immediately. If it isn't, I suspect your code that sets the item in local storage isn't running as you expect. –  Aug 15 '19 at 15:43
  • @SPlatten setInterval will loop your code again and again, don't do that or you'll ruin your program – Alfian Busyro Aug 15 '19 at 15:44
  • From experience, do a getItem() after setItem() to confirm data before you call your router.navigate() – Austyns Aug 15 '19 at 15:47
  • @arufian, it depends how you code it and what you do in the loop and how frequent the interval is. – SPlatten Aug 15 '19 at 15:49
  • @SPlatten Nope, setInterval definitely useless, unless you're use it for animation. I assume you've great understanding of JS. – Alfian Busyro Aug 15 '19 at 15:55
  • @arufian, again depends on how you use it and what you do with it, like any feature it can perform badly if the implementation is poor. – SPlatten Aug 15 '19 at 15:59
  • I figured out where the problem is but I can't find a solution. After the redirect, the root component doesn't get triggered. Neither the constructor nor the ngOnInit() method gets called so my code never runs. https://github.com/angular/angular/issues/18254 – Sergio Aug 15 '19 at 16:17
  • I assume your root component is therefore `app.component` and your `app.component.html` contains your root <`app-router>`? This will only load once and then all other components will load into this app router this is why your methods are not running when you navigate. Because the angualr router is simply swapping components out within the component. – Sam Aug 15 '19 at 16:30
  • Check my answer for the root component to trigger. – Chetan Naik Aug 15 '19 at 16:37
  • @ChetanNaik the link is about passing parameters from one component to another. It doesn't say anything about triggering – Sergio Aug 15 '19 at 16:55
  • Edited my answer please check – Chetan Naik Aug 15 '19 at 17:04

2 Answers2

3

It's nothing related to the local storage. Your root component needs a trigger or refresh to access the local storage or any change in the data.

When you redirect to the home page only the code from the home page component is executed and not from the parent or root component.

You need to declare a variable in the service file. So whenever you update the local storage you will have to update the value of the service file variable. You can access this variable in your root component. So if there is any change in the service variable a trigger will be fired and you can update the local storage. Check the link for a sample code https://github.com/resistcheat/angular-variable-as-observable

Create a Service File

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CommonService {
  data: any;
  private items: BehaviorSubject<any> = new BehaviorSubject<any>(this.data);
  items$: Observable<any> = this.items.asObservable();
  constructor(private http: HttpClient) { }
  setLocalStorageData() {// Call this function to set localstorage
    localStorage.setItem("oauth_token", oauth_token)
    this.data = oauth_token;
  }
}

//Trigger will be fired when this.data changes. Add the below code to your root Component

constructor(private commonService: CommonService) { }
items: any;
subscription: Subscription; //import { Subscription } from 'rxjs';

ngOnInit() {
  this.subscription = this.commonService.items$.subscribe(items =>  {
    this.items = JSON.stringify(items));
    console.log(localStorage.getItem("oauth_token"));
  }
}

ngOnDestroy() {
  this.subscription && this.subscription.unsubscribe();
}
YakovL
  • 7,557
  • 12
  • 62
  • 102
Chetan Naik
  • 613
  • 3
  • 12
1

try without window, like that:

localStorage.getItem("oauth_token")...
tehila
  • 135
  • 7