1

I have a form that a user needs to fill out and submit. After the Submit button is clicked a function that should push the data to the array is triggered but I have no luck pushing it into the array. The array that the data needs to be pushed in is in another controller.

Debugging the code I found out that I'm getting this error.

Cannot read property 'comments' of undefined
    at n.$scope.submitComment (app.js:167)

JavaScript/HTML

.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.feedback = {
        author: "",
        rating: "",
        comment: "",
        feedbackDate: ""
    };
    $scope.submitComment = function() {
        $scope.feedback.feedbackDate = new Date().toISOString();
        $scope.dish.comments.push($scope.feedback);
    }
}]);
    <div class="col-xs-9 col-xs-offset-1" ng-controller="DishCommentController">
        <div class="col-xs-12">
            <form class="form-horizontal" role="form" name="commentForm" ng-submit="submitComment()" novalidate>
                <div class="form-group form-inline" ng-class="{ 'has-error' : commentForm.author.$error.required && !commentForm.author.$pristine }">
                    <label for="author">Your Name</label>
                    <input type="text" class="form-control" id="author" name="author" placeholder="Enter Your Name" ng-model="feedback.author" required> <span ng-show="commentForm.author.$error.required && !commentForm.author.$pristine" class="help-block">Your name is required</span>
                </div>
                <div class="form-group" ng-init="feedback.rating=5">
                    <label for="rating">Number Of Stars</label>
                    <input type="radio" name="rating" id="rating" value="1" ng-model="feedback.rating"> 1 </label>
                    <input type="radio" name="rating" id="rating" value="2" ng-model="feedback.rating"> 2 </label>
                    <input type="radio" name="rating" id="rating" value="3" ng-model="feedback.rating"> 3 </label>
                    <input type="radio" name="rating" id="rating" value="4" ng-model="feedback.rating"> 4 </label>
                    <input type="radio" name="rating" id="rating" value="5" ng-model="feedback.rating"> 5 </label>
                </div>
                <div class="form-group form-inline" ng-class="{ 'has-error' : commentForm.comment.$error.required && !commentForm.comment.$pristine}">
                    <label for="comment">Your Comment</label>
                    <textarea id="comment" name="comment" ng-model="feedback.comment" class="form-control" rows="3" placeholder="Your Comment" required></textarea>
                    <span ng-show="commentForm.comment.$error.required && !commentForm.comment.$pristine" class="help-block">Your comment is required</span>
                </div>
                <button type="submit" ng-disabled="commentForm.$invalid" class="btn btn-primary">Submit Comment</button>
            </form>
        </div>
    </div>
Dinesh Sundaraneedi
  • 402
  • 1
  • 5
  • 18
Jack Wolther
  • 121
  • 1
  • 2
  • 10
  • 2
    To share data between controllers you should use a service. – jcubic Aug 17 '16 at 09:18
  • It's tempting to do everything in controllers for Angular newbies. But everything that is data (retrieving, storing) should be handled in a service, as functions. – Christian Bonato Aug 17 '16 at 09:33

2 Answers2

5

Use services to share the data between the controller and use the angular object reference to update the data in different controller.

.service('sharingService', function ($injector) {
            this.sharedObject= [];

        });

In DishDetailController

  $scope.dish = dish;

After this use like

angular.extend(sharingService.sharedObject, $scope.dish);

In DishCommentController

sharingService.sharedObject.comments.push($scope.feedback);
Jeeva J
  • 3,173
  • 10
  • 38
  • 85
-2

You have two differents controllers, each controller have their own $scope, if you want to pass data between controller you can use $rootscope , this one is the main scope for angularjs.

https://docs.angularjs.org/api/ng/service/$rootScope

Every application has a single root scope. All other scopes are descendant scopes of the root scope. Scopes provide separation between the model and the view, via a mechanism for watching the model for changes. They also provide event emission/broadcast and subscription facility. See the developer guide on scopes.

Sergi Case
  • 226
  • 2
  • 12
  • Better to use a service. $rootScope works, but usually you end up with $emit and $broadcast scattered over many controllers. While it works, it's not so great from an architectural point of view. – Christian Bonato Aug 17 '16 at 09:32