1

span is not displayed but the button in the li tag is being displayed if ng-repeat is not used , but once i use ng-repeat , neither the span nor the button is being displayed. I have used ng-repeat numerous times but never faced such a situation, both span and button elements are not displayed if I use ng-repeat in the li tag.

This is the index.html file:

<ul id="contactdelete">
    <li ng-repeat="contact in $ctrl.contacts">
        <span>{{contact.name}}</span>
        <button ng-click="$ctrl.deletecontact()">Delete</button>
    </li>
</ul>

This is the controller.js file

(function() {

    class ContactsComponent {
        constructor($http) {

            var result;

            $http.get("/api/contacts/").success(function(response) {

                result = response;

            });

            this.contacts = result;
        }
    }

    angular.module('myApp')
        .component('contacts', {
            templateUrl: 'app/contacts/contacts.html',
            controller: ContactsComponent
        });
})();
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
RohitB97
  • 440
  • 2
  • 6
  • 16

2 Answers2

1

this.contacts is empty as the success callback is async and its context is different from the constructor, which is why you can't use this directly.

Also, you should use the then function which takes 2 functions as arguments, one for success, the other as an error callback.

One way to work around this is making this a local variable, then using it inside the callback.

var self = this;
$http.get("/api/contacts/").then(function(response){

    self.contacts = response; // or response.data, depending of what you're receiving.

});

Or you could use the bind function:

$http.get("/api/contacts/").then(function(response){
    this.contacts = response; 

}.bind(this)); // notice the bind here

Angular provides its own bind implementation:

$http.get("/api/contacts/").then(angular.bind(this, function(response){

    this.contacts = response;

}));

Additional informations on scope and context:

Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • thanks man !.... but there were many instances where i used 'this' keyword . for example while using ng-model="$ctrl.logo" in the html file , i use this keyword for logo in the js file , but why cant i use the same syntax which i have been using for months , instead why should i create something called self again ? – RohitB97 Jul 21 '16 at 17:19
  • the `this` keyword refers to the context of the innermost function. The callbacks have their own context, which is not the context of the controller's constructor. Local variables are accessible from within a callback if defined inline, but the `this` value will change. You can inject the context with which a function is called with [`call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) or `apply`. To override the context of a callback and ensure that `this` is what you want, you may use `bind` as my second example. – Emile Bergeron Jul 21 '16 at 17:26
  • can you suggest a source , where i can learn about this in detail ! – RohitB97 Jul 22 '16 at 05:51
  • I added links to the end of my answer – Emile Bergeron Jul 22 '16 at 14:01
0

You should move this.contacts = result; to inside success function:

 $http.get("/api/contacts/").success(function(response){

     result = response;
     this.contacts = result;

  });

And i think you have to user result = response.data instead of result = response

Arun Ghosh
  • 7,634
  • 1
  • 26
  • 38