diff --git a/CHANGELOG.md b/CHANGELOG.md index edf91ec..c16028f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ + +# 1.3.6 (2017-04-28) + + +## Bug Fixes + +- Always remove $$hashKey from object or array objects + ([1237fac1](https://github.com/ocombe/angular-localForage/commit/1237fac1b6536a739887819b5175044908f6d866)) + + # 1.3.5 (2017-02-22) diff --git a/bower.json b/bower.json index 4a71db7..f6a883c 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "angular-localforage", "main": "dist/angular-localForage.js", - "version": "1.3.5", + "version": "1.3.6", "homepage": "https://github.com/ocombe/angular-localForage", "authors": [ "Olivier Combe " diff --git a/dist/angular-localForage.js b/dist/angular-localForage.js index 0caca6a..351bbcd 100644 --- a/dist/angular-localForage.js +++ b/dist/angular-localForage.js @@ -1,6 +1,6 @@ /** * angular-localforage - Angular service & directive for https://github.com/mozilla/localForage (Offline storage, improved.) - * @version v1.3.5 + * @version v1.3.6 * @link https://github.com/ocombe/angular-localForage * @license MIT * @author Olivier Combe @@ -126,13 +126,7 @@ } else { var deferred = $q.defer(), args = arguments, - localCopy = value; - - //avoid $promises attributes from value objects, if present. - if(angular.isObject(localCopy) && angular.isDefined(localCopy.$promise)) { - localCopy = angular.extend({}, value); - delete localCopy.$promise; - } + localCopy = stripMeta(value); self._localforage.setItem(self.prefix() + key, localCopy) .then(function success() { @@ -151,6 +145,26 @@ return deferred.promise; } + + function stripMeta(value) { + var copy; + if (angular.isArray(value)) { + return value.map(stripMeta); + } else if (angular.isObject(value) && !(value instanceof Blob)) { + copy = angular.extend({}, value); + + angular.isDefined(copy.$promise) && delete copy.$promise; + angular.isDefined(copy.$$hashKey) && delete copy.$$hashKey; + + return Object + .keys(copy) + .reduce(function stripEntries(acc, key) { + acc[key] = stripMeta(copy[key]); + return acc; + }, {}); + } + return value; + } }; // Directly get a value from storage diff --git a/dist/angular-localForage.min.js b/dist/angular-localForage.min.js index bdb41f0..751761a 100644 --- a/dist/angular-localForage.min.js +++ b/dist/angular-localForage.min.js @@ -1,8 +1,8 @@ /** * angular-localforage - Angular service & directive for https://github.com/mozilla/localForage (Offline storage, improved.) - * @version v1.3.5 + * @version v1.3.6 * @link https://github.com/ocombe/angular-localForage * @license MIT * @author Olivier Combe */ -!function(e,r){"use strict";var t=e&&e.angular||window&&window.angular;if("function"==typeof define&&define.amd)define(["localforage"],function(e){return r(t,e)});else{if("object"!=typeof exports&&"object"!=typeof global)return r(t,e.localforage);"undefined"==typeof module?global.module.exports=r(t,require("localforage")):module.exports=r(t,require("localforage"))}}(this,function(e,r,t){"use strict";var n=e.module("LocalForageModule",["ng"]);return n.provider("$localForage",function(){var t={},n={name:"lf"},o={setItem:!1,removeItem:!1},i={};this.setNotify=function(e,r){o={setItem:e,removeItem:r}},this.config=function(r){if(!e.isObject(r))throw new Error("The config parameter should be an object");e.extend(n,r)},this.$get=["$rootScope","$q","$parse",function(a,f,s){var u=function(t){e.isDefined(t)?this._localforage=r.createInstance(t):(this._localforage=r,r.config(n))};u.prototype.createInstance=function(r){if(e.isObject(r)){if(r=e.extend({},n,r),e.isDefined(t[r.name]))throw new Error("A localForage instance with the name "+r.name+" is already defined.");return t[r.name]=new u(r),t[r.name]}throw new Error("The parameter should be a config object.")},u.prototype.instance=function(r){if(e.isUndefined(r))return t[n.name];if(e.isString(r)){if(e.isDefined(t[r]))return t[r];throw new Error("No localForage instance of that name exists.")}throw new Error("The parameter should be a string.")},u.prototype.setDriver=function(e){return this._localforage.setDriver(e)},u.prototype.driver=function(){return this._localforage.driver()},u.prototype.defineDriver=function(e){return this._localforage.defineDriver(e)},u.prototype.setItem=function(r,t){if(e.isUndefined(r))throw new Error("You must define a key to set");var n=this;if(e.isArray(r)){if(!e.isArray(t))throw new Error("If you set an array of keys, the values should be an array too");return f.all(r.map(function(e,r){return n.setItem(e,t[r])}))}var i=f.defer(),s=arguments,u=t;return e.isObject(u)&&e.isDefined(u.$promise)&&(u=e.extend({},t),delete u.$promise),n._localforage.setItem(n.prefix()+r,u).then(function(){o.setItem&&a.$broadcast("LocalForageModule.setItem",{key:r,newvalue:u,driver:n.driver()}),i.resolve(u)})["catch"](function(e){n.onError(e,s,n.setItem,i)}),i.promise},u.prototype.getItem=function(r,t){if(e.isUndefined(r))throw new Error("You must define a key to get");var n,o=f.defer(),i=arguments,a=this;if(e.isArray(r)){var s=[],u=0;n=a._localforage.iterate(function(e,t){var n=r.indexOf(a.prefix()+t);return n>-1&&(s[n]=e,u++),u===r.length?s:void 0}).then(function(){for(var n=!0,i=0;ii;i++)o.push(r[i].substr(t.prefix().length,r[i].length));r=o}e.resolve(r)},function(n){t.onError(n,r,t.keys,e)}),e.promise};return u.prototype.keys=l,u.prototype.getKeys=l,u.prototype.length=function(){var e=f.defer(),r=arguments,t=this;return t._localforage.length().then(function(r){e.resolve(r)},function(n){t.onError(n,r,length,e)}),e.promise},u.prototype.bind=function(r,o){if(e.isString(o))o={key:o};else if(!e.isObject(o)||e.isUndefined(o.key))throw new Error("You must define a key to bind");var a={defaultValue:"",name:n.name};o=e.extend({},a,o);var f=t[o.name];if(e.isUndefined(f))throw new Error("You must use the name of an existing instance");var u=o.scopeKey||o.key,l=s(u);return f.getItem(o.key).then(function(t){return null!==t?l.assign(r,t):e.isUndefined(o.defaultValue)||(l.assign(r,o.defaultValue),f.setItem(o.key,o.defaultValue)),e.isDefined(i[o.key])&&i[o.key](),i[o.key]=r.$watch(u,function(r){e.isDefined(r)&&f.setItem(o.key,r)},!0),t})},u.prototype.unbind=function(r,o){if(e.isString(o))o={key:o};else if(!e.isObject(o)||e.isUndefined(o.key))throw new Error("You must define a key to unbind");var a={scopeKey:o.key,name:n.name};o=e.extend({},a,o);var f=t[o.name];if(e.isUndefined(f))throw new Error("You must use the name of an existing instance");return s(o.scopeKey).assign(r,null),e.isDefined(i[o.key])&&(i[o.key](),delete i[o.key]),f.removeItem(o.key)},u.prototype.prefix=function(){return"localStorageWrapper"===this.driver()&&n.oldPrefix?this._localforage.config().name+".":""},u.prototype.onError=function(r,t,n,o){if((e.isObject(r)&&r.name?"InvalidStateError"===r.name:e.isString(r)&&"InvalidStateError"===r)&&"asyncStorage"===this.driver()||e.isObject(r)&&r.code&&5===r.code){var i=this;i.setDriver("localStorageWrapper").then(function(){n.apply(i,t).then(function(e){o.resolve(e)},function(e){o.reject(e)})},function(){o.reject(r)})}else o.reject(r)},t[n.name]=new u,t[n.name]}]}),n.directive("localForage",["$localForage",function(r){return{restrict:"A",link:function(t,n,o){var i=t.$eval(o.localForage);e.isObject(i)&&e.isDefined(i.key)?r.bind(t,i):r.bind(t,o.localForage)}}}]),n.name}); \ No newline at end of file +!function(e,r){"use strict";var t=e&&e.angular||window&&window.angular;if("function"==typeof define&&define.amd)define(["localforage"],function(e){return r(t,e)});else{if("object"!=typeof exports&&"object"!=typeof global)return r(t,e.localforage);"undefined"==typeof module?global.module.exports=r(t,require("localforage")):module.exports=r(t,require("localforage"))}}(this,function(e,r,t){"use strict";var n=e.module("LocalForageModule",["ng"]);return n.provider("$localForage",function(){var t={},n={name:"lf"},o={setItem:!1,removeItem:!1},i={};this.setNotify=function(e,r){o={setItem:e,removeItem:r}},this.config=function(r){if(!e.isObject(r))throw new Error("The config parameter should be an object");e.extend(n,r)},this.$get=["$rootScope","$q","$parse",function(a,f,s){var u=function(t){e.isDefined(t)?this._localforage=r.createInstance(t):(this._localforage=r,r.config(n))};u.prototype.createInstance=function(r){if(e.isObject(r)){if(r=e.extend({},n,r),e.isDefined(t[r.name]))throw new Error("A localForage instance with the name "+r.name+" is already defined.");return t[r.name]=new u(r),t[r.name]}throw new Error("The parameter should be a config object.")},u.prototype.instance=function(r){if(e.isUndefined(r))return t[n.name];if(e.isString(r)){if(e.isDefined(t[r]))return t[r];throw new Error("No localForage instance of that name exists.")}throw new Error("The parameter should be a string.")},u.prototype.setDriver=function(e){return this._localforage.setDriver(e)},u.prototype.driver=function(){return this._localforage.driver()},u.prototype.defineDriver=function(e){return this._localforage.defineDriver(e)},u.prototype.setItem=function(r,t){function n(r){var t;return e.isArray(r)?r.map(n):!e.isObject(r)||r instanceof Blob?r:(t=e.extend({},r),e.isDefined(t.$promise)&&delete t.$promise,e.isDefined(t.$$hashKey)&&delete t.$$hashKey,Object.keys(t).reduce(function(e,r){return e[r]=n(t[r]),e},{}))}if(e.isUndefined(r))throw new Error("You must define a key to set");var i=this;if(e.isArray(r)){if(!e.isArray(t))throw new Error("If you set an array of keys, the values should be an array too");return f.all(r.map(function(e,r){return i.setItem(e,t[r])}))}var s=f.defer(),u=arguments,c=n(t);return i._localforage.setItem(i.prefix()+r,c).then(function(){o.setItem&&a.$broadcast("LocalForageModule.setItem",{key:r,newvalue:c,driver:i.driver()}),s.resolve(c)})["catch"](function(e){i.onError(e,u,i.setItem,s)}),s.promise},u.prototype.getItem=function(r,t){if(e.isUndefined(r))throw new Error("You must define a key to get");var n,o=f.defer(),i=arguments,a=this;if(e.isArray(r)){var s=[],u=0;n=a._localforage.iterate(function(e,t){var n=r.indexOf(a.prefix()+t);return n>-1&&(s[n]=e,u++),u===r.length?s:void 0}).then(function(){for(var n=!0,i=0;ii;i++)o.push(r[i].substr(t.prefix().length,r[i].length));r=o}e.resolve(r)},function(n){t.onError(n,r,t.keys,e)}),e.promise};return u.prototype.keys=c,u.prototype.getKeys=c,u.prototype.length=function(){var e=f.defer(),r=arguments,t=this;return t._localforage.length().then(function(r){e.resolve(r)},function(n){t.onError(n,r,length,e)}),e.promise},u.prototype.bind=function(r,o){if(e.isString(o))o={key:o};else if(!e.isObject(o)||e.isUndefined(o.key))throw new Error("You must define a key to bind");var a={defaultValue:"",name:n.name};o=e.extend({},a,o);var f=t[o.name];if(e.isUndefined(f))throw new Error("You must use the name of an existing instance");var u=o.scopeKey||o.key,c=s(u);return f.getItem(o.key).then(function(t){return null!==t?c.assign(r,t):e.isUndefined(o.defaultValue)||(c.assign(r,o.defaultValue),f.setItem(o.key,o.defaultValue)),e.isDefined(i[o.key])&&i[o.key](),i[o.key]=r.$watch(u,function(r){e.isDefined(r)&&f.setItem(o.key,r)},!0),t})},u.prototype.unbind=function(r,o){if(e.isString(o))o={key:o};else if(!e.isObject(o)||e.isUndefined(o.key))throw new Error("You must define a key to unbind");var a={scopeKey:o.key,name:n.name};o=e.extend({},a,o);var f=t[o.name];if(e.isUndefined(f))throw new Error("You must use the name of an existing instance");return s(o.scopeKey).assign(r,null),e.isDefined(i[o.key])&&(i[o.key](),delete i[o.key]),f.removeItem(o.key)},u.prototype.prefix=function(){return"localStorageWrapper"===this.driver()&&n.oldPrefix?this._localforage.config().name+".":""},u.prototype.onError=function(r,t,n,o){if((e.isObject(r)&&r.name?"InvalidStateError"===r.name:e.isString(r)&&"InvalidStateError"===r)&&"asyncStorage"===this.driver()||e.isObject(r)&&r.code&&5===r.code){var i=this;i.setDriver("localStorageWrapper").then(function(){n.apply(i,t).then(function(e){o.resolve(e)},function(e){o.reject(e)})},function(){o.reject(r)})}else o.reject(r)},t[n.name]=new u,t[n.name]}]}),n.directive("localForage",["$localForage",function(r){return{restrict:"A",link:function(t,n,o){var i=t.$eval(o.localForage);e.isObject(i)&&e.isDefined(i.key)?r.bind(t,i):r.bind(t,o.localForage)}}}]),n.name}); \ No newline at end of file diff --git a/package.json b/package.json index e32246a..22eae39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular-localforage", - "version": "1.3.5", + "version": "1.3.6", "description": "Angular service & directive for https://github.com/mozilla/localForage (Offline storage, improved.)", "license": "MIT", "main": "dist/angular-localForage.js",