localStorage is not defined (Angular Universal)

后端 未结 13 2448
情书的邮戳
情书的邮戳 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:25

    Update for newer versions of Angular

    OpaqueToken was superseded by InjectionToken which works much in the same way -- except it has a generic interface InjectionToken which makes for better type checking and inference.

    Orginal Answer

    Two things:

    1. You are not injecting any object that contains the localStorage object, you are trying to access it directly as a global. Any global access should be the first clue that something is wrong.
    2. There is no window.localStorage in nodejs.

    What you need to do is inject an adapter for localStorage that will work for both the browser and NodeJS. This will also give you testable code.

    in local-storage.ts:

    import { OpaqueToken } from '@angular/core';
    
    export const LocalStorage = new OpaqueToken('localStorage');
    

    In your main.browser.ts we will inject the actual localStorage object from your browser:

    import {LocalStorage} from './local-storage.ts';
    
    export function ngApp() {
      return bootstrap(App, [
        // ...
    
        UserService,
        { provide: LocalStorage, useValue: window.localStorage}
      ]);
    

    And then in main.node.ts we will use an empty object:

    ... 
    providers: [
        // ...
        UserService,
        {provide: LocalStorage, useValue: {getItem() {} }}
    ]
    ...
    

    Then your service injects this:

    import { LocalStorage } from '../local-storage';
    
    export class UserService {
    
        constructor(@Inject(LocalStorage) private localStorage: LocalStorage) {}
    
        loadCurrentUser() {
    
            const token = this.localStorage.getItem('token');
            ...
        };
    }
    

提交回复
热议问题