Skip to content

Commit 24bb0ee

Browse files
committed
Merge pull request scotttrinh#33 from GaelMagnan/master
feat: Added search functionality
2 parents 708a63b + 220110b commit 24bb0ee

File tree

3 files changed

+142
-2
lines changed

3 files changed

+142
-2
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This angularJS module is a rewrite of [angular-local-storage by grevory](https:/
1212
- Store your data in the best available storage solution that your browser can offer (IndexedDB / WebSQL or localstorage as a fallback)
1313

1414
- All browsers are supported starting at IE8. For the full list check: [IndexedDB support](http://caniuse.com/#search=indexeddb), [WebSQL support](http://caniuse.com/#search=websql) and [localstorage support](http://caniuse.com/#search=localstorage)
15-
15+
1616
- Everything is async and uses promises
1717

1818
- Use the service or the directive
@@ -60,6 +60,8 @@ angular.module('yourModule', ['LocalForageModule'])
6060

6161
- `length()`: returns the number of items stored (async, promise)
6262

63+
- `search(filter)`: returns all the items for which filter returns true (filter is a function taking key,value as params) (async, promise)
64+
6365
- `bind($scope, key/params object)`: lets you directly bind a LocalForage value to a $scope variable (async, promise)
6466
```js
6567
$localForage.bind($scope, 'myStorageKey');

src/angular-localForage.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,55 @@
125125
return deferred.promise;
126126
};
127127

128+
129+
// Get all the values for which the filter function returns true
130+
// filter should be a function that takes two parameters key, value and returns a boolean
131+
// return a list of item
132+
LocalForageInstance.prototype.search = function search(filter) {
133+
// throw error on undefined key
134+
if(angular.isUndefined(filter)) {
135+
throw new Error("You must define a filter");
136+
}
137+
if(!angular.isFunction(filter)) {
138+
throw new Error("filter must be a function");
139+
}
140+
var deferred = $q.defer(),
141+
args = arguments,
142+
self = this;
143+
144+
self._localforage.keys().then(function success(keyList) {
145+
var promises = [],
146+
datas = [],
147+
ret = [];
148+
angular.forEach(keyList, function(key){
149+
var d = $q.defer()
150+
self._localforage.getItem(self.prefix() + key)
151+
.then(function success(item) {
152+
datas.push({'key': key, 'value': item});
153+
d.resolve();
154+
},function failure(err){
155+
self.onError(data, args, self.search, deferred);
156+
});
157+
promises.push(d.promise);
158+
});
159+
$q.all(promises).then(function(){
160+
angular.forEach(datas, function(data){
161+
var key = data['key'],
162+
value = data['value'];
163+
if(filter(key, value))
164+
ret.push(value);
165+
});
166+
deferred.resolve(ret);
167+
},function(err){
168+
self.onError(data, args, self.search, deferred);
169+
});
170+
}, function error(data) {
171+
self.onError(data, args, self.search, deferred);
172+
deferred.reject(data)
173+
});
174+
return deferred.promise;
175+
};
176+
128177
// Remove an item from storage
129178
LocalForageInstance.prototype.removeItem = function removeItem(key) {
130179
// throw error on undefined key

tests/angular-localForage.js

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ describe('Module: LocalForageModule', function () {
66
var rootScope,
77
$injector,
88
myService,
9+
q,
910
spies = {};
1011

11-
beforeEach(inject(function ($rootScope) {
12+
beforeEach(inject(function ($rootScope, $q) {
1213
rootScope = $rootScope;
14+
q = $q;
1315
$injector = angular.injector(['LocalForageModule']);
1416
myService = $injector.get('$localForage');
1517

@@ -44,6 +46,11 @@ describe('Module: LocalForageModule', function () {
4446
expect(typeof myService.getItem).toBe('function');
4547
});
4648

49+
it('service:search should be defined', function () {
50+
expect(myService.search).toBeDefined();
51+
expect(typeof myService.search).toBe('function');
52+
});
53+
4754
it('service:removeItem should be defined', function () {
4855
expect(myService.removeItem).toBeDefined();
4956
expect(typeof myService.removeItem).toBe('function');
@@ -159,4 +166,86 @@ describe('Module: LocalForageModule', function () {
159166
run('webSQLStorage');
160167
});
161168

169+
170+
it('service:search should work', function() {
171+
function run(driver) {
172+
return runs(function() {
173+
return myService.setDriver(driver).then(function() {
174+
return myService.clear().then(function() {
175+
q.all(myService.setItem('myName', 'Olivier Combe'),
176+
myService.setItem('myPassion', 'AngularJs'),
177+
myService.setItem('myHobbie', 'Open Source')
178+
).then(function(all_rets) {
179+
180+
var promises = [];
181+
//test no filter
182+
var d1 = q.defer();
183+
myService.search(
184+
function(key, value){
185+
return true;
186+
}
187+
).then(function(data) {
188+
expect(data.length).toEqual(3);
189+
d1.resolve();
190+
}, function(res) {
191+
console.log(res);
192+
throw('Fail search, driver = '+driver)
193+
d1.reject();
194+
});
195+
promises.push(d1);
196+
197+
//test key filter
198+
var d2 = q.defer();
199+
myService.search(
200+
function(key, value){
201+
return key == 'myPassion';
202+
}
203+
).then(function(data) {
204+
expect(data.length).toEqual(1);
205+
expect(data[0]).toBe('AngularJs');
206+
d2.resolve();
207+
}, function(res) {
208+
console.log(res);
209+
throw('Fail search, driver = '+driver)
210+
d2.reject();
211+
});
212+
promises.push(d2);
213+
214+
//test value filter
215+
var d3 = q.defer();
216+
myService.search(
217+
function(key, value){
218+
return value == 'AngularJs';
219+
}
220+
).then(function(data) {
221+
expect(data.length).toEqual(1);
222+
expect(data[0]).toBe('AngularJs');
223+
d3.resolve();
224+
}, function(res) {
225+
console.log(res);
226+
throw('Fail search, driver = '+driver)
227+
d3.reject();
228+
});
229+
promises.push(d3);
230+
return q.all(promises);
231+
}, function(res) {
232+
console.log(res);
233+
throw('Fail set item, driver = '+driver)
234+
});
235+
}, function(res) {
236+
console.log(res);
237+
throw('Fail clear, driver = '+driver)
238+
})
239+
}, function( res ) {
240+
console.log(res);
241+
throw('Fail sets driver '+driver)
242+
})
243+
});
244+
}
245+
246+
// run('asyncStorage');
247+
run('localStorageWrapper');
248+
// run('webSQLStorage');
249+
});
250+
162251
});

0 commit comments

Comments
 (0)