Skip to content

Commit

Permalink
Merge pull request #138 from ocombe/137-remove-hashkey
Browse files Browse the repository at this point in the history
fix: Always remove $$hashKey from object or array objects
  • Loading branch information
scotttrinh authored Apr 28, 2017
2 parents 66b72e5 + 1237fac commit 126a72f
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 10 deletions.
28 changes: 21 additions & 7 deletions src/angular-localForage.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,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() {
Expand All @@ -144,6 +138,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
Expand Down
86 changes: 83 additions & 3 deletions tests/angular-localForage.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,15 @@ describe('Module: LocalForageModule', function() {
it('setItem and getItem should work', function(done) {
var interval = triggerDigests();
var objectToStore = {
$$hashKey: 'object:1',
name: 'Scott Trinh'
};

spyOn($localForage._localforage, 'setItem').and.callThrough();

$localForage.setItem('myObject', objectToStore).then(function(data) {
expect(data).toEqual({ name: 'Scott Trinh' });
expect($localForage._localforage.setItem.calls.mostRecent().args[1]).toBe(objectToStore);
expect($localForage._localforage.setItem.calls.mostRecent().args[1]).toEqual({ name: 'Scott Trinh'});

$localForage.getItem('myObject').then(function(data) {
stopDigests(interval);
Expand All @@ -202,6 +203,84 @@ describe('Module: LocalForageModule', function() {
}, done);
});

it('setItem should remove $$hashKey from nested arrays', function () {
var arrayToStore = [
{
collection: [
{ $$hashKey: 'object:1' },
{ $$hashKey: 'object:2' }
],
deeperCollection: {
collection: [
{ $$hashKey: 'object:3' },
{ $$hashKey: 'object:4' }
]
}
}
];

$localForage.setItem('myArray', arrayToStore).then(function (data) {
expect(data).toEqual([
{
collection: [{}, {}],
deeperCollection: {
collection: [{}, {}]
}
}
]);
expect(arrayToStore).toEqual([
{
collection: [
{ $$hashKey: 'object:1' },
{ $$hashKey: 'object:2' }
],
deeperCollection: {
collection: [
{ $$hashKey: 'object:3' },
{ $$hashKey: 'object:4' }
]
}
}
]);
});
});

it('setItem works with arrays of non-objects, and strips the $$hashKey of any object', function () {
var arrayToStore = [
[[]],
[{}, {$$hashKey: 'object:1'}],
'string',
true,
false,
null,
undefined,
{},
];

$localForage.setItem('myWeirdArray', arrayToStore).then(function (data) {
expect(data).toEqual([
[[]],
[{}, {}],
'string',
true,
false,
null,
undefined,
{},
]);
expect(arrayToStore).toEqual([
[[]],
[{}, {$$hashKey: 'object:1'}],
'string',
true,
false,
null,
undefined,
{},
]);
});
});

it('setItem error should reject promise', function(done) {
var interval = triggerDigests();

Expand Down Expand Up @@ -482,7 +561,8 @@ describe('Module: LocalForageModule', function() {
var setWith = $localForage._localforage.setItem.calls.argsFor(0)[1];
var setWithNoPromise = $localForage._localforage.setItem.calls.argsFor(1)[1];
expect(setWith).not.toBe(objectToStore);
expect(setWith.childObject).toBe(objectToStore.childObject);
expect(setWith.childObject).not.toBe(objectToStore.childObject);
expect(setWith.childObject).toEqual(objectToStore.childObject);
expect(setWith).toEqual({
childObject: {}
});
Expand All @@ -491,7 +571,7 @@ describe('Module: LocalForageModule', function() {
childObject: {}
});

expect(setWithNoPromise).toBe(objectNoPromise);
expect(setWithNoPromise).toEqual(objectNoPromise);

$localForage.getItem('myObject').then(function(data) {
stopDigests(interval);
Expand Down

0 comments on commit 126a72f

Please sign in to comment.