angularangularjsangular17angular-local-storage

Error: localStorage is not defined in Angular service


I'm developing an Angular application and encountering an issue with localStorage in my AuthService. When attempting to use localStorage to store the user's email for authentication purposes, I'm getting an error: "localStorage is not defined".

Here's a simplified version of my AuthService:

//auth.service.ts

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

@Injectable({
    providedIn: 'root',
})
export class AuthService {
    public isAuth = new BehaviorSubject<boolean>(false);

    constructor(private router: Router) {
        this.autoSignIn();
    }

    autoSignIn() {
        if (localStorage.getItem('email')) {
            this.isAuth.next(true);
            this.router.navigate(['/dashboard']);
        }
    }

    signIn(email: string) {
        localStorage.setItem('email', email);
        this.isAuth.next(true);
        this.router.navigate(['/dashboard']);
    }

    signOut() {
        localStorage.removeItem('email');
        this.isAuth.next(false);
        this.router.navigate(['/auth']);
    }
}

I've imported the necessary modules, including Injectable from @angular/core, and I'm using localStorage within my service methods.


Solution

  • LocalStorage is only present on the browser, but If you have SSR then the written code runs on the server also, so when accessing it, it will be undefined, we have a function that will determine if it's server or browser and we can handle such scenarios

    //auth.service.ts
    
    import { Injectable } from '@angular/core';
    import { Router } from '@angular/router';
    import { BehaviorSubject } from 'rxjs';
    import { PLATFORM_ID } from '@angular/core';
    import { isPlatformBrowser } from '@angular/common';
    
    @Injectable({
        providedIn: 'root',
    })
    export class AuthService {
        public isAuth = new BehaviorSubject<boolean>(false);
        isBrowser: boolean;
    
        constructor(@Inject(PLATFORM_ID) platformId: Object, private router: Router) {
            this.isBrowser = isPlatformBrowser(platformId);
            this.autoSignIn();
        }
    
        autoSignIn() {
            if (this.isBrowser ? localStorage.getItem('email') : false) {
                this.isAuth.next(true);
                this.router.navigate(['/dashboard']);
            }
        }
    
        signIn(email: string) {
            if (this.isBrowser) {           
                 localStorage.setItem('email', email);
            }
            this.isAuth.next(true);
            this.router.navigate(['/dashboard']);
        }
    
        signOut() {
            if (this.isBrowser) {
                localStorage.removeItem('email');
            }
            this.isAuth.next(false);
            this.router.navigate(['/auth']);
        }
    }