0

I am trying to add comments from html form elements to array in angularjs. When I use javascipt push function I got an error "property of object doesn't exist". Can someone help me to solve this issue. Below you can find my javascript and html code:

Thank you for reading

    .controller('DishDetailController', ['$scope', function($scope) {

            var dish={
                          name:'Uthapizza',
                          image: 'images/uthapizza.png',
                          category: 'mains', 
                          label:'Hot',
                          price:'4.99',
                          description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
                           comments: [
                               {
                                   rating:5,
                                   comment:"Imagine all the eatables, living in conFusion!",
                                   author:"John Lemon",
                                   date:"2012-10-16T17:57:28.556094Z"
                               },
                               {
                                   rating:4,
                                   comment:"Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
                                   author:"Paul McVites",
                                   date:"2014-09-05T17:57:28.556094Z"
                               },
                               {
                                   rating:3,
                                   comment:"Eat it, just eat it!",
                                   author:"Michael Jaikishan",
                                   date:"2015-02-13T17:57:28.556094Z"
                               },
                               {
                                   rating:4,
                                   comment:"Ultimate, Reaching for the stars!",
                                   author:"Ringo Starry",
                                   date:"2013-12-02T17:57:28.556094Z"
                               },
                               {
                                   rating:2,
                                   comment:"It's your birthday, we're gonna party!",
                                   author:"25 Cent",
                                   date:"2011-12-02T17:57:28.556094Z"
                               }
                               
                           ]
                    };
            
            $scope.dish = dish;
            
        }])

        .controller('DishCommentController', ['$scope', function($scope) {


            $scope.newcomment = {
                rating : "",
                comment: "",
                author: "",
                date: new Date().toISOString()
        };
            $scope.submitComment = function () {
                
                //Step 2: This is how you record the date


                $scope.dish.comments.push($scope.newcomment);
                
              
            }
        }])

;
<!DOCTYPE html>
<html lang="en" ng-app="confusionApp">

<head>
     <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  
       <link href="../bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="../bower_components/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet">
    <link href="../bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="styles/bootstrap-social.css" rel="stylesheet">
    <link href="styles/mystyles.css" rel="stylesheet">
<!-- endbuild -->

   
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body>

    <div class="container">
        <div class="row row-content" ng-controller="DishDetailController">
            <div class="media" ng-model="dish">
                <div class="media-left media-middle">
                    <a href="#">
                        <img class="media-object img-thumbnail" ng-src={{dish.image}} alt="Uthapizza">
                    </a>
                </div>
                <div class="media-body">
                    <h2 class="media-heading"> {{dish.name}}
                        <span class="label label-danger">
            {{dish.label}}
        </span>
                        <span class="badge">
            {{dish.price | currency}}
        </span>
                    </h2>
                    <p>{{dish.description}}</p>
                </div>

            </div>
        </div>
        <br>
        <br>
        <br>

        <div class="col-xs-9 col-xs-offset-1" ng-controller="DishDetailController">
            <h4>Customer Comments</h4> Sort by:
            <input type="text" ng-model="filterText">
            <blockquote ng-repeat="commentla in dish.comments | orderBy: filterText">
                <p class="mb-0">  {{commentla.rating}} Stars </p>
                <p class="mb-0">{{commentla.comment}}</p>
                <footer class="blockquote-footer"> {{commentla.author}} {{commentla.date | date: 'mediumDate'}} </footer>
            </blockquote>
        </div>
    </div>

            <div class="col-xs-9 col-xs-offset-1" ng-controller="DishCommentController">
                    <ul class="list-unstyled">
                   Your Name: {{newcomment.author}}
                        <br>
                        Comment:  {{newcomment.comment}}
                        <br>
                        Your Rating: {{newcomment.rating}}


					<!--	<p>Task 3: Here you include the code to show the live preview of the comment</p>
						<p>The comment should be shown only when the form contains valid
						information and is not pristine</p> -->
                    </ul>
                <form class="form-horizontal" name="commentForm" ng-submit="submitComment()" novalidate>
                    <div class="form-group">
                        <label for="yname" class="col-sm-2 control-label">Your Name:</label>
                        <div class="col-sm-10">
                        <input type="text" class="form-control" id="yname" aria-des                <div class="col-sm-10">
                        <label class="radio-inline">
                            <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="1" ng-model="newcomment.rating"> 1
                        </label>
                        <label class="radio-inline">
                            <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="2" ng-model="newcomment.rating"> 2
                        </label>
                        <label class="radio-inline">
                            <input type="radio" name="inlineRadioOptions" id="inlineRadio3" value="3" ng-model="newcomment.rating"> 3
                        </label>
                        <label class="radio-inline">
                            <input type="radio" name="inlineRadioOptions" id="inlineRadio4" value="4" ng-model="newcomment.rating"> 4
                        </label>
                        <label class="radio-inline">
                            <input type="radio" name="inlineRadioOptions" id="inlineRadio5" value="5" ng-model="newcomment.rating"> 5
                        </label>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="commentm" class="col-sm-2 control-label">Your Comment</label>
                        <div class="col-sm-10">
                            <textarea class="form-control" id="commentm" name="commentm" rows="12" ng-model="newcomment.comment"></textarea>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <button type="submit" class="btn btn-primary" ng-disabled="feedbackForm.$invalid">Submit Comment</button>
                        </div>
                      
                    </div>
                </form>

        </div>
    </div>

<!-- build:js scripts/main.js -->
    <script src="../bower_components/angular/angular.min.js"></script>
    <script src="scripts/app.js"></script>
<!-- endbuild -->

</body>

</html>

6
  • 1
    Please try boiling it down to an MCVE as this process often leads to a solution and when it doesn't it makes it easier to answer. Commented Jan 31, 2017 at 20:18
  • In Angular, scopes mirror the DOM hierarchy, therefore a scope can only inherit properties from its ancestor scope(s), with rootscope at the top level. A scope doesn't inherit from any of its descendants, or from any siblings, which is (it appears) what you are expecting to happen. Commented Jan 31, 2017 at 23:57
  • Thank you so much. I've tryed to create this as rootscope. Even in that case it doesn't push to array. I deleted second scope added function to the first scope. Whatever I have done it doesn't add new element to array. Commented Feb 1, 2017 at 11:21
  • Mmm, I'm at a loss. Don't know what else to advise :( Commented Feb 1, 2017 at 23:23
  • OMG I solved issue. The problem was one </div> which in Html which I closed before the access to second scope from the html code. So it took my three days ))))))) just one <div> Commented Feb 2, 2017 at 10:31

1 Answer 1

0

I believe it has something to do with the scope of each controller. You are defining dish.comments in DishDetailController while your submit function is in DishCommentController controller.

Try taking the submitcomment function from DishCommentController controller to DishDetailController controller since DishCommentController doesn't even have $scope.dish.comments in its scope.

Edit: After you have updated the code as suggested, give it a try

 .controller('DishDetailController', ['$scope', function($scope) {

    var $scope.dish ={
                  name:'Uthapizza',
                  image: 'images/uthapizza.png',
                  category: 'mains', 
                  label:'Hot',
                  price:'4.99',
                  description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
                  comments: [
                       {
                           rating:5,
                           comment:"Imagine all the eatables, living in conFusion!",
                           author:"John Lemon",
                           date:"2012-10-16T17:57:28.556094Z"
                       }
                       ...
                   ]
            };

    $scope.newcomment = {
        rating : "",
        comment: "",
        author: "",
        date: new Date().toISOString()
    };

    $scope.submitComment = function (rating , author, stars, date) {
        $scope.dish.comments.push($scope.newcomment);     
    }

}]);

I have removed some extra code which you can add back later when it start working.

<div class="row row-content" ng-controller="DishDetailController">          

        <div class="col-xs-9 col-xs-offset-1">
            <h4>Customer Comments</h4> Sort by:
            <input type="text" ng-model="filterText">
            <blockquote ng-repeat="commentla in dish.comments | orderBy: filterText">
                <p class="mb-0">  {{commentla.rating}} Stars </p>
                <p class="mb-0">{{commentla.comment}}</p>
                <footer class="blockquote-footer"> {{commentla.author}} {{commentla.date | date: 'mediumDate'}} </footer>
            </blockquote>
        </div>    

    <div class="col-xs-9 col-xs-offset-1">
            <ul class="list-unstyled">
           Your Name: {{newcomment.author}}
                <br>
                Comment:  {{newcomment.comment}}
                <br>
                Your Rating: {{newcomment.rating}}

            </ul>
        <form class="form-horizontal" name="commentForm" ng-submit="submitComment()" novalidate>
            <div class="form-group">
                <label for="yname" class="col-sm-2 control-label">Your Name:</label>
                <div class="col-sm-10">
                <input type="text" class="form-control" id="yname" aria-des                <div class="col-sm-10">
                <label class="radio-inline">
                    <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="1" ng-model="newcomment.rating"> 1
                </label>
                ..
            </div>
            <div class="form-group">
                <label for="commentm" class="col-sm-2 control-label">Your Comment</label>
                <div class="col-sm-10">
                    <textarea class="form-control" id="commentm" name="commentm" rows="12" ng-model="newcomment.comment"></textarea>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="submit" class="btn btn-primary" ng-disabled="feedbackForm.$invalid">Submit Comment</button>
                </div>

            </div>
        </form>
    </div>
</div>
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for comment. I tried that too. But what I am doing I just got an error: Cannot read property 'comments' of undefined
@AgilYolchuyev I am not sure why you have so many ng-controllers or even controllers for single functions only
I changed javascript part.
@AgilYolchuyev See how its structured now
thank you so much for all your comments. I appreciate your help to me. I have done by the same way too. The problem is I still get an error: TypeError: Cannot read property 'comments' of undefined at b.$scope.submitComment (app.js:169). My problem is that in view part (html code) I have live preview and in console.log it show me normal results. But I think the problem in push to array part and I don't know what is a reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.