jmdobry / angular-cache

angular-cache is a very useful replacement for the Angular 1 $cacheFactory.
http://jmdobry.github.io/angular-cache
MIT License
1.39k stars 156 forks source link

When localstorage mode enabled, multiple sets of same value corrupt the value (2.3.x) #109

Closed jeffthompson1971 closed 10 years ago

jeffthompson1971 commented 10 years ago

This cache works fine when I don't enable the localstorage mode. when i enable the localstorage though, the first 'set' of an item looks good in my localstorage as inpsected from devTools (Chrome) . In this example, I'm using 'userInfo' as my key, andi'm storing a json string that is what i get back from google when i ask for user info:

\ MY CONFIG ** var theCache = $angularCacheFactory('theCache', { maxAge: 900000, // Items added to this cache expire after 15 minutes. cacheFlushInterval: 3600000, // This cache will clear itself every hour. deleteOnExpire: 'aggressive',
storageMode: 'localStorage'

KEY
angular-cache.caches.theCache.data.userInfo

VALUE: {"key":"userInfo","value":{"id":"114245370654600479826","email":"jeffthompson1971@gmail.com","verified_email":true,"name":"Jeff Thompson","given_name":"Jeff","family_name":"Thompson","link":"https://plus.google.com/114245370654600479826","picture":"https://lh3.googleusercontent.com/-DZDryCfO4Tc/AAAAAAAAAAI/AAAAAAAAAAA/jcWiT2tyduY/photo.jpg","gender":"male","locale":"en"},"created":1396377149944,"accessed":1396377149944,"expires":1396378049944}

\ AFTER I TRY TO SET userInfo again in exact same way**

{"key":"userInfo","value":{"key":"userInfo","value":{"id":"114245370654600479826","email":"jeffthompson1971@gmail.com","verified_email":true,"name":"Jeff Thompson","given_name":"Jeff","family_name":"Thompson","link":"https://plus.google.com/114245370654600479826","picture":"https://lh3.googleusercontent.com/-DZDryCfO4Tc/AAAAAAAAAAI/AAAAAAAAAAA/jcWiT2tyduY/photo.jpg","gender":"male","locale":"en"},"created":1396377149944,"accessed":1396377149944,"expires":1396378049944},"created":1396377149944,"accessed":1396377297529,"expires":1396378049944}

NOTICE that it's adding basically just nesting it .. if i set it third time it adds another nested level: {"key":"userInfo","value":{"key":"userInfo","value":{"key":"userInfo","value":{"id":"114245370654600479826","email":"jeffthompson1971@gmail.com","verified_email":true,"name":"Jeff Thompson","given_name":"Jeff","family_name":"Thompson","link":"https://plus.google.com/114245370654600479826","picture":"https://lh3.googleusercontent.com/-DZDryCfO4Tc/AAAAAAAAAAI/AAAAAAAAAAA/jcWiT2tyduY/photo.jpg","gender":"male","locale":"en"},"created":1396377491052,"accessed":1396377491052,"expires":1396378391052},"created":1396377491052,"accessed":1396377501182,"expires":1396378391052},"created":1396377491052,"accessed":1396377515682,"expires":1396378391052}

NOTE that if i just remove that option for localstorage mode, the cache works fine and i can alway write over userInfo as many times as I want without corruption.

I really want to use this guys.. can you fix this? any other info you need from me? I think this project is exactly what i need, but i want the localstorage support :)

jmdobry commented 10 years ago

@jeffthompson1971 I could fix this now, but I need to know:

  1. What version of angular-cache you are using.
  2. Exactly how you're using it. That means I need code examples. The best thing would be a jsfiddle or plunker that reproduces the bug.

Thanks!

jeffthompson1971 commented 10 years ago

Good stuff man... so i just did as you said and looked at the new docs.. all i had to do is import the module as :

angular-data.DSCacheFactory

And then inject into my service as follows and the rest just worked as i had it:

assetsApp.service('CacheService', ['DSCacheFactory', '$log', function ($ DSCacheFactory, $log) {

  var theCache = $DSCacheFactory('theCache', {
    maxAge: 900000, // Items added to this cache expire after 15

minutes. cacheFlushInterval: 3600000, // This cache will clear itself every hour. deleteOnExpire: 'aggressive',// Items will be deleted from this cache right when they expire. storageMode: 'localStorage' });

On Tue, Apr 1, 2014 at 2:15 PM, Jason Dobry notifications@github.comwrote:

@jeffthompson1971 https://github.com/jeffthompson1971 I could fix this now, but I need to know:

  1. What version of angular-cache you are using.
  2. Exactly how you're using it. That means I need code examples. The best thing would be a jsfiddle or plunker that reproduces the bug.

Thanks!

Reply to this email directly or view it on GitHubhttps://github.com/jmdobry/angular-cache/issues/109#issuecomment-39246383 .

jmdobry commented 10 years ago

@jeffthompson1971 I'm glad it's fixed in 3.x.x, but some (many) are using 2.x.x. If you have the time, could you please create a JSFiddle/Plunker that reproduces the bug with a 2.3.x version of angular-cache? That would really help.

You're welcome to use 3.x.x, but I'd like to fix that bug in 2.3.x for those who may be on angular-cache 2.3.x for a while.

jeffthompson1971 commented 10 years ago

I'm not familiar with JSFiddle/Plunker- but I can say that it's very easy to reproduce. Simply configure the cache service to use 'localstorage' as my service does below.

All you need to do is call CacheService.put("myKey", "someValue");

do that more than one time with the same key and you'll see how it just nests the value.. so really nothing to it.

// MY service that just initializes your and wraps the API so i can log my sets and gets

assetsApp.service('CacheService', function ($angularCacheFactory) {

var theCache = $angularCacheFactory('theCache', {
    maxAge: 900000,
    cacheFlushInterval: 3600000,
    deleteOnExpire: 'aggressive',
    *storageMode: 'localStorage' *

return {
    putItem: function (key, value) {
        console.log("cache storing " + key + " = " + value);

        theCache.put(key, value);
    },
    getItem: function (item) {

        var val = theCache.get(item);
        console.log("cache returning " + item + " = " + val);
        return val
    },
    info: function () {
        return theCache.info();
    }
}

On Tue, Apr 1, 2014 at 3:22 PM, Jason Dobry notifications@github.comwrote:

@jeffthompson1971 https://github.com/jeffthompson1971 I'm glad it's fixed in 3.x.x, but some (many) are using 2.x.x. If you have the time, could you please create a JSFiddle/Plunker that reproduces the bug with a 2.3.x version of angular-cache? That would really help.

You're welcome to use 3.x.x, but I'd like to fix that bug in 2.3.x for those who may be on angular-cache 2.3.x for a while.

Reply to this email directly or view it on GitHubhttps://github.com/jmdobry/angular-cache/issues/109#issuecomment-39253738 .

jmdobry commented 10 years ago

@jeffthompson1971

I created a Plunker in an attempt to reproduce the bug using angular-cache 2.3.3, but I see no bug. Take a look, perhaps I'm not correctly mirroring what is was you were doing.

jeffthompson1971 commented 10 years ago

so that looks right.. i'm not able to really run it properly or see what it's doing. when i hit 'run' and then look at my browsers local storage i see no entries at all. i also was using v. 2.3.1 not 2.3.3.

i did a fork so i coulid edit it and put an 'alert' in it but i nver see my alert either. I don't see any of the console.log messages either.. maybe i just dn't know how to use plunkr properly

On Tue, Apr 1, 2014 at 3:42 PM, Jason Dobry notifications@github.comwrote:

@jeffthompson1971 https://github.com/jeffthompson1971

I created a Plunker in an attempt to reproduce the bug using angular-cache 2.3.3, but I see no bug. Take a lookhttp://plnkr.co/edit/JNylEnPHlkdv6mylo9KP?p=preview, perhaps I'm not correctly mirroring what is was you were doing.

Reply to this email directly or view it on GitHubhttps://github.com/jmdobry/angular-cache/issues/109#issuecomment-39256060 .

jmdobry commented 10 years ago

@jeffthompson1971

I updated the Plunker to print what is in localStorage. Everything appears to be working.

jeffthompson1971 commented 10 years ago

Strange.. I could not get it to work.. But on 2.3.1... On Apr 1, 2014 4:23 PM, "Jason Dobry" notifications@github.com wrote:

@jeffthompson1971 https://github.com/jeffthompson1971

I updated the Plunkerhttp://plnkr.co/edit/JNylEnPHlkdv6mylo9KP?p=previewto print what is in localStorage. Everything appears to be working.

Reply to this email directly or view it on GitHubhttps://github.com/jmdobry/angular-cache/issues/109#issuecomment-39260931 .

jeffthompson1971 commented 10 years ago

Jason - so today I'm digging in a bit more on your solution. forgive my ignorance here, but can i use it not only for the caching and REST resourcing, but just also to wrap local storgage? i'm looking around and not sure where just basic data store API is.

so I see the http://angular-data.codetrain.io/documentation/api/angular-data/DS.sync_methods:get

get function, but where is the 'set' or 'add'? maybe i'm missing the point ;)

so the cache is working of course and it works great for me configured for localstorage. but what about just straight-up storeage? do i just use the cache API but set it to never expire? seems like a mis-use of 'cache'ing that way then?

On Tue, Apr 1, 2014 at 4:42 PM, Jeff Thompson jeffthompson1971@gmail.comwrote:

Strange.. I could not get it to work.. But on 2.3.1... On Apr 1, 2014 4:23 PM, "Jason Dobry" notifications@github.com wrote:

@jeffthompson1971 https://github.com/jeffthompson1971

I updated the Plunkerhttp://plnkr.co/edit/JNylEnPHlkdv6mylo9KP?p=previewto print what is in localStorage. Everything appears to be working.

Reply to this email directly or view it on GitHubhttps://github.com/jmdobry/angular-cache/issues/109#issuecomment-39260931 .

jmdobry commented 10 years ago

@jeffthompson1971 angular-cache and angular-data are two different projects.

angular-cache is an API-compatible replacement for Angular's $cacheFactory. It's a simple cache.

angular-data is (will be) a full-fledged datastore that provides an abstraction layer for working with RESTful resources. angular-data has no integration with localStorage at this time. Any data that gets injected into angular-data's datastore resides in memory for now.

If all you want is a wrapper for localStorage, angular-data is not the solution–use angular-cache instead. store.js is another option.

jmdobry commented 10 years ago

@jeffthompson1971 If you have usage questions about angular-cache, angular-cache has a mailing list.

If you have usage questions about angular-data, angular-data has a mailing list.

Those are the places to ask these types of questions.

jeffthompson1971 commented 10 years ago

Jason.. so i know you say it has no interaction with local storage, but it's working for me ;)

This is my service i'm using... and i can see my values getting written to local storage. I also can see the expirey works perfectly too and it deletes the values from local storage when they expire...

FYI i will use those mail lists going forward..just wanted to finish up this train of thought first...

so y do you say it doesn't write to local store ? :)

(maybe i'm using your new stuff like the old cach way and somehow the legacy code is still there?

assetsApp.service('CacheService', ['DSCacheFactory', '$log', function ($DSCacheFactory, $log) {

  var theCache = $DSCacheFactory('theCache', {
    maxAge: 90000, // Items added to this cache expire after 15 minutes.
    cacheFlushInterval: 3600000, // This cache will clear itself every

hour. deleteOnExpire: 'aggressive',// Items will be deleted from this cache right when they expire. storageMode: 'localStorage' });

return {
putItem: function (key, value) {
        $log.info("cache storing " + key + " = " + value);

        theCache.put(key, value);

},
getItem: function (item) {

        var val = theCache.get(item);
        $log.info("cache returning " + item + " = " + val);
        return val
},
info: function () {

return theCache.info();
}

}

// my localstorage in devTools:

{"key":"accessToken","value":"ya29.1.AADtN_W-xl-agvDhzg3CGDe0KFMRy0sAEUycSCo8E947WCbEa_XZ8F5P5UJAgg8","created":1396477471002,"accessed":1396477471002,"expires":1396478371002} {"key":"userInfo","value":{"id":"114245370654600479826","email":" jeffthompson1971@gmail.com","verified_email":true,"name":"Jeff Thompson","given_name":"Jeff","family_name":"Thompson","link":" https://plus.google.com/114245370654600479826","picture":" https://lh3.googleusercontent.com/-DZDryCfO4Tc/AAAAAAAAAAI/AAAAAAAAAAA/jcWiT2tyduY/photo.jpg ","gender":"male","locale":"en"},"created":1396477472682,"accessed":1396477472682,"expires":1396478372682}

On Wed, Apr 2, 2014 at 1:55 PM, Jason Dobry notifications@github.comwrote:

@jeffthompson1971 https://github.com/jeffthompson1971 angular-cache and angular-data are two different projects.

angular-cache is an API-compatible replacement for Angular's $cacheFactory. It's a simple cache.

angular-data is (will be) a full-fledged datastore that provides an abstraction layer for working with RESTful resources. angular-data has no integration with localStorage at this time. Any data that gets injected into angular-data's datastore resides in memory for now.

If all you want is a wrapper for localStorage, angular-data is not the solution-use angular-cache instead. store.jshttps://github.com/marcuswestin/store.js/is another option.

Reply to this email directly or view it on GitHubhttps://github.com/jmdobry/angular-cache/issues/109#issuecomment-39369287 .

jmdobry commented 10 years ago

@jeffthompson1971 You confused me when you said you were using angular-data. If you're using angular-cache then of course localStorage works.

Marking this bug as cannot reproduce.