1

I'm trying to inject Browser Storage to my angular application using the following code:

import {Inject, Injectable, InjectionToken} from '@angular/core';

export const BROWSER_STORAGE = new InjectionToken<Storage>('Browser Storage', {
  providedIn: 'root',
  factory: () => localStorage
});

@Injectable({
  providedIn: 'root'
})
export class BrowserStorageService {
  constructor(@Inject(BROWSER_STORAGE) public storage: Storage) {
  }

  get(key: string) {
    return this.storage.getItem(key);
  }

  set(key: string, value: string) {
    this.storage.setItem(key, value);
  }

  remove(key: string) {
    this.storage.removeItem(key);
  }

  clear() {
    this.storage.clear();
  }
}

But it throws error on the server and application doesnot runs

ERROR ReferenceError: localStorage is not defined

how to define the storage so that it defined and my application works?

2 Answers2

2

You could try one of these 2 options

Option 1

Modify your factory to accept the platform id

declare let localStorage: any;

export function localStorageFactory(platformId: Object)
{
    return isPlatformBrowser(platformId)? localStorage: null; //Don't use null, use a dummy implementation that does not rely on localStorage
}


export const BROWSER_STORAGE = new InjectionToken<Storage>('Browser Storage', {
  providedIn: 'root',
  factory: () => localStorageFactory,
  deps: [PLATFORM_ID]
});

Option 2

Modify your current service implementation to inject the platform id token

@Injectable({
  providedIn: 'root'
})
export class BrowserStorageService {

  private readonly isBrowser;

  constructor(@Inject(BROWSER_STORAGE) public storage: Storage, @Inject(PLATFORM_ID) private platformId: Object) {

       this.isBrowser = isPlatformBrowser(platformId);
  }

  get(key: string) {
    //check if browser or not
    return this.isBrowser? this.storage.getItem(key) : null;
  }
David
  • 33,444
  • 11
  • 80
  • 118
0

Updated answer - How to use localStorage in angular universal?

Use the Platform ID in your components.ts file

Components.ts

  import {  PLATFORM_ID} from '@angular/core';
    import { Inject } from '@angular/core';
    import { Router } from '@angular/router';
    import { isPlatformBrowser } from '@angular/common';
    
    @Component({
      selector: 'app-navigation',
      templateUrl: './navigation.component.html',
      styleUrls: ['./navigation.component.scss'],
      changeDetection: ChangeDetectionStrategy.OnPush,
    })
    export class NavigationComponent implements OnInit {
      locale_Menu: any = [];
      defaultURL: any;
      defaultURLpath: any;
      private isBrowser: boolean = false;
    
      constructor(
        @Inject(DOCUMENT) private dom: Document,
        private router: Router,
        @Inject(PLATFORM_ID) private platformId: Object
      ) {
        this.isBrowser = isPlatformBrowser(platformId);
      }
    
      ngOnInit(): void {
        this.generalAppSettings.subscribe((location: any) => {
          this.locale_Menu = location.localeMenu.continents;
        });
        this.defaultURL = new URL(this.dom.URL);
        this.defaultURLpath = this.defaultURL?.pathname.split('/');
        if (this.defaultURLpath.length == 2) {
          if (this.isBrowser) {
            var retrievedLocale = localStorage?.getItem('preferredLocale');
    
            if (retrievedLocale) {
              const navigateURL = this.defaultURL?.pathname.replace(
                this.defaultURLpath[1],
                retrievedLocale
              );
              this.router.navigate([navigateURL]);
            } else {
              this.router.navigate([this.defaultURL]);
            }
          }
        }
      }
    
      changeLocale(category: any): void {
        const locale = this.coreService.locales.find((l) => l.code === category);
        if (locale) {
          let _URL = this.defaultURL.pathname.replace(
            this.defaultURL.pathname.split('/')[1],
            locale.code
          );
          if (this.defaultURLpath.length == 2) {
            window.localStorage.setItem('preferredLocale', locale.code);
          }
    
          this.router.navigate([_URL]).then(() => {
            window.location.reload();
          });
        }
      }
    }
Surya R Praveen
  • 3,393
  • 1
  • 24
  • 25