Storing a list of Items in Cookie in Angular - angularjs

im am trying to store a list of items in a cookie.
For Testing-Examples i use a list of citys.
It works so far but i always get the
SQLiteManager_currentLangue: and the XSRF-TOKEN: with it.
I dont really have an idea how to get rid of them both.
Any suggestions?
$scope.addToList = function(name,id) {
var cityToAdd = name;
var cityToAddID = id;
// ADD A CITY TO THE COOKIE -> WORKS
$cookies.put(cityToAddID, cityToAdd);
// SHOW THE NEW CITY_LIST ->WORKS
var allCitys = $cookies.getAll();
console.log(allCitys);
// PUT ALL INTO AN ARRAY -> WORKS
var favouritesFromCookie = [];
$.each(allCitys, function(index, value) {
console.log(value);
favouritesFromCookie.push(value);
});
// PUT THE ARRAY OF CITYS INTO A SCOPE_VARIABLE
$scope.favouriteFinal = favouritesFromCookie;
// GET RID OF THE LAST TWO ELEMENTS
}

You could give your own cookies a recognizable label and then grab that conditionally when you're compiling your array. Like so:
$cookies.put('city.' + cityToAddID, cityToAdd);
...
$.each(allCitys, function(index, value) {
if (index.indexOf('city.') == 0) { favouritesFromCookie.push(value) }
});

Related

passing objects in Angular

I know that passing objects in Angular is the same as passing objects in vanillaJs, what's stumping me is why my model is not being updated.
I have bins that contain packages. Given a packageId, I need to find the bin it's in, and remove the package from it.
vm.Bins = []; // bins of packages
vm.debinPackage = function (packageId) {
var bin = vm.getBin(packageId);
var packagge = vm.getPackage(packageId, bin.Packages);
vm.removePackageFromBin(packagge, bin);
};
vm.getBin = function (binId){
return $filter('filter')(vm.Bins, function(bin, index) {
return bin.Id == binId;
})[0];
};
vm.getPackage = function (packageId, packages) {
return $filter('filter')(packages, function(packageItem, index) {
return packageItem.Id == packageId;
})[0];
};
vm.removePackageFromBin = function (packagge, bin) {
bin = $filter('filter')(bin.Packages, function(packageItem, index) {
return packageItem.Id != packagge.Id;
});
};
.
<button ng-click="adminManifestVm.debinPackage(packageId)"></button>
{{ adminManifestVm.Bins }}
So, vm.Bins in my controller, and consequently adminManifestVm.Bins in my view don't update to reflect the package that's been removed from the bin.
i.e. this line:
vm.removePackageFromBin(packagge, bin);
does not actually result in an updated vm.Bins object.
I think the problem is that, when I get the bin object I use var as a holder:
var bin = vm.getBin(packageId);
and that it is somehow detached from my vm.Bins object.
but I can't figure out how to manipulate the actual object in vm.Bins.
I tried operating on the object directly, rather than through the var
vm.debinPackage = function (packageId) {
var binId = vm.getBinIdWithPackage(packageId);
var packagge = vm.getPackage(packageId, vm.getBin(binId).Packages);
vm.removePackageFromBin(packagge, vm.getBin(binId));
};
but not only does that not work, it starts to make my code unreadable.
How do I ensure that the bin object I am operating on is the one that's in vm.Bin, as opposed to some copy of it?
Have you tried using splice to remove the item from the array instead of reassigning the array with the filtered list?
vm.removePackageFromBin = function (package, bin) {
var idx = bin.indexOf(package);
bin.splice(idx, 1);
};

How to extend returned objects in the list returned by $asArray?

I'm having trouble decorate the objects in my list returned by $asArray in angularfire with a new method (not decorating the array itself).
The angularfire documentation seems to suggest that the right way to do this is to override the $$added method in the factory for $FirebaseArray, returning a new object that either encapsulates or extends the snapshot that gets passed in to that method. From the documentation:
// an object to return in our JokeFactory
app.factory("Joke", function($firebaseUtils) {
function Joke(snapshot) {
this.$id = snapshot.name();
this.update(snapshot);
}
Joke.prototype = {
update: function(snapshot) {
// apply changes to this.data instead of directly on `this`
this.data = snapshot.val();
},
makeJoke: function() {
alert("Why did the " + this.animal + " cross the " + this.obstacle + "?");
},
toJSON: function() {
// since we didn't store our data directly on `this`, we need to return
// it in parsed format. We can use the util function to remove $ variables
// and get it ready to ship
return $firebaseUtils.toJSON(this.data);
}
};
return Joke;
});
app.factory("JokeFactory", function($FirebaseArray, Joke) {
return $FirebaseArray.$extendFactory({
// change the added behavior to return Joke objects
$$added: function(snap) {
return new Joke(snap);
},
// override the update behavior to call Joke.update()
$$updated: function(snap) {
this.$getRecord(snap.name()).update(snap);
}
});
});
However, when I do this in my code, nothing ever gets added to the array, although I can see from outputting to the console that it is getting called.
var printMessageObjConstructor = function(snap) {
this.$id = snap.name();
this.snapshot = snap;
this.$update = function(snap) {
this.snapshot = snap;
};
this.printMessage = function() {
return this.author + "'s question is: " + this.body;
};
};
var ref = new Firebase("https://danculley-test.firebaseio.com/questions");
//What Am I Doing Wrong Here?
var arrayFactory = $FirebaseArray.$extendFactory({
$$added: function(snap, prevChild) {
var x = new printMessageObjConstructor(snap);
console.log("I am being called from FirebaseDecoratedCtlOverloadAddedinNewObj.");
return x;
},
$createObject: function(snap) {
return new printMessageObjConstructor(snap);
},
$$updated: function(snap) {
var i = this.$indexFor(snap.name());
var q = this.$list[i];
q.$update(snap);
}
});
var sync = $firebase(ref, {arrayFactory:arrayFactory});
var list = sync.$asArray();
list.$loaded(function(list) {
$scope.questions = list;
});
I've set up a new plunk stripped down to show the issue with a couple other use cases that I've tried. (The actual method I'm adding is more complex and isn't related to the view, but I wanted to do something simple to reproduce the issue.)
I think the issue is that I don't quite understand what exactly $$added is supposed to return, or what additional behavior beside returning the value to be stored $$added is supposed to have. There also doesn't really seem to be an $$added on the prototype or on $FirebaseArray to call as a super to get the default behavior. Can someone point me in the right direction?
UPDATE
For the benefit of others, after reviewing the like that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}
For the benefit of others, after reviewing the link that Kato posted, I was able to solve the issue by adding the following, almost all copied directly from the source except for the commented line below.
$$added: function(snap, prevChild) {
var i = this.$indexFor(snap.name());
if( i === -1 ) {
var rec = snap.val();
if( !angular.isObject(rec) ) {
rec = { $value: rec };
}
rec.$id = snap.name();
rec.$priority = snap.getPriority();
$firebaseUtils.applyDefaults(rec, this.$$defaults);
//This is the line that I added to what I copied from the source
angular.extend(rec, printMessageObj);
this._process('child_added', rec, prevChild);
}
}

Angularjs: Assigning Array within object

I am having an issue with losing data within an array when i try to assign it to a new array.
My object im using is as follows:
$scope.shops = [
{
name: "Kroger",
items: [ { itemName: "Chips"} ]
}
];
This is the code for the functions im using, it may be a callback issue? or something? Im losing the items info for the shop.
$scope.addItem = function(newItem, newShop){
var x = findShop(newShop);
x.items.push(newItem);
$scope.shops.push(x);
};
findShop = function(shopTag){
var old = angular.copy($scope.shops);
var tar = {
name: shopTag,
items: []
};
$scope.shops = [];
angular.forEach(old, function(shop, key){
if(shop.name === shopTag) {
tar.items = angular.copy(shop.items);
}
else {
$scope.shops.push(shop);
}
});
return tar;
};
the goal is to have the findShop function return a shop with the correct name, with empty items if there wasnt a shop previously, or with items full of the items if the shop was already created. then the addItem will push the item into the shop.items array and push the shop into the $scope
Any help is greatly appreciated!!!
You are right , it is this line which is causing the problem ,
tar.items = shop.items;
Try using it like this ,
tar.items = angular.copy(shop.items);
var old = $scope.shops; // old and $scope.shops point to the same place
..........
$scope.shops = []; // you assigned a new array that overrides the data
............
angular.forEach(old, function(shop, key){ // for each on an empty array????
If you dont want to point to the same reference use:
var copiedObject = angular.copy(objToCopy);
I guess the array is getting empty even before for loop.
Var old is reference to shops array, which you are making empty before foreach.. effectively making old empty...

Testing Angular Filter That Returns An Array with Jasmine

So, I'm having issues testing an angular filter that takes an array that has previously been sorted by a group property. It uses a flag property to indicate that the item is the first observation of that group, and then false for subsequent observations.
I'm doing this to have a category header in the UI with an ng-repeat directive.
When I test the filter, the output does not return the array with the flags unless I create new objects for the return array. This is a problem, because it causes an infinite loop when running in a webpage. The code works in the webpage when it just adds a flag property to the input object.
Is there some additional step I should be taking to simulate how angular handles filters so that it outputs the proper array?
This is what my test looks like right now.
describe('IsDifferentGroup', function() {
var list, itemOne, itemTwo, itemThree;
beforeEach(module("App.Filters"));
beforeEach(function () {
list = [];
itemOne = new ListItem();
itemTwo = new ListItem();
itemThree = new ListItem();
itemOne.group = "A";
itemTwo.group = "B";
itemThree.group = "C";
list.push(itemOne);
list.push(itemOne);
list.push(itemOne);
list.push(itemOne);
list.push(itemTwo);
list.push(itemThree);
list.push(itemThree);
list.push(itemThree);
list.push(itemThree);
list.push(itemThree);
});
it('should flag the items true that appear first on the list.', (inject(function (isDifferentGroupFilter) {
expect(list.length).toBe(10);
var result = isDifferentGroupFilter(list);
expect(result[0].isDifferentGroup).toBeTruthy();
expect(result[1].isDifferentGroup).toBeFalsy();
expect(result[4].isDifferentGroup).toBeTruthy();
expect(result[5].isDifferentGroup).toBeTruthy();
expect(result[6].isDifferentGroup).toBeFalsy();
expect(result[9].isDifferentGroup).toBeFalsy();
})));
});
And here is something like the code with the filter:
var IsDifferentGroup = (function () {
function IsDifferentGroup() {
return (function (list) {
var arrayToReturn = [];
var lastGroup = null;
for (var i = 0; i < list.length; i++) {
if (list[i].group != lastGroup) {
list[i].isDifferentGroup = true;
lastAisle = list[i].group;
} else {
list[i].isDifferentGroup = false;
}
arrayToReturn.push(list[i]);
}
return arrayToReturn;
});
}
return IsDifferentGroup;
})();
Thanks!
I figured out my issue.
When I was passing the items into the list, I just pushed a pointer to an item multiple times. I was not passing in unique objects so the flag was being overridden by the following flag in the array(I think). So, I just newed up 10 unique objects using a loop, pushed them into the array and ran it through the filter. And it worked.
I'm not entirely sure my analysis is correct about the override, because itemTwo was not being flagged as unique when it was the only itemTwo in the array. But the test is working as I would expect now so I'm going to stop investigating the issue.

Unable to remove the elements still the array get cleared

I am fetching the data from the server each 10 sec, in this, i am getting 3 type of the data,
After the timeout call, i am removing the existing data, i can witness the console show that the array clears, but the elements still keep append upon.
how can i clear both elements in the DOM and unbind as well..
my close function is keep called, but the elements not remove from DOM.
my single view :
singleton.view = Backbone.View.extend({
tagName :'article',
template0 : function(value){
var label = value === 0 ? "projectName" : value === 1 ? "assignedTo" :"projectName";
return _.template("<a href='#'><%= "+label+" %></a>");
},
template1 : _.template($('#boardTemplate').html()),
initialize :function(prams){
this.template = this['template'+0](prams.subTempNo);
},
close:function(){
console.log('clean up') // i am getting consoled
this.unbind();// i am unbinding
this.remove();// i am removing
},
render:function(){
var temp = this.template;
this.$el.html(temp(this.model.toJSON()));
return this;
}
});
return singleton.view;
in the views :
listViewAppender:function(item,i){
var listElement = new singleton.view({model:item,tempNo:0,subTempNo:i,tagName:'li'});
listElement.close(); // whenever i call the new instance i am removing old stuff..
this.$el.find('.'+this.classItems[i]).append(listElement.render().el);
},
How can i fix this issue.. any correct approach pelase..
Ok just a quick rework.....you're going to have to test it out. Comment with what happens and I'll correct the code below.
Can you try
listViewSet:function(key,i){
var l = this.listCatch.length;
if(l > 0){
for (var i = 0; i < l; i++) {
console.log(this.listCatch[i]);
this.listCatch[i].remove();
}
}
this.listCatch = [];
_.each(this.listCollection.models, function(model){
that.listViewAppender(model,i); //setting agian.
});
},
listViewAppender:function(item,i){
var listElement = new singleton.view({model:item,tempNo:0,subTempNo:i,tagName:'li'});
console.log(listElement);
this.$el.find('.'+this.classItems[i]).append(listElement.render().el);
this.listCatch[i] = listElement;
},
I gone through across my functions, i find the issue in the line of this.listCatch[i] = listElement; wrongly declared.
Later i declared the array by manually, it's works fine. in my initialize i introduced 3 arrays, what i required now it works fine.
this.listCatch = [];
for(var i=0;i<this.listItems.length; i+=1){
this.listCatch[i] = [];
}
So before pushing the model to array, now the array introduced solved the issue.

Resources