TypeError: Unable to read comments on undefined properties using Angular

I follow this guide When I try to post a comment on a post, I get a TypeError: Cannot read property 'comments' of undefined error in my console.

mainCtrl,

 .controller('mainCtrl', ['$scope', 'posts', function($scope, posts){ $scope.posts = posts.posts; $scope.addPost = function(){ if(!$scope.title || $scope.title === '') { alert("Field can't left blank"); return; } $scope.posts.push({ title: $scope.title, upvotes: 0, comments: [ {author: 'Joe', body: 'Cool post!', upvotes: 0}, {author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0} ] }); }; } ]) 

and postCtrl,

 .controller('PostsCtrl', ['$scope', '$stateParams', 'posts', function($scope, $stateParams, posts){ $scope.post = posts.posts[$stateParams.id]; $scope.addComment = function(){ if($scope.body === '') { return; } $scope.post.comments.push({ body: $scope.body, author: 'user', upvotes: 0 }); $scope.body = ''; }; } ]) 

Both controllers are located in mainCtrl.js .

And here are my part.html and post.html parts that are enabled through router-ui.

 %script{:id => "/home.html", :type => "text/ng-template"} %h1 Flappernews %a{:href => "#/posts/{{$index}}"} Comments %script{:id => "/posts.html", :type => "text/ng-template"} %h2 Below here should be comments %span {{ post.comments }} %div{"ng-repeat" => "comment in post.comments | orderBy:'-upvotes'"} {{comment.upvotes}} - by {{comment.author}} %span{:style => "font-size:20px; margin-left:10px;"} {{comment.body}} %form{"ng-submit" => "addComment()"} %h3 Add a new comment .form-group %input.form-control{"ng-model" => "body", :placeholder => "Comment", :type => "text"} %button.btn.btn-primary{:type => "submit"} Post 

When I visit the homepage, I am redirected to localhost:3000/#/home . Then I can enter the title and publish it. When I click on the comments link, I redirect to http://localhost:3000/#/posts/ , and when I try to post a comment, I get

TypeError: Cannot read property 'comments' of undefined at Scope.$scope.addComment error.

+6
source share
4 answers

You have defined two separate controllers, no need to do this. If you look at this tutorial again, you will see that the addPost and addComment functions are inside the same controller, such as

  .controller('PostsCtrl', [ '$scope', '$stateParams', 'posts', function($scope, $stateParams, posts){ // Fetch post object from state parameter. $scope.post = posts.posts[$stateParams.id]; // Add Post. $scope.posts.push({ title: $scope.title, link: $scope.link, upvotes: 0, comments: [ {author: 'Joe', body: 'Cool post!', upvotes: 0}, {author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0} ] }); // Add comment. $scope.addComment = function(){ if($scope.body === '') { return; } $scope.post.comments.push({ body: $scope.body, author: 'user', upvotes: 0 }); $scope.body = ''; }; }]); 

add a comment and the comment runs on the same Post object, where the comment property is predefined.

+1
source

I am sure there is a problem with the link link. $ scope.posts = posts.posts; for accessing the posts object only. The CURD operation must be performed directly in the service.

$ scope.posts will automatically change because there is a link link between $ scope.posts and the posts.

Please make the following change. Hope it should work.

  $scope.addPost = function () { if (!$scope.title || $scope.title === '') { alert("Field can't left blank"); return; } posts.posts.push({ title: $scope.title, upvotes: 0, comments: [{ author: 'Joe', body: 'Cool post!', upvotes: 0 }, { author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0 }] }); }; 

Now you can exchange data between different controllers. The same should be done when adding a comment.

Main part:

you cannot receive a message like posts.posts [$ stateParams.id]; This will match the index of the array and return the object.

 angular.forEach(posts.posts, function (post) { if (post.id === parseInt($stateParams.id)) { $scope.post = post; return; } }) 

Hope this helps you.

0
source

In your "mainCrtl" you do not save / add new message data to your "posts" object, but are added to "$ scope.posts", therefore its reflection on your page with a link to a comment (let's say your newly created message identifier is' x ').

And when you click on the comments link and try to check the data that was not added before your "posts" object, that is .., the messages [x] are undefined (you did not add id 'x' data to maincrtl).

Hope I answered your question.

0
source

Since I cannot debug the code, so I will try to list all the possible reasons, and you can confirm what is true for your case

  • Make sure the new post is correctly clicked on the posts service.

Place a breakpoint after $scope.posts.push and log posts.posts to make sure the new object is added to the array

  1. Make sure PostsCtrl has the same posts.posts array with a new post added.

  2. Make sure $stateParams.id indeed a valid index for the posts.posts array

Hope this helps. If not, make a comment with the results.

0
source

All Articles