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>

2
  • 2
    To share data between controllers you should use a service. Commented Aug 17, 2016 at 9: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. Commented Aug 17, 2016 at 9:33

2 Answers 2

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Worked just as I wanted to!
-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.

1 Comment

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.