localStorage is not defined (Angular Universal)

后端 未结 13 2492
情书的邮戳
情书的邮戳 2020-11-29 01:26

I am using universal-starter as backbone.

When my client starts, it read a token about user info from localStorage.

@Injectable()
export class UserSe         


        
13条回答
  •  清歌不尽
    2020-11-29 02:07

    In Angular 4 (and 5) you can easily deal with such issue with a simple function in the following way:

    app.module.ts

    @NgModule({
        providers: [
            { provide: 'LOCALSTORAGE', useFactory: getLocalStorage }
        ]
    })
    export class AppModule {
    }
    
    export function getLocalStorage() {
        return (typeof window !== "undefined") ? window.localStorage : null;
    }
    

    If you have a server/client split file AppModule, place it in the app.module.shared.ts file - the function won't break your code - unless you need to enforce completely different behaviours for the server and client builds; if that’s the case, it could be wiser to implement a custom class factory instead, just like it has been shown in other answers.

    Anyway, once you're done with the provider implementation, you can inject the LOCALSTORAGE generic in any Angular component and check for the platform type with the Angular-native isPlatformBrowser function before using it:

    import { PLATFORM_ID } from '@angular/core';
    import { isPlatformBrowser, isPlatformServer } from '@angular/common';
    
    @Injectable()
    export class SomeComponent {
        constructor(
            @Inject(PLATFORM_ID) private platformId: any,
            @Inject('LOCALSTORAGE') private localStorage: any) {
    
            // do something
    
        }
    
        NgOnInit() {
            if (isPlatformBrowser(this.platformId)) {
                // localStorage will be available: we can use it.
            }
            if (isPlatformServer(this.platformId)) {
                // localStorage will be null.
            }
        }
    }
    

    It’s worth noting that, since the getLocalStorage() function will return null if the window object isn’t available, you could just check for this.localStorage nullability and entirely skip the platform type check. However, I strongly recommend the above approach as that function implementation (and return value) might be subject to change in the future; conversely, the isPlatformBrowser / isPlatformServer return values are something that can be trusted by design.

    For more info, check out this blog post that I wrote on the topic.

提交回复
热议问题