AngularJS, $ http.get () and "controller as"

I am new to AngularJS all over the world and how it works, however I try my best to make it work as expected. I know this is due to the way I use $http.get() and trying to assign variables back to my controller, but I just can't figure it out.

Using $scope instead of this , I can make it work, however, if possible, I would prefer to use this , so I can use "controller as"

the code:

 app.controller('ctrlSuppliers', function($http){ this.supplierList = {}; $http.get("http://some_url_here") .success(function(response) { this.supplierList = response.records;}) .error(function() { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting Details'}];}); }); 

In this example, I cannot access the results from the $http.get request from the supplierList in the HTML page (ie {{ supplier.supplierList[0].supplier_name }} does not display any results)

I know that if I change the controller to $scope , I will get access to this data (although I do not use the same format as above), and I also know that the data is populated using console.log(this.supplierList) inside a .success call.

I also know that the reason it doesn’t work is because the this context is changed from inside the controller by calling $http.get .

So my question is this: how do you access the results of calling $ http.xxx using this instead of scope ? I read several different sources, but most of them talk about using $scope and promises. I did not find this cover using this (or declaring it with var supplier = this ). Any help would be greatly appreciated.

Thanks,

+7
javascript angularjs
source share
5 answers

Always keep a reference to the this variable so that you don’t have any problems with the context, and then use this variable instead of this on the controller

 app.controller('ctrlSuppliers', function($http){ var vm = this; // now can forget using "this" and use variable instead vm.supplierList = {}; $http.get("http://some_url_here") .success(function(response) { // no context issues since "vm" is in scope vm.supplierList = response.records; }); }); 
+9
source

For $ http, you have the option of storing your own objects in configObject , which is the optional second argument to $http.get() . This object then becomes available to you because it is a response property.

This method is especially useful if you call $ http.get () several times in a loop.

+2
source

This variable is complex in JavaScript. When the callback function is executed, you do not know what references this . Unless it's documented somewhere.

You must use .bind(this) to attach your own this value, which will be used in this function.

 app.controller('ctrlSuppliers', function($http){ this.supplierList = {}; $http.get("http://some_url_here") .success(function(response) { this.supplierList = response.records; }.bind(this)) .error(function() { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting Details'}]; }.bind(this)); }); 

See the binding guide:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

+2
source

With arrow functions available in ecmascript 6, the problem with this will take care, and you have less type. Your example would look like this:

 app.controller('ctrlSuppliers', function($http){ this.supplierList = {}; $http.get("http://some_url_here") .success(response => { this.supplierList = response.records; }) .error(() => { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting Details'}]; }); }); 

the result is equivalent to keeping this variable, but more concise.

+2
source

I think charlietfl's answer is correct, but think a slightly expanded explanation might be helpful.

"this" in javascript refers to the context of the current function call. If you look at your code, you will see that it is used in two functions -

 app.controller('ctrlSuppliers', function($http){ //first use of this - used in the context of the controller function //In this case, this = the controller this.supplierList = {}; $http.get("http://some_url_here") .success(function(response) { //second use of this - used in the context of the http success function callback //this will likely not be the controller. It value depends on how the caller (the $http framework) invoked the method. this.supplierList = response.records; }) .... 

Since they are two different functions, they can have completely different contexts, so "this" will refer to different objects (how you experience it).

The standard way to deal with this is to save the context of the first function call for use in others. @Charlietfl's answer is a good way to achieve this. I added its code for reference.

 app.controller('ctrlSuppliers', function($http){ var vm = this; vm.supplierList = {}; $http.get("http://some_url_here") .success(function(response) { vm.supplierList = response.records;}) }); 
+1
source

All Articles