Kenneth Cheung
Kenneth Cheung

Reputation: 63

Angular ng-repeat doesn't work with data fetched from mongodb

I am new for web development. If it is a silly question, I apologize for it. My ng-repeat shows not thing with the JSON fetched from mongodb, but it works when I pass a local JSON. I've struggled for it the whole day. Could anyone tell me what went wrong?

here is my Angular code

(function(){
  var app = angular.module('app', ['ngRoute']);
  app.controller('CommentController', ['$scope', '$http', function($scope, $http){

//I've tried 'this.comment', it still not work.
//It works when I use a test local JSON'this.comment = [{Visitor: 123, Comment: 345, CreateDate: 879}, {Visitor: 123, Comment: 345, CreateDate: 879}]
    $scope.comment = 
    $http({url: 'db-comments'}).success(function (comments) {

//I've confirmed 'comments' is an array of the JSON objects which I want.

      return comments;
    });
  }]);
})();

here is my HTML code

<div id="home" class="container" ng-controller='CommentController as comments'>
  <div id="comment" ng-repeat="x in comments.comment">
    <h2>{{x.Visitor}}</h2>
    <hr>
    <p>{{x.Comment}}<p>
    <span>{{x.CreateDate}}</span>
    <hr>
  </div>
</div>

here is my node.js code

router.get('/db-comments', function(req, res, next){
  Comment.find(function(err, data){
    if(err){
        console.log('can not fetch the data')
    }
    res.send(data);
  })
});

Thanks in advance!

Upvotes: 1

Views: 803

Answers (3)

Michel
Michel

Reputation: 28259

As it was pointed to you by scottseeker, you need to assign the http response data to your variable, not the promise.

However, because you are using the controller as syntax, that's not enough to make your example work. You need to set this.comment instead of $scope.comment. At first, you may want to write something like the following:

$http(...).success(function (comments) {
    this.comment = comments;  // don't write that
});

But be aware that the keyword this in a callback does not refer to the same this as outside. So if you use the controller as syntax, take the habit to write var vm = this; at the beginning of your controller, and set inside vm the variables you want to bind to the view (vm stands for viewmodel). Like that:

app.controller('CommentController', ['$http', function ($http) {
    var vm = this;

    $http({url: 'db-comments'}).success(function (comments) {
        vm.comment = comments;
    });
}]);

As a side note, if you are not setting specific headers to your $http call, I'll suggest you use the short method $http.get. That's more readable:

$http.get('db-comments').success(...)

Upvotes: 1

Bruno Duarte Brito
Bruno Duarte Brito

Reputation: 140

I don't really know how the $http service works on AngularJS, but i would guess that it returns a promise right?

Altough i'm not very familiar with promises, i would suggest you to do it this way:

(function() {
var app = angular.module('app', ['ngRoute']);
app.controller('CommentController', ['$scope', '$http', function($scope, $http) {

  $http({
    url: 'db-comments'
  }).success(function(response) {

      // Bind the variable here
      $scope.comment = response.data;

    });
  }]);
})();

I hope this works for you, if not, let me know. Good luck!

Upvotes: 0

scottseeker
scottseeker

Reputation: 64

$http returns a promise, set your scope variable in the 'then' portion.

Example:

       $http({url: 'db-comments'})
       then(function(response) {                    
          $scope.comment = response.data.
       }, function(response) {                  
          console.log('error: ' + response.error);
       });

Upvotes: 1

Related Questions