how to apply filter functionality on a particular trees node rather on the whole tree - angularjs

I am searching for compName-1 in the search box. It is returning all the repos in which this compName-1 string is found.
I dont want the search option to search in all the repos. I want it to search in particular repo which is checked. Is there any way to achieve it?
Please find my problem in this plunker. https://plnkr.co/edit/iCOiJDjeP8httwnf2c0t?p=preview
Controller.js
var app = angular.module('testApp', []);
app.controller('treeTable', ['$scope', '$http', function ($scope, $http) {
$scope.list = [];
$scope.list.push({name: "repo 1", version:"0.0", size:"0", description:" ", label: "", date: "XXX", id:"repo1"});
$scope.list.push({name: "repo 8", version:"0.0", size:"0", description:" ", label: "", date: "XXX", id:"repo2"});
$scope.list.push({name: "repo 7", version:"0.0", size:"0", description:" ", label: "", date: "XXX", id:"repo3"});
$scope.displayChildren = function(item, id) {
console.log(item.showTree);
item.showTree = !item.showTree;
console.log(id);
if(id === 'repo'+1) {
if(!(item.children && item.children.length > 0)) {
$http.get("List_repo1.json")
.then(function(response) {
console.log('response repo1');
item.children = response.data.response.repoBundles;
item.showTree = true;
});
}
}
if(id === 'repo'+2) {
if(!(item.children && item.children.length > 0)) {
$http.get("List_repo2.json")
.then(function(response) {
console.log('response repo2');
item.children = response.data.response.repoBundles;
item.showTree = true;
});
}
}
if(id === 'repo'+3) {
if(!(item.children && item.children.length > 0)) {
$http.get("List_repo3.json")
.then(function(response) {
console.log('response repo3');
item.children = response.data.response.repoBundles;
item.showTree = true;
});
}
}
};
$scope.toggleChildren = function(item, parentItem) {
console.log(parentItem);
if(parentItem !== void 0) {
if(parentItem.bundles !== void 0) {
$scope.$emit('changeBundles', parentItem);
} else if(parentItem.item.children !== void 0) {
console.log('parent child');
$scope.$emit('changeParent', parentItem);
}
}
if (item.children !== void 0) {
console.log(item.children);
console.log('inside children');
$scope.$broadcast('changeChildren', item);
} else if(item.components !== void 0){
console.log(item + 'inside comp');
$scope.$broadcast('changeComponents', item);
}
};
$scope.toggleAllCheckboxes = function ($event) {
var i, item, len, ref, results, selected;
selected = $event.target.checked;
if(selected) {
$scope.selectedCheckbox = false;
} else {
$scope.selectedCheckbox = true;
}
ref = $scope.list;
results = [];
for (i = 0, len = ref.length; i < len; i++) {
item = ref[i];
item.selected = selected;
if (item.children != null) {
results.push($scope.$broadcast('changeChildren', item));
} else {
results.push(void 0);
}
}
return results;
};
$scope.$on('changeChildren', function (event, parentItem) {
var child, i, len, ref, results;
ref = parentItem.children;
results = [];
console.log(ref === void 0);
for (i = 0, len = ref.length; i < len; i++) {
child = ref[i];
child.selected = parentItem.selected;
console.log("child" + child);
if (child.components != null) {
console.log("inside if " + child.components);
results.push($scope.$broadcast('changeComponents', child));
} else {
results.push(void 0);
}
}
return results;
});
$scope.$on('changeComponents', function (event, parentItem) {
var child, i, len, ref, results;
ref = parentItem.components;
results = [];
console.log(parentItem.selected);
for (i = 0, len = ref.length; i < len; i++) {
child = ref[i];
child.selected = parentItem.selected;
console.log("child" + child.selected + child.value);
}
});
$scope.$on('changeParent', function (event, parentScope) {
var children;
children = parentScope.item.children;
parentScope.item.selected = $filter('selected')(children).length === children.length;
parentScope = parentScope.$parent.$parent;
if (parentScope.item != null) {
return $scope.$broadcast('changeParent', parentScope);
}
});
$scope.$on('changeBundles', function (event, parentScope) {
var children;
children = parentScope.bundles.components;
parentScope.bundles.selected = $filter('selected')(children).length === children.length;
parentScope = parentScope.$parent.$parent;
if (parentScope.item !== null) {
return $scope.$broadcast('changeParent', parentScope);
}
});
}]);
app.filter('selected', [
'$filter',
function ($filter) {
return function (files) {
return $filter('filter')(files, { selected: true });
};
}
]);

Related

problems with ng-show angularjs

ng-show did not work clearly for me in angular js.
this is the "loading" div:
<div class="loader" ng-show="vm.loadingNotifications" ng-cloak>loading...</div>
and that's the API call in the controller:
function getNotifications(userId) {
if (vm.generalNotifications.length > 0) {
vm.loadingNotifications = false;
} else {
vm.loadingNotifications = true;
$.ajax({
type: 'GET',
url: AppConfig.apiUrl + 'Notifications/GetAllNotificationsByUserId?userId=' + userId,
success: function (notifications) {
if (notifications) {
$("#all-not").addClass("active");
if (notifications.length > 0) {
let tempNotifications = [];
for (let j = 0; j < notifications.length; j++) {
let element = notifications[j];
let title = getSpecificConst(element.NotificationTitle)
element.NotificationTitle = title;
let text = getSpecificConst(element.NotificationText)
element.NotificationText = text;
tempNotifications.push(element);
}
vm.generalNotifications = sortArray(tempNotifications);
vm.displayedNotifications = sortArray(tempNotifications);
vm.isEmptyNotifications = false;
}
else {
vm.isEmptyNotifications = true;
}
} else {
vm.isEmptyNotifications = true;
}
vm.loadingNotifications = false;
}
});
}
}
the VM loading is updating clearly, but the ng-show stack always in true.
you need to use AngularJS Scope on the controller.
$scope.vm = {
generalNotifications:[],
loadingNotifications: false,
....
};
function getNotifications(userId) {
if ($scope.vm.generalNotifications.length > 0) {
$scope.vm.loadingNotifications = false;
} else {
$scope.vm.loadingNotifications = true;
.....
}

Rewriting ng-options with ng-repeat so it works with md-select

I am trying to transform a Bootstrap select field into Angular Material, but am having difficulty getting the code to work with ng-repeat, instead of ng-options. The original code looks like this:
<select name="{{field.name}}" ng-model="fieldValue" ng-model-options="{getterSetter: true}" sn-select-width="auto" ng-disabled="field.isReadonly()" ng-options="c.value as c.label for c in field.choices track by c.value">
The new AngularJS Material html code looks like this:
<md-select name="{{field.name}}" ng-model="fieldValue" ng-disabled="field.isReadonly()">
<md-option ng-value="c.value" ng-repeat="c in field.choices | filter:searchTerm track by c.value">{{c.label}}</md-option>
</md-select>
The selected item from md-select won't save in the back-end table. What am I missing here? I am pretty sure not being able to use ng-options is causing this issue, but how do I fix it with ng-repeat?
UPDATE: The rest of the out of the box directive code is below for reference.
link: function(scope, element, attrs, ngModel) {
scope.clearSearchTerm = function() {
scope.searchTerm = '';
};
var g_form = scope.getGlideForm();
var field = scope.field;
var fieldOptions;
var isOpen = false;
scope.fieldValue = function() {
return field.value;
};
g_form.$private.events.on('change', function(fieldName, oldValue, newValue) {
if (fieldName == field.name) {} else if (fieldName == field.dependentField) {
field.dependentValue = newValue;
refreshChoiceList();
} else if (typeof field.variable_name !== 'undefined' && field.reference_qual && isRefQualElement(fieldName)) {
refreshReferenceChoices();
}
});
function isRefQualElement(fieldName) {
var refQualElements = [];
if (field.attributes && field.attributes.indexOf('ref_qual_elements') > -1) {
var attributes = spUtil.parseAttributes(field.attributes);
refQualElements = attributes['ref_qual_elements'].split(',');
}
return field.reference_qual.indexOf(fieldName) != -1 || refQualElements.indexOf(fieldName) != -1;
}
function refreshChoiceList() {
var params = {};
params.table = g_form.getTableName();
params.field = field.name;
params.sysparm_dependent_value = field.dependentValue;
var url = urlTools.getURL('choice_list_data', params);
return $http.get(url).success(function(data) {
field.choices = [];
angular.forEach(data.items, function(item) {
field.choices.push(item);
});
selectValueOrNone();
});
}
function selectValueOrNone() {
var hasSelectedValue = false;
angular.forEach(field.choices, function(c) {
if (field.value == c.value)
hasSelectedValue = true;
});
if (!hasSelectedValue && field.choices.length > 0) {
g_form.setValue(field.name, field.choices[0].value, field.choices[0].label);
}
}
function refreshReferenceChoices() {
var params = [];
params['qualifier'] = field.reference_qual;
params['table'] = field.lookup_table;
params['sysparm_include_variables'] = true;
params['variable_ids'] = field.sys_id;
var getFieldSequence = g_form.$private.options('getFieldSequence');
if (getFieldSequence) {
params['variable_sequence1'] = getFieldSequence();
}
var itemSysId = g_form.$private.options('itemSysId');
params['sysparm_id'] = itemSysId;
var getFieldParams = g_form.$private.options('getFieldParams');
if (getFieldParams) {
angular.extend(params, getFieldParams());
}
var url = urlTools.getURL('sp_ref_list_data', params);
return $http.get(url).success(function(data) {
field.choices = [];
angular.forEach(data.items, function(item) {
item.label = item.$$displayValue;
item.value = item.sys_id;
field.choices.push(item);
});
selectValueOrNone();
});
}
var pcTimeout;
g_form.$private.events.on('propertyChange', function(type, fieldName, propertyName) {
if (fieldName != field.name)
return;
if (propertyName == "optionStack") {
$timeout.cancel(pcTimeout);
pcTimeout = $timeout(function() {
field.choices = applyOptionStack(fieldOptions, field.optionStack);
selectValueOrNone();
}, 35);
}
});
setDefaultOptions();
if (field.choices) {
setChoiceOptions(field.choices);
}
selectValueOrNone();
function setDefaultOptions() {
setChoiceOptions([{
value: scope.field.value,
label: scope.field.displayValue || scope.field.placeholder
}]);
}
function setChoiceOptions(options) {
if (options) {
options.forEach(function(option) {
option.value = String(option.value);
});
}
fieldOptions = options;
scope.options = applyOptionStack(options, scope.field.optionStack);
}
function applyOptionStack(options, optionStack) {
if (!optionStack || optionStack.length == 0) {
return options;
}
var newOptions = angular.copy(options);
if (!newOptions) {
newOptions = [];
}
optionStack.forEach(function(item) {
switch (item.operation) {
case 'add':
for (var o in newOptions) {
if (newOptions[o].label == item.label)
return;
}
var newOption = {
label: item.label,
value: item.value
};
if (typeof item.index === 'undefined') {
newOptions.push(newOption);
} else {
newOptions.splice(item.index, 0, newOption);
}
break;
case 'remove':
var itemValue = String(item.value);
for (var i = 0, iM = newOptions.length; i < iM; i++) {
var optionValue = String(newOptions[i].value);
if (optionValue !== itemValue) {
continue;
}
newOptions.splice(i, 1);
break;
}
break;
case 'clear':
newOptions = [];
break;
default:
}
});
return newOptions;
}
}
};
}

How do I optimize filtering in AngularJS?

I have here a filter for AngularJS. Is there any better way for this?
return function (data, selected) {
var result = [];
if (selected[0] == 'All Types') {
result = data;
}
else {
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < selected.length; j++) {
if (data[i].Type == selected[j]) {
result.push(data[i]);
}
}
}
}
return result;
};
return function (data, selected) {
var result = [];
if (selected[0] == 'All Types') {
result = data;
}
else {
result=data.filter(x=>selected.indexOf(x.Type)>-1);
}
return result;
};
Obviously this is using lodash, but native methods can be substituted:
return (data, selected) => {
return
_.first(selected) === 'All Types' ? data :
_.reduce(data, (sum, value, key) => {
if (_.includes(selected, value.Type)) {
sum.push(value);
}
return sum;
}, []);
}
Use data for selected value. I am assuming selected value is in data[i].selected.
return function (data) {
var result = [];
if (data[0].selected == 'All Types') {
result = data;
}
else {
for (var i = 0; i < data.length; i++) {
if (data[i].Type == data[i].selected) {
result.push(data[i]);
}
}
}
return result;
};
We can use filters
return function (data) {
if (data[0].selected == 'All Types') {
return data;
}
else {
return data.filter(function (item) {
return item.Type == item.selected;
});
}
};

angularjs ng-repeat not update

I used the ng-repeat in the ion-slide and operated the array myTags in the controller,ion-slide-tab-label was custom directive.When I changed the array,ng-repeat view has not changed.If I use the method remove() and then add() the same tag,it would be error:duplicate. Here's the code.
slidingTabsDirective.js
var slidingTabsDirective = angular.module("ionic").directive('ionSlideTabs', ['$timeout', '$compile', '$interval', '$ionicSlideBoxDelegate', '$ionicScrollDelegate', '$ionicGesture', function($timeout, $compile, $interval, $ionicSlideBoxDelegate, $ionicScrollDelegate, $ionicGesture) {
return {
require: "^ionSlideBox",
restrict: 'A',
link: function(scope, element, attrs, parent) {
var ionicSlideBoxDelegate;
var ionicScrollDelegate;
var ionicScrollDelegateID;
var slideTabs;
var indicator;
var slider;
var tabsBar;
var options = {
"slideTabsScrollable": true
};
var init = function() {
if (angular.isDefined(attrs.slideTabsScrollable) && attrs.slideTabsScrollable == false) {
options.slideTabsScrollable = false;
}
var tabItems = '<li ng-repeat="(key, value) in tabs" ng-click="onTabTabbed($event, {{key}})" class="slider-slide-tab" ng-bind-html="value"></li>';
if (options.slideTabsScrollable) {
//alert(options.slideTabsScrollable)
ionicScrollDelegateID = "ion-slide-tabs-handle-" + Math.floor((Math.random() * 10000) + 1);
tabsBar = angular.element('<ion-scroll delegate-handle="' + ionicScrollDelegateID + '" class="slidingTabs" direction="x" scrollbar-x="false"><ul>' + tabItems + '</ul> <div class="tab-indicator-wrapper"><div class="tab-indicator"></div></div> </ion-scroll>');
} else {
tabsBar = angular.element('<div class="slidingTabs"><ul>' + tabItems + '</ul> <div class="tab-indicator-wrapper"><div class="tab-indicator"></div></div> </div>');
}
slider = angular.element(element);
var compiled = $compile(tabsBar);
slider.parent().prepend(tabsBar);
compiled(scope);
//get Tabs DOM Elements
indicator = angular.element(tabsBar[0].querySelector(".tab-indicator"));
//get the slideBoxHandle
var slideHandle = slider.attr('delegate-handle');
var scrollHandle = tabsBar.attr('delegate-handle');
ionicSlideBoxDelegate = $ionicSlideBoxDelegate;
if (slideHandle) {
ionicSlideBoxDelegate = ionicSlideBoxDelegate.$getByHandle(slideHandle);
}
if (options.slideTabsScrollable) {
ionicScrollDelegate = $ionicScrollDelegate;
if (scrollHandle) {
ionicScrollDelegate = ionicScrollDelegate.$getByHandle(scrollHandle);
}
}
addEvents();
setTabBarWidth();
slideToCurrentPosition();
};
var addEvents = function() {
ionic.onGesture("dragleft", scope.onSlideMove, slider[0]);
ionic.onGesture("dragright", scope.onSlideMove, slider[0]);
ionic.onGesture("release", scope.onSlideChange, slider[0]);
};
var setTabBarWidth = function() {
if (!angular.isDefined(slideTabs) || slideTabs.length == 0) {
return false;
}
tabsList = tabsBar.find("ul");
var tabsWidth = 0;
angular.forEach(slideTabs, function(currentElement, index) {
var currentLi = angular.element(currentElement);
tabsWidth += currentLi[0].offsetWidth;
});
if (options.slideTabsScrollable) {
angular.element(tabsBar[0].querySelector(".scroll")).css("width", tabsWidth + 1 + "px");
} else {
slideTabs.css("width", tabsList[0].offsetWidth / slideTabs.length + "px");
}
slideToCurrentPosition();
};
var slideToCurrentPosition = function() {
if (!angular.isDefined(slideTabs) || slideTabs.length == 0) {
return false;
}
var targetSlideIndex = ionicSlideBoxDelegate.currentIndex();
var targetTab = angular.element(slideTabs[targetSlideIndex]);
var targetLeftOffset = targetTab.prop("offsetLeft");
var targetWidth = targetTab[0].offsetWidth;
indicator.css({
"-webkit-transition-duration": "300ms",
"-webkit-transform": "translate(" + targetLeftOffset + "px,0px)",
"width": targetWidth + "px"
});
if (options.slideTabsScrollable && ionicScrollDelegate) {
var scrollOffset = 40;
ionicScrollDelegate.scrollTo(targetLeftOffset - scrollOffset, 0, true);
}
slideTabs.removeClass("tab-active");
targetTab.addClass("tab-active");
};
var setIndicatorPosition = function(currentSlideIndex, targetSlideIndex, position, slideDirection) {
var targetTab = angular.element(slideTabs[targetSlideIndex]);
var currentTab = angular.element(slideTabs[currentSlideIndex]);
var targetLeftOffset = targetTab.prop("offsetLeft");
var currentLeftOffset = currentTab.prop("offsetLeft");
var offsetLeftDiff = Math.abs(targetLeftOffset - currentLeftOffset);
if (currentSlideIndex == 0 && targetSlideIndex == ionicSlideBoxDelegate.slidesCount() - 1 && slideDirection == "right" ||
targetSlideIndex == 0 && currentSlideIndex == ionicSlideBoxDelegate.slidesCount() - 1 && slideDirection == "left") {
return;
}
var targetWidth = targetTab[0].offsetWidth;
var currentWidth = currentTab[0].offsetWidth;
var widthDiff = targetWidth - currentWidth;
var indicatorPos = 0;
var indicatorWidth = 0;
if (currentSlideIndex > targetSlideIndex) {
indicatorPos = targetLeftOffset - (offsetLeftDiff * (position - 1));
indicatorWidth = targetWidth - ((widthDiff * (1 - position)));
} else if (targetSlideIndex > currentSlideIndex) {
indicatorPos = targetLeftOffset + (offsetLeftDiff * (position - 1));
indicatorWidth = targetWidth + ((widthDiff * (position - 1)));
}
indicator.css({
"-webkit-transition-duration": "0ms",
"-webkit-transform": "translate(" + indicatorPos + "px,0px)",
"width": indicatorWidth + "px"
});
if (options.slideTabsScrollable && ionicScrollDelegate) {
var scrollOffset = 40;
ionicScrollDelegate.scrollTo(indicatorPos - scrollOffset, 0, false);
}
};
scope.onTabTabbed = function(event, index) {
ionicSlideBoxDelegate.slide(index);
slideToCurrentPosition();
};
scope.tabs = [];
scope.addTabContent = function($content) {
$content = $content.replace(/\“/g, '').replace(/\”/g, '');
scope.tabs.push($content);
scope.$apply();
$timeout(function() {
slideTabs = angular.element(tabsBar[0].querySelector("ul").querySelectorAll(".slider-slide-tab"));
slideToCurrentPosition();
setTabBarWidth();
});
};
scope.onSlideChange = function(slideIndex) {
slideToCurrentPosition();
};
scope.onSlideMove = function() {
var scrollDiv = slider[0].getElementsByClassName("slider-slide");
var currentSlideIndex = ionicSlideBoxDelegate.currentIndex();
var currentSlide = angular.element(scrollDiv[currentSlideIndex]);
var currentSlideLeftOffset = currentSlide.css('-webkit-transform').replace(/[^0-9\-.,]/g, '').split(',')[0];
var targetSlideIndex = (currentSlideIndex + 1) % scrollDiv.length;
if (currentSlideLeftOffset > slider.prop("offsetLeft")) {
targetSlideIndex = currentSlideIndex - 1;
if (targetSlideIndex < 0) {
targetSlideIndex = scrollDiv.length - 1;
}
}
var targetSlide = angular.element(scrollDiv[targetSlideIndex]);
var position = currentSlideLeftOffset / slider[0].offsetWidth;
var slideDirection = position > 0 ? "right" : "left";
position = Math.abs(position);
setIndicatorPosition(currentSlideIndex, targetSlideIndex, position, slideDirection);
};
init();
},
controller: ['$scope', function($scope) {
this.addTab = function($content) {
$timeout(function() {
if ($scope.addTabContent) {
$scope.addTabContent($content);
}
});
};
}]
};
}]);
slidingTabsDirective.directive('ionSlideTabLabel', [function() {
return {
require: "^ionSlideTabs",
link: function($scope, $element, $attrs, $parent) {
$parent.addTab($attrs.ionSlideTabLabel);
}
};
}]);
index.html
<ion-slide-box id="slide_box" show-pager="false" ion-slide-tabs>
<ion-slide ng-repeat="tag in myTags track by $index" ion-slide-tab-label=“{{tag.tagname}}”>
.........
</ion-slide>
</ion-slide-box>
service.js
function getTags() {
var url = xxxxxxx;
return $http({
method: 'GET',
url: url
})
.success(function(res) {
//console.log('is collect success');
})
.error(function(msg, code) {
console.log('tag error.....', code);
});
}
indexCtrl.js
$scope.tags = [];
$scope.myTags = [];
$scope.moreTags = [];
function getTags() {
ds.getTags()
.then(function(res) {
var traTags = [];
var l = res.data.length;
$scope.tags = res.data;
traTags = angular.copy($scope.tags);
$scope.myTags = traTags.splice(0, l / 2);
$scope.moreTags = traTags;
});
}
function remove(index) {
if (!$scope.lock) {
$scope.moreTags.unshift($scope.myTags[index]);
$scope.myTags.splice(index, 1);
} else {
return;
}
}
function add(index) {
$scope.myTags.push($scope.moreTags[index]);
$scope.moreTags.splice(index, 1);
}
what should I do? please help me! Thank you!
function:
function addlist(obj, item, addtype) {
var isdata = false;
for (var i = 0; i < obj.length; i++) {
if (obj[i] == item) {
isdata = true;
break;
}
}
if (!isdata) {
if (addtype) {
obj.push(item);
} else {
obj.unshift(item);
}
}
}
code:
function remove(index) {
if (!$scope.lock) {
addlist($scope.moreTags,$scope.myTags[index],false);
$scope.myTags.splice(index, 1);
} else {
return;
}
}
function add(index) {
addlist($scope.myTags,$scope.moreTags[index],true);
$scope.moreTags.splice(index, 1);
}

AngularJS Property Bag

Is there a formal property bag for Angular? I need a way to temporarily store variables and optionally save them between apps.
To save time, I whipped one up. It's here if anyone needs it, however I would love to find one in a framework that is supported by a team:
/**
* Created by Fred Lackey on 4/24/15.
*/
(function (module) {
var propertyBag = function (localStorage) {
var items = [];
var getIndex = function (key) {
if (!key || !key.trim || key.trim().length < 1) { return -1; }
if (items.length < 1) { return -1; }
for (var i = 0; i < items.length; i += 1) {
if (items[i].key.toLowerCase() === key.toLowerCase()) { return i; }
}
return -1;
};
var exists = function (key) {
return (getIndex(key) >= 0);
};
var getItem = function (key) {
var index = getIndex(key);
return (index >= 0) ? items[index] : null;
};
var getValue = function (key) {
var index = getIndex(key);
return (index >= 0) ? items[index].value : null;
};
var putItem = function (key, value) {
if (!key || !key.trim || key.trim().length < 1) { return; }
var index = getIndex(key);
if (index >= 0) {
items[index].value = value;
} else {
items.push({ key: key, value: value });
}
};
var removeItem = function (key) {
var index = getIndex(key);
if (index >= 0) { items.splice(index, 1); }
};
var count = function () {
return items.length;
};
var saveBag = function (key) {
if (!key || !key.trim || key.trim().length < 1) { return; }
localStorage.add(key, items);
};
var loadBag = function (key) {
if (!key || !key.trim || key.trim().length < 1) { return; }
var bag = localStorage.get(key);
if (!bag || !bag.length) { return; }
for (var i = 0; i < bag.length; b += 1) {
if (!bag[i].key || !bag[i].key.trim || bag[i].key.trim().length < 1) { continue; }
putItem(bag[i].key, bag[i].value);
}
localStorage.remove(key);
};
return {
getItem: getItem,
exists: exists,
getValue: getValue,
putItem: putItem,
removeItem: removeItem,
count: count,
save: saveBag,
load: loadBag
};
};
module.factory('propertyBag', propertyBag);
})(angular.module('common'));
Here's the local storage code if you don't already have one (referenced in the code above)...
(function (module) {
var localStorage = function ($window) {
var store = $window.localStorage;
var add = function (key, value) {
value = angular.toJson(value);
store.setItem(key, value);
};
var get = function (key) {
var value = store.getItem(key);
if (value) {
value = angular.fromJson(value);
}
return value;
};
var remove = function (key) {
store.removeItem(key);
};
return {
add: add,
get: get,
remove: remove
}
};
module.factory('localStorage', localStorage);
})(angular.module('common'));

Resources