1

I'm beginner using AngularJS, and I have a question to ask.
I call a rest api to get comments by blog id, like following:

_getAllCommentsByBlogId(1, _convertComments);

function _getAllCommentsByBlogId(blogId, callback) {
    $http({
        method : "GET",
        url : "/api/v1/blogs/" + blogId + "/comments"
    }).then(function(res) {
        // success
        callback(res.data);

    }, function(res) {
        // error
        console.log("Error: " + res.status + " : " + res.data);
    });
}

The response data is converted for view task, like following:

function _convertComments(response) {
    $scope.comments = convert(response);
}

function convert(array) {
    var map = {};
    for (var i = 0; i < array.length; i++) {
        var obj = array[i];
        obj.children = [];
        map[obj.id] = obj;
        var parent = obj.parentId;

        if (!map[parent]) {
            map[parent] = {
                children : []
            };
        }
        map[parent].children.push(obj);
    }

    return map['0'].children;
}

After converting, i can view it as follows:

<div id="commentsApp"
  class="response-area"
  ng-app="commentsApp"
  ng-controller="CommentsController as c"
>
  <h2>3 RESPONSES</h2>

  <div>
    <script id="comments.template" type="text/ng-template">
      <div class="comment">
        {{comment.username}}
        <div ng-if="comment.showReply">
            <div class="form-group">
                <textarea autofocus class="form-control" row="3" ng-focus="c.showReply" ng-model="c.newComment.description"></textarea>
            </div>
            <div class="form-group">
                <button class="btn btn-danger" ng-click="c.reply(comment)">reply</button>
                <button class="btn btn-danger" ng-click="comment.showReply=false">cancel</button>
            </div>
        </div>
        <ng-include src="'comments.template'" ng-repeat="comment in comment.children"></ng-include>
      </div>
    </script>
    <ng-include
      src="'comments.template'"
      ng-repeat="comment in comments"
    ></ng-include>
  </div>
</div>

I try changing following part in view

<ng-include
  src="'comments.template'"
  ng-repeat="comment in comments"
></ng-include>

into

<ng-include
  src="'comments.template'"
  ng-repeat="comment in c.comments"
></ng-include>

and following part in js

function _convertComments(response) {
    $scope.comments = convert(response);
}

into

function _convertComments(response) {
    this.comments = convert(response);    
}

then the view doesn't show anything. I already worked in this way and everything seems to work as expected. Can you explain that?

I also read 'this' vs $scope in AngularJS controllers but my english is not good enough to understand it. Thanks

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Naul
  • 33
  • 7
  • Don't use callbacks with promise-based APIs. Use fat arrow (`=>`) functions in the `.then` method to bind the `this` context properly. – georgeawg Oct 12 '19 at 18:02

1 Answers1

1

When you use this inside some function in controller then it create its own context so its scope is different than outer scope which is actually a $scope.

So, best way to use this is, at the top of controller (starting of controller code) just define var vm = this; and then use vm everywhere where you're actually previously using $scope. This way you'll not encounter problems which you're facing now. (Btw on controller level scope you can still use this) e.g.

var vm = this;
...
function _convertComments(response) {
    vm.comments = convert(response)
}

Plunker Example

Check out these simple explanations: article1 , article2

Shantanu
  • 3,483
  • 2
  • 17
  • 20
  • I change code as you suggest, and it works now, now I can understand it. By the way, here's the link about using vm https://johnpapa.net/angularjss-controller-as-and-the-vm-variable/ – Naul Oct 13 '19 at 00:11