Access controller property from another Class in AngularJS - javascript

today I discovered the following problem while using AngularJS.
My Code is as follows:
app.controller("SomeController", function(){
this.foo = true
this.changeFoo = function(bool){
this.foo = bool
}
api.check(function(response){
this.changeFoo(response.bar)
})
})
(by the way: response & response.bar are not undefined)
api is an instance of my class API, defined outside of my Angular-code.
The problem is, that I can not change this.foo inside my callback-function.
What can I do to access this.foo?
Edit:
I tried to pass this as an argument, the result is the same
api.check(this, function(scope, response){
scope.foo = response.bar
})
scope seems to be defined inside this function, but the changes doesn't effect anything

You need to assign this to a different variable in your angular code before your Api call. Then use that variable to access your this variable. Like this
app.controller("SomeController", ['$scope',function($scope){
this.foo = true;
this.changeFoo = function(bool){
this.foo = bool;
$scope.$apply();
};
Var controller=this;
api.check(function(response){
controller.changeFoo(response.bar);
});
}]);

Related

Why don't you have to refer to an "intermediate" object in an Angular.js factory, when accessing the factory's objects?

I'm plugging along at this tutorial:
https://thinkster.io/mean-stack-tutorial
Which defines an Angular.js factory using this code:
app.factory('posts', [function(){
var o = {
posts: []
};
return o;
}]);
What I don't understand is that later in the controller, to populate the variable $scope.posts, the following code is used:
$scope.posts = posts.posts;
This works, while:
$scope.posts = posts.o.posts;
does not. I don't understand how you can access the "posts" variable in the "posts" factory directly; is this because by typing the code:
return o
all of the o objects's code is now considered to be part of the "posts" factory's code?
Variable o is not a property of the factory, it is just a temporary local variable. The factory source code is equivalent to:
app.factory('posts', [function(){
return {
posts: []
};
}]);
In general, this code:
var x = <some expression>;
return x;
is equivalent to:
return <some expression>;
This is beacause you are returning the entire object.
For exemple you can simplify this code:
app.factory('posts', [function(){
var o = {
posts: []
};
return o;
}]);
like this:
app.factory('posts', [function(){
return {
posts: []
};
}]);
It has the same logic, and you clearly canot do that posts.o.posts...
Imagine this in simpler terms.
Take a piece of code like this:
function foo()
{
var bar = {
baz: 5
};
return bar;
}
var myVar = foo();
At this point myVar refers to the bar that foo() created. It doesn't refer to foo()'s variables altogether.
So, to access bar.baz, you would do myVar.baz. You wouldn't do myVar.bar.baz.
The factory in Angular is essentially the same scenario, just wrapped as an Angular factory.

AngularJS: What is 'this' when AngularJS controller is a member function of a class?

I use a member function of a class to be AngularJS controller:
Note: the code below is compiled from some TypeScript code.
function Clazz(x) {
this.Member = x;
this.Func= function ($scope) {
$scope.message = '' + this.Member; // this.Member is undefined
}
}
app.controller('TaxCtrl', new Clazz('Hello').Func );
The Func is called when the I switch to the TaxCtrl, but the this seems not to be the instance of Clazz because this.Member is always undefined.
When Func is a member of the Clazz instance then this will work. When angular constructs the function as an object is is creating a new object where this is referencing the instance of Func.
Here is a jsbin example:
http://jsbin.com/rocopiwila/edit?js,console
If you are trying to share properties down to controllers use services and injectables instead.
Try this:
function Clazz(x) {
this.Member = x;
self = this;
this.Func= function ($scope) {
$scope.message = '' + self.Member;
}
}
app.controller('TaxCtrl', new Clazz('Hello').Func );

How use prototypical inheritance in controllers in node.js

I need make one Super Function inherit the this of other function and make this other function inherit the methods from the Super Function, this is possible?
Explanation:
I have my BookingController and I want make the Controller function inherit the this.ME property:
BookingController.js:
var Controller = require('../api/Controller');
function BookingController() {
Controller.call(this);
this.ME = 'something here';
}
BookingController.prototype = new Controller;
BookingController.constructor = BookingController;
Controller.js:
function Controller() {
console.log(this); // EMPTY
};
Controller.prototype.myMethod = function() {
// Should work if BookingController try to access.
}
But nothing happens, there is no error and the BookingController can't find my myMethod and my Controller can't my this.ME
You use a bit wrong inheritance model. I suggest you to use something like
BookingController.prototype = Object.create(Controller.prototype);
BookingController.prototype.constructor = BookingController;

Angular calling a parent method from an extended controller

I been spinning on this for days with no luck. I have BaseController with an init method among other things. I then wish to extend this controller and call the parents 'init' method from within the childs 'init' method.
The general answer for this is to call $scope.$parent.init($settings_object). However this is returning Error: $scope.$parent.init is not a function.
Generally the extended controller works fine being able to access the perents function and settings without issues. Just this example calling the same parent method from the child fails.
BaseController
(function( ){
var mainApp = angular.module("MyAppModule");
mainApp.controller('BaseController',function($scope, $rootScope,GLOBAL_CONFIG, ajaxRESTful,sharedValues, messageDisplay) { //base contorller
var bvm = this; //base vm
this.init = function($settings_object){
var keys = Object.keys($settings_object);
for(i=0;i<keys.length;i++){
bvm[keys[i]] = $settings_object[keys[i]];
}
}
//code remved to keep simple
});
})();
Extended controller
(function( ){
var app = angular.module('MyAppModule');
app.controller('RoleEdit', function($scope, $rootScope,$controller) {
angular.merge(this, $controller('BaseController', {$scope: $scope}));
var vm = this;
vm.newRoleFormData = [];
vm.role_id = null;
vm.mode = 'create';
vm.role = null;
vm.init = function ($object) {
console.log(vm);
console.log($scope.$parent);
$scope.$parent.init($object);
if(vm.role_id != null){
vm.loadInRole( );
}
};
}) //end contoller
})();//end of app
Why doesn't this work?
Is there a better way to do this?
The controller object (this) and the $scope object aren't directly related. There is no automatic wiring between them. $scope.$parent doesn't return a controller, it returns the parent scope. And since you registered your parent method in this.init instead of the usual $scope.init, you can't expect to find it using scopes.
You may circumvent this in a great number of ways, but as others have suggested, if you have functionality that is shared by many controllers, try to put it in a service instead. Maybe your BaseContoller itself should be a service.
You should do:
var parentInit = this.init.bind(this);
this.init = function ($object) {
parentInit($object);
if(vm.role_id != null){
vm.loadInRole( );
}
}

How can i pass scope in template in angular js

I have one BaseController with common functions which my all other controllers inherit .
The controller is like this
function BaseController () {
this.defaultFilters = {};
this.doStuff = function ($scope) {
$scope.myobj.value = 1;
this.otherfunction();
};
I inherit that in my controller like this
BaseController.call($scope);
Now in my do stuff function i need to pass $scope because myobj is only visible there.
Now i want to know that how can i pass that in my template because i want to call that function when some click on some button
ng-click="doStuff(scope)"
Everything that you associate with your controller's scope, so you just associate your scope with some variable and i guess that will do the job.
Something like this :
app.controller(function($scope) {
$scope.scope = $scope;
});
But if you go by some standard approach, i suggest moving these common functions inside some service, injecting this service into each controller and using it in the views.
Something like this :
app.service("constantService", function() {
this.data = {}; // This will represent your common data.
this.commonFunction = function() {
};
});
app.controller(function() {
$scope.constantService = constantService;
// You can now use $scope.constantService.data as your reference for data, and then can copy it to some local $scope variable whenever required.
});
ng-click="constantService.commonFunction()"

Categories

Resources