looping + rendering in backbone - backbone.js

render:function(output){
_.each(output, function(i){
p=i.name;
});
$(this.el).append(p);
}
here i am getting output in the form of json....i have 100 names...and i want to append it one after the another...in this case i get one name....
if i put like this...
render:function(output){
_.each(output, function(i){
p=i.name;
$(this.el).append(p);
});
}
inside the each loop nothing come...
do i need to make 100 variable like p here or is there any other way...

You need to provide the context, i.e. this. "this" is the reference to the current object you are working in. However, when you are calling a different function from within your current object, you are loosing the reference to your current object. Basically, this then refers to the the function. But you can easily fix this.
Either by adding this as an argument to the function call:
render:function(output){
_.each(output, function(i){
p=i.name;
$(this.el).append(p);
},this);
}
Or by providing this via a helper variable
render:function(output){
var self=this;
_.each(output, function(i){
p=i.name;
$(self.el).append(p);
});
}
I would go for option 1

Related

Backbone collection.reset function returns array

I have the following code in backbone view:
getAccounts: function() {
var filteredCollection = this.view.collection.reset(this.view.collection.where({ AccountStatus: 'Open' }));
return filteredCollection;
}
And I assume that this code returns me collection according to doc link http://backbonejs.org/#Collection-reset
But it returns an array. What is wrong here?
The documentation says
Returns the newly-set models
This means you get an array containing newly set models. It doesn't say it returns the collection itself. There is no reason to return the collection itself because you just performed this action on the collection and you already have access to it.
You can just do return this.view.collection instead.

How to use controller function in factory?

myapp.controller("controller1",function(factory_name){
function abc(){
//code of function
})
myapp.factor(""factory_name",function(){
return {
'name': function(){
i want to use function abc here
}
}
})
I want to use controller function into the factory.As I cant use $scope I am not able to use. I have searched many pages but failed with all solution I have found.
I'm not sure how you want to output to look like but to get you started you can get the keys and values of the dict as separate lists. Use dict.keys() and dict.values().

TypeError: push is not a function

Here is my code for factories.html
af.factory("PurchaseFactory",function(){
var productlist={products:[]};
return{
getpurchaseCart:function(){
return productlist;
},
addPurchaseCart:function(products){
productlist.products.push(products);
}
}
})
For Services.html
as.service("PurchaseService",function(PurchaseFactory){
this.getAllPurchase=function(){
return PurchaseFactory.getpurchaseCart();
}
this.addPurchase=function(products)
{
PurchaseFactory.addPurchaseCart(products);
}
})
For Controller.html
ac.controller("PurchaseController",function($scope,PurchaseService){
$scope.savepurchase=function(products){
if($scope.products._id==undefined){
$scope.products=angular.extend($scope.products,$scope.sizes)
PurchaseService.addPurchase($scope.products);
}
}
}
Here i have an another function in the same controller, as
$scope.saveorder=function(cartorder){
$scope.Mainpurchaselist=angular.extend($scope.cartorder,$scope.getpurchaseList)
CartService.addPurchaseCart($scope.Mainpurchaselist);
$scope.getpurchaseList.products={}
$scope.cartorder={}
$scope.products={}
$rootScope.isLogin=false;
CartService.deletecartyPurchase(idx);
Notification.success({message: 'your Cart Saving Successfully', delay: 1000});
}
In my HTML file, i have a button with function as savepurchase(products).
For first time its saving data but from second time its showing me error as TypeError:productlist.products.push is not a function. If I refresh the page its again saving the data, but continuously its not working.Let me know where the code goes wrong.
Here $scope.getpurchaselist.products={} is used to make a data null for every new purchase. If I remove the $scope.getpurchaselist.products={}, its working fine with no error but the problem is that the list is not getting null.
SO finally i have two ways
1. either to make it null by writing $scope.getpurchaselist.products={} but error as productlist.products.push is not a function let me know to overcome that error
2. Or to remove that line and let me know, how to make it null
I think, $scope.getpurchaseList.products={} is effecting you. As it passing an empty object instead of array as soon as the controller load. So, try removing it.
The condition if($scope.products._id==undefined) is breaking you. please check the logic you wrote. keep in mind $scope.products and products both are different variable in savepurchase function.
After extending $scope.products first time, condition return false.
change the $scope.products into just products. because u pass the products as paramater to the savepurchase() function. so no need to define as scope.products in ur controller

angular - fail to update array from service

I got a service that contain some contacts (name,phone). The controller has array that contain a reference to the array from the service so for every change on the array all gets updated.
Service:
app.service('ContactManagerService', function()
{
this.Contacts=[];
...
this.AddContact=function(Contact){...};
this.RemoveContact=function(Contact){...};
...
});
First question: Is this a good approach? Should every controller/directive need to have a direct reference to the original array from the service? I have read a lot about setting up some events from the service to the controllers when the array has been changed, but it sound stupid because the array on the controller will be change anyway (because its the same array) and the ng-repeat will be updated automatically.
Second problem: The service has a method that replace the array to new one:
this.ReplaceContacts=function(NewContacts)
{
this.Contacts=NewContacts;
});
The ng-repeat does not update because the controller still got the old reference to the old array. So a refresh need to be done.
I tried to replace the code to this one so the same array's reference wont change, but when the the code enter the foreach, this.Contacts array is undefined and the code stops. Why ?!
this.ReplaceContacts=function(NewContacts)
{
this.Contacts.splice(0, this.Contacts.length); //remove all contacts
NewContacts.forEach(function (contact, index)
{
this.Contacts.push(contact);//place the new ones
});
});
The controller code:
app.controller("myCtrl",
function ($scope,ContactManagerService)
{
$scope.Contacts = ContactManagerService.Contacts;
$scope.AddContact= function (Contact1) {
ContactManagerService.AddContact(Contact1);
}
$scope.RemoveContact = function (ContactID) {
ContactManagerService.RemoveContact(ContactID);
}
});
I hope everything is clear,
Thanks.
Because the callback function passed to forEach isn't bound to the service instance. So this, inside the callback, is not the service.
My advice: avoid this like the plague. It's an enormous source of bugs in JavaScript.
Use
var self = this;
at the top of the service, and use self instead of this everywhere.
Or bind the callback function to the service instance:
NewContacts.forEach(function (contact, index) {
...
}, this);
You can simply push elements to Contacts using Array.prototype.push()
The push() method adds one or more elements to the end of an array and returns the new length of the array.
this.ReplaceContacts=function(NewContacts){
this.Contacts.splice(0, this.Contacts.length); //remove all contacts
Array.prototype.push(this.Contacts, NewContacts);
});
As mentioned in previous anser, context of this in forEach loop is not what you think it is.
A simplification would be to use Array.prototype.concat():
var self = this;
self.ReplaceContacts = function (NewContacts) {
self.Contacts.splice(0, this.Contacts.length); //remove all contacts
self.Contacts.concat(NewContacts);
});

Passing arguments to a Backbone.View's constructor

I create a Backbone View
App.MyView = Backbone.View.extend({...});
then instance it like
new App.MyView();
but if my object needs some initial values i
new App.MyView({name:"Beautiful"});
I then would access this options from MyView like that
App.MyView= Backbone.View.extend({
initialize: function(){
console.log(this.options.name);
}
});
This works good, however is not a self-explanatory object: i have to know before hand the need of passing in the initial values in a literal way ({this.name:"Beautiful"}) in order to make MyView work..
How can i pass in arguments like initialize(name) or something like that to make it clear that the values are needed in the View?
Javascript functions don't have a defined number of arguments, so basically, you can't.
Writing:
function(name) {...}
is simply a shortcut for:
function() {
var name = arguments[0];
...
}
You could eventually throw an error is your argument is undefined:
function(name) {
if(typeof name === 'undefined') throw 'Error: missing argument';
...
}
But yeah, other than that, you can't force the use of an argument.
Edit:
If you're problem is just clarity, you cannot do that either I fear.
Edit2:
Well, you could if you really want to, but I'd really avoid walking those paths.

Resources