Javascriptservices: Trying to add a service which uses localstorage fail

Created on 13 Oct 2016  路  11Comments  路  Source: aspnet/JavaScriptServices

I am trying to add the following service:

import { Injectable } from '@angular/core';
import { Http, Headers, Response, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map'

@Injectable()
export class AuthenticationService {
    public token: string;
    public codusuario: string;
    constructor(private http: Http) {
        // set token if saved in local storage
        var currentUser = JSON.parse(localStorage.getItem('currentUser'));
        this.token = currentUser && currentUser.token;
    }

    login(username, password): Observable<boolean> {
        //...
    }

    logout(): void {
        // clear token remove user from local storage to log user out
        this.token = null;
        localStorage.removeItem('currentUser');
    }
}

I added it to the app.module.ts. But it gives me the following error:

Exception: Call to Node module failed with error: Error: Uncaught (in promise): ReferenceError: localStorage is not defined

I am trying to migrate this service from a yeoman project structure: https://www.npmjs.com/package/generator-aspnetcore-angular2, where the service works fine.

Why it is not working here?

Most helpful comment

@kolte We are doing it like this in ng4:

import { OnInit, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformServer, isPlatformBrowser } from '@angular/common';

export class SomeClass implements OnInit {

    constructor(@Inject(PLATFORM_ID) private platformId: Object) { }

    ngOnInit() {
        if (isPlatformServer(this.platformId)) {
            // do server side stuff
        }

        if (isPlatformBrowser(this.platformId)) {
            // do client side stuff
        }
    }

}

All 11 comments

It doesn't work because the code is running on the server. The server doesn't know what localstorage is. Localstorage is only available to the browser.

What you'll need to do is use Dependency injection to abstract out localStorage and pass in a version for the server, and the normal (localStorage) for the browser.

Or at least surround any code that touches localStorage inside a block like this:

import { isBrowser } from 'angular2-universal';

if (isBrowser) {
    // Do stuff with localStorage
}

In angular 4 it is like this
import { isPlatformBrowser } from '@angular/common';
but it's not working
any idea?

@kolte We are doing it like this in ng4:

import { OnInit, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformServer, isPlatformBrowser } from '@angular/common';

export class SomeClass implements OnInit {

    constructor(@Inject(PLATFORM_ID) private platformId: Object) { }

    ngOnInit() {
        if (isPlatformServer(this.platformId)) {
            // do server side stuff
        }

        if (isPlatformBrowser(this.platformId)) {
            // do client side stuff
        }
    }

}

Thanks @MorisatoK that worked very well !

this doesn't help me at all... I could really use some more help on this. I am getting the same error localStorage is not defined this works some of the time, but not all of the time..

Update: my project works running on a Mac... when I run the same project on Windows 10 I get localStorage not defined maybe this shouldn't be closed? I understand the localStorage is a browser deal, but then why does it work on Mac but not Windows? I would like to see a real explanation.

My project is straight out of Microsoft's dotnet new angular cli. added a provider called AuthService which needs to store timeouts and tokens in localStorage. should this provider be somewhere else in the project? Is there a way to have code in a project reference localStorage at all if localStorage is only a browser thing?

I could really use some help here. I can't run this project from a windows environment...

@MarkPieszak can we open this issue again?

I have the same problem! I got this annoying error about localstorage sometimes! @8bitreid I decided to disable server-side rendering by removing asp-prerender-module from index.cshtml.

There used to be an example in this repo of how to inject a class that uses localStorage on the browser & in
memory variable on the server, but it got removed. See this old commit for details:

https://github.com/MarkPieszak/aspnetcore-angular2-universal/commit/a5b3be3cf35c9da4c2bd7b3ede98b07f243cfeac

Was this page helpful?
0 / 5 - 0 ratings