angular2-localstorage icon indicating copy to clipboard operation
angular2-localstorage copied to clipboard

Problem with the @LocalStorage() object

Open theunreal opened this issue 8 years ago • 24 comments

After installing the package I got the following error: Cannot read property '_username_mapped' of undefined

caused by declaring the variable like in the example..

@LocalStorage() public lastSearchQuery:Object = {};

What's wrong?

theunreal avatar Apr 12 '16 15:04 theunreal

Can you give us more code? Hard to guess.

marcj avatar Apr 12 '16 16:04 marcj

boots.ts relevant code

LocalStorageSubscriber(bootstrap(AppComponent, [
  HTTP_PROVIDERS,
  ROUTER_PROVIDERS
]));

AppComponent.ts


import {Component} from 'angular2/core';
import {MainMenuComponent} from './main-menu.component';
import {LocalStorage} from "./LocalStorage";

@Component({
    selector: 'heroland2',
    templateUrl: 'app/template/master.html',
    directives: [HeroListComponent,MainMenuComponent,ROUTER_DIRECTIVES]
})


export class AppComponent {

    @LocalStorage() public lastSearchQuery:Object = {};

    constructor(private router: Router){
}

theunreal avatar Apr 12 '16 17:04 theunreal

at which line and file occurs the error? Please post the full stack trace.

marcj avatar Apr 12 '16 17:04 marcj

The error is happening here:

LocalStorageEmitter.subscribe(() => {
            for (let instance of instances) {
                console.log('this', this)
                console.log('oldJSONValues', oldJSONValues)
                var currentValue = JSON.stringify(instance[decoratedPropertyName]);
                var oldJSONValue = oldJSONValues[this['_' + decoratedPropertyName + '_mapped']];
                if (currentValue !== oldJSONValue) {
                    oldJSONValues[this['_' + decoratedPropertyName + '_mapped']] = currentValue;
                    webStorage.setItem(storageKey, currentValue);
                }
            }
        });

"this" object is undefined for some reason.

nick-jonas avatar Apr 12 '16 17:04 nick-jonas

Here's the full stack trace:

browser_adapter.js:76TypeError: Cannot read property '_username_mapped' of undefined
    at WebStorage.ts:74
    at LocalStorageEmitter.ts:24
    at SafeSubscriber.schedulerFn [as _next] (async.js:134)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:166)
    at SafeSubscriber.next (Subscriber.js:115)
    at Subscriber._next (Subscriber.js:74)
    at Subscriber.next (Subscriber.js:51)
    at EventEmitter.Subject._finalNext (Subject.js:124)
    at EventEmitter.Subject._next (Subject.js:116)
    at EventEmitter.Subject.next (Subject.js:73)

nick-jonas avatar Apr 12 '16 17:04 nick-jonas

That's very weird. It worked for me pretty well. Do you have more informationen like: on which browser it happens? This error didn't appear with the 0.2.0 version, did it?

marcj avatar Apr 12 '16 17:04 marcj

"this" object is undefined for some reason.

yeah, for some reasons this is suddenly undefined. Could you post the generated ecmascript5 code? Maybe typescript compiler changed some stuff

marcj avatar Apr 12 '16 17:04 marcj

I have unfortunately not yet any project set up to test it further. Maybe @SirDarquan could help out a bit? :)

marcj avatar Apr 12 '16 17:04 marcj

Full error:

EXCEPTION: TypeError: Cannot read property '_lastSearchQuery_mapped' of undefined
angular2.dev.js:23941 EXCEPTION: TypeError: Cannot read property '_lastSearchQuery_mapped' of undefinedBrowserDomAdapter.logError @ angular2.dev.js:23941
angular2.dev.js:23941 STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23941
angular2.dev.js:23941 TypeError: Cannot read property '_lastSearchQuery_mapped' of undefined
    at eval (http://localhost:3000/app/LocalStorage.js:66:59)
    at eval (http://localhost:3000/app/LocalStorageEmitter.js:41:29)
    at SafeSubscriber.schedulerFn [as _next] (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:13193:11)
    at SafeSubscriber.__tryOrUnsub (http://localhost:3000/node_modules/rxjs/Subscriber.js:166:16)
    at SafeSubscriber.next (http://localhost:3000/node_modules/rxjs/Subscriber.js:115:22)
    at Subscriber._next (http://localhost:3000/node_modules/rxjs/Subscriber.js:74:26)
    at Subscriber.next (http://localhost:3000/node_modules/rxjs/Subscriber.js:51:18)
    at EventEmitter.Subject._finalNext (http://localhost:3000/node_modules/rxjs/Subject.js:124:30)
    at EventEmitter.Subject._next (http://localhost:3000/node_modules/rxjs/Subject.js:116:18)
    at EventEmitter.Subject.next (http://localhost:3000/node_modules/rxjs/Subject.js:73:14)
  -------------   Elapsed: 3 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at resolvePromise (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:538:22)
    at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:576:18
    at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:365:38)
    at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:2103:31)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at ZoneAwarePromise.then (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:649:18)
    at StyleCompiler._loadStyles (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:22074:51)
    at StyleCompiler.compileComponentRuntime (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:22047:19)
    at TemplateCompiler._compileComponentRuntime (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:25187:64)
  -------------   Elapsed: 1 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at resolvePromise (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:538:22)
    at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:520:14
    at ZoneDelegate.invoke (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:332:29)
    at Object.NgZoneImpl.inner.inner.fork.onInvoke (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:2111:31)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at resolvePromise (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:538:22)
    at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:576:18
    at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:365:38)
    at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:2103:31)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at ZoneAwarePromise.then (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:649:18)
    at RouterOutlet.deactivate (http://localhost:3000/node_modules/angular2/bundles/router.dev.js:2219:19)
    at http://localhost:3000/node_modules/angular2/bundles/router.dev.js:3203:32
    at ZoneDelegate.invoke (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:332:29)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at ZoneAwarePromise.then (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:649:18)
    at RootRouter.Router.deactivate (http://localhost:3000/node_modules/angular2/bundles/router.dev.js:3202:21)
    at RootRouter.Router.commit (http://localhost:3000/node_modules/angular2/bundles/router.dev.js:3158:23)
    at RootRouter.commit (http://localhost:3000/node_modules/angular2/bundles/router.dev.js:3279:45)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at resolvePromise (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:538:22)
    at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:576:18
    at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:365:38)
    at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:2103:31)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at ZoneAwarePromise.then (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:649:18)
    at RootRouter.Router._routerCanDeactivate (http://localhost:3000/node_modules/angular2/bundles/router.dev.js:3136:19)
    at http://localhost:3000/node_modules/angular2/bundles/router.dev.js:3074:22
    at ZoneDelegate.invoke (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:332:29)
  -------------   Elapsed: 1 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at resolvePromise (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:538:22)
    at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:520:14
    at ZoneDelegate.invoke (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:332:29)
    at Object.NgZoneImpl.inner.inner.fork.onInvoke (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:2111:31)
  -------------   Elapsed: 0 ms; At: Tue Apr 12 2016 20:27:29 GMT+0300 (שעון קיץ ירושלים)   -------------  
    at Object.Zone.longStackTraceZoneSpec.onScheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1354:23)
    at ZoneDelegate.scheduleTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:342:50)
    at Zone.scheduleMicroTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:280:40)
    at scheduleResolveOrReject (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:574:15)
    at resolvePromise (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:538:22)
    at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:576:18
    at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:365:38)
    at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:2103:31)BrowserDomAdapter.logError @ angular2.dev.js:23941
angular2-polyfills.js:471 TypeError: Cannot read property '_lastSearchQuery_mapped' of undefined(…)consoleError @ angular2-polyfills.js:471

I started using this library just now, after fixing this: https://github.com/marcj/angular2-localStorage/pull/8/commits/b174fae2ac2a74b6a30315fc0102ded94f5262d1

Maybe this error causes by changing the onTurnDone?

using Google Chrome

theunreal avatar Apr 12 '16 17:04 theunreal

Actually as soon as I saw this error I tried it out myself thinking maybe the new merged code had a bug. But it worked like a charm for me. Would it be possible for you to recreate it on plunkr or some other code sharing site?

SirDarquan avatar Apr 12 '16 17:04 SirDarquan

I did a git pull on the master branch of this, and replaced 0.2.0 that npm had pulled down.

After that I'm getting this error, in Google Chrome, Angular 2.0.0-beta.14, Typescript 1.8.9.

nick-jonas avatar Apr 12 '16 17:04 nick-jonas

Ok, I just setup a brand new test project from scratch. The npm package is up-to-date but the version number hasn't been incremented (maybe @marcj wants to take care of that). I was also careful to only follow instructions that are listed on the angular.io quick setup guide to get a simple application going. Then made the final connections using systemjs to grab the localstorage package and my application works. It placed an empty object in a key called lastSearchQuery in LocalStorage. I honestly don't understand how you are creating this error.

SirDarquan avatar Apr 12 '16 18:04 SirDarquan

Okay I got it working, and I narrowed down what makes it break:

In step 2 of the README, registering it in my boot.ts breaks it:

var appPromise = bootstrap(MyRootAppComponent);

// register LocalStorage, this registers our change-detection.
import {LocalStorageSubscriber} from 'angular2-localstorage/LocalStorageEmitter';
LocalStorageSubscriber(appPromise);

but if I simply provide it to my component (option 2b) it works fine:

import {Component} from "angular2/core";
import {LocalStorageService} from "angular2-localstorage/LocalStorageEmitter";

@Componenet({
    provider: [LocalStorageService]
})
export class AppRoot{
    constructor(storageService: LocalStorageService){}
...
}

nick-jonas avatar Apr 12 '16 18:04 nick-jonas

While I'm glad option 2b works for you, they both are supposed to do the same thing overall. In my recreated test project I used option 2a and it works just fine. I would love to examine the code you have if that's possible.

SirDarquan avatar Apr 12 '16 18:04 SirDarquan

I can't show you the exact code unfortunately, but will try and isolate it when I get a chance, under a deadline ATM!

nick-jonas avatar Apr 12 '16 19:04 nick-jonas

It's not storing values for me though, am I doing something stupid?

export class BattleSubComponent {

  @Input() battle:Battle
  @LocalStorage() public votes: Array<Vote> = [];

  constructor(private http:Http, private zone:NgZone) {}

  onVote(entryId){
    let body:Vote = {
      entry_id: entryId,
      battle_id: this.battle.id
    }
    this.votes.push(body)
  }

}

onVote is triggered on the click of a button.

When I log console.log(this.votes) in the constructor or on a lifecycle hook (like ngOnInit) it's still an empty array...

nick-jonas avatar Apr 12 '16 20:04 nick-jonas

So, I pulled the latest code and was seeing this same behavior in my angular2 + webpack project. After setting some breakpoints, I saw that this is always undefined in the following block:

        LocalStorageEmitter.subscribe(() => {
            for (let instance of instances) {
                var currentValue = JSON.stringify(instance[decoratedPropertyName]);
                var oldJSONValue = oldJSONValues[this['_' + decoratedPropertyName + '_mapped']];
                if (currentValue !== oldJSONValue) {
                    oldJSONValues[this['_' + decoratedPropertyName + '_mapped']] = currentValue;
                    webStorage.setItem(storageKey, currentValue);
                }
            }
        });

~~I was able to fix this issue by swapping usage of this out for target which is available in scope as a function parameter, if this is a valid fix maybe someone should implement it.~~

Scratch that, I'm seeing some issues with this fix in place, not sure if related yet.

zachgrayio avatar Apr 16 '16 03:04 zachgrayio

I'm getting this problem also. It was working fine but since I upgraded to angular2 beta 15 (from 0) it stopped working. 'this' or '_this' is not defined. I also changed to gulp-typescript so perhaps there is a difference in the compiled js files...

I tried both provider methods in the README step 2, tried using a clone of the master repo, tried both npm module versions but nothing works now. Problem persists in Firefox 44 and chrome 49 on osx el capitan.

joesheridan avatar Apr 17 '16 20:04 joesheridan

I have the same problem with [email protected]. this in the LocalStorageEmitter callback is always undefined. I put a breakpoint at the top of decoratorFactory. When decoratorFactory is called, this is undefined.

tdterry avatar Apr 19 '16 17:04 tdterry

I suspect it may be an issue with angular-polyfills, since this is directly below in the callstack and supplies the 'applythis' variable. Just a suspicion though at this stage.

joesheridan avatar Apr 20 '16 07:04 joesheridan

same problem here in [email protected].

SET001 avatar Apr 26 '16 15:04 SET001

I hate leaving everyone out in the cold with issues but unfortunately I can't reproduce the problem. If we were able to do more automated testing on this library we might have been able to fix it. But this isn't possible due to way static classes are being used. With that said, I wanted to see if I could remedy the situation with a more testable library inspired by the work done by @marcj. It's not a drop in replacement but switching over shouldn't be difficult if you wanted to. https://github.com/SirDarquan/h5webstorage/ I hope it helps.

SirDarquan avatar Apr 26 '16 18:04 SirDarquan

Found a solution - https://github.com/SET001/angular2-localStorage/commit/43282ebfbf8a811bcd5c5f7e2bb9788342784455

SET001 avatar Apr 27 '16 01:04 SET001

here bump with same issues, @SET001 's pull request work for us. Our angular2 is also 2.0.0-beta.15

angusan avatar Apr 27 '16 06:04 angusan