I am trying to access the this object returned in the initialize function of a backbone view. In my initialize function I will
console.log(this)
and it will return an object for that view. When I access the view directly through my namespace architecture like:
console.log(mysite.some.namespace.View)
I get the following returned:
function (){a.apply(this,arguments)}
How can I have access to the the "this" object outside of logging it in my initialize function?
Related
I have a controller ctrl which has ctrl.$setValidity() method. I am doing angular.copy(ctrl,ctrlCopy) and I trying to access ctrlCopy.$setValidity() but I got error:
$setValidity is not a function.
I wonder why angular.copy doesn't copy all the $function from an object to another.
You can't angular.copy() a controller... period.
If you want to share a function then create a service that returns the function and inject the service into the two separate controllers
If I assign an object in a factory like this:
$http.get('/api/whatever').success(function(data) {
result = data.obj
});
It gives result a new address and therefore the reference from my controller to the result is broken.
How to assign it then? Value by value works, but seems not the right way. How to watch an object properly?
Basically factory has get and set methods for getting and setting the value in factory object.
Here is the example. Some time you may have to use events after updating the factory object so all others instance have updated value
In AngularJS is $scope actually the parent object's body? If so, does this mean that the controller in the image below (called "MainCtrl") is essentially setting two variables within the MODULE and that "categories" and "bookmarks" would now be available within the module called "Eggly?"
OR...
Is the function, passed in as the 2nd argument of the controller function actually NEWING UP a new empty object and passing that new object in as the $scope? That would indicate that the two variables are being set on the new object and the new object, with the new variables, would be set as the controller.
From a C# perspective
In C# it is common to pass in "this" when creating an instance of an object within an object IF the child needs to access the parent. The child would receive this and have access to any PUBLIC properties or methods. It appears that passing in $scope does something similar except that EVERYTHING in the parent is available from the child (probably a function).
Setting a property on $scope exposes the property to whoever sees this scope, typically child directives and controllers.
It doesn't set it "on the module" - whatever that means.
I have a function being used in my service that is defined as:
var getData = function() {
return anotherService.getData().$promise;
};
and a this property that I manipulate throughout the service.
this.someProperty = 'a string';
I call the above function inside the return section of my service:
return{
updateProperty: function(){
getData().then(function(data){
this.someProperty = data;
});
}
}
In the above, I get an this is undefined related error in my browser console. I assume this is because the resolved $promise is an AJAX call and this is used out of context. What's the best way to manipulate a this property using the returned data from an AJAX call in this instance?
if you're manipulating this throughout your service, assign it to a variable like var self = this. The problem is that this is the context of a function and can be changed by other code using fn.call(context) or fn.apply(context, args). So it's liable to be different inside of the scope of any given function.
So just assign it to some variable and use it:
var self = this;
return {
updateProperty: function(){
getData().then(function(data){
self.someProperty = data;
});
}
};
The simplest way would be to use the bind function. This function sets the 'this' context for the function call. So, in your case you'd have to use it twice so that the proper 'this' populates in.
return{
updateProperty: function(){
getData().then((function(data){
this.someProperty = data;
}).bind(this));
}
}
This comes to ensure that the handler you passed to the promise is executed with the original 'this' (passed to updateProperty). Now, to pass the correct 'this' value to the updateProperty function, you should, in your controller do:
(myService.updateProperty.bind(this))();
There are numerous versions of binding, including binding the entire service. Also, have a look at lodash for function extensions.
I prepared a small pen to demonstrate this. It covers what I listed above, plus another important thing to note. When you use setTimeout, the handler is invoked with in the global context (in this case, 'window'), this is why I added a third bind, to make sure 'this' is relevant inside the timeout handler. I also added various count increment calls to demonstrate that 'this' is the same value along the way.
If this is a repeating scenario, you might want to pass either the target object (and then use the handler just to know it was updated), or a handler (which also needs binding). I added examples for these scenarios as well.
One last word, call, apply and bind are key to javascript and worth learning. Put some time into it and work your way out of context hell.
In a controller, when I get a resource from a service
$scope.myVariable = MyObject.get($scope.id);
then myVariable is not defined as MyObject since it will be resolved later. Is there a way to inspect the variable in the controller (not in the service), for example for debugging or logging? Basically I am looking for something like
console.log("myVariable now has property "+ $scope.myVariable.myProperty);
From AngularJS Doc to $resource, you can read that:
It is important to realize that invoking a $resource object method
immediately returns an empty reference.
Once the data is returned from the server the existing reference is
populated with the actual data. This is a useful trick since usually
the resource is assigned to a model which is then rendered by the
view. Having an empty object results in no rendering, once the data
arrives from the server then the object is populated with the data and
the view automatically re-renders itself showing the new data. This
means that in most case one never has to write a callback function for
the action methods.
But, if you need to print the value of $scope.myVariable once it gets populated, you will have to define a callback function:
$scope.myVariable = MyObject.get($scope.id, function(myVar){
// From now, myVar == $scope.myVariable
console.log("myVariable now has property "+ myVar.myProperty);
});