1

I am writing a small dialog controller, that takes a question, a set of answers and marks the index of the correct answer. I need to enable the user to add multiple questions, and store them in an array.

All works, until I try to push the JSON containing details about the question to an array I created earlier. Upon trying to push, JS throws an error: Cannot read property 'push' of undefined. I read few threads about how to push elements/values to an array in Angular, but no one seems to have the exact same problem.

Here's my code:

function TestController($mdDialog, $scope, $mdSidenav, $mdBottomSheet, $timeout, $log) {
    $scope.questionSet = [];
    $scope.question = {
        text: null,
        answers: [],
        correctIndex: -1
    };

    $scope.clickPoP = function(ev) {
        // Appending dialog to document.body to cover sidenav in docs app
        // Modal dialogs should fully cover application
        // to prevent interaction outside of dialog
        var parentEl = angular.element(document.body);

        $mdDialog.show({
            parent: parentEl,
            targetEvent: ev,
            templateUrl: "edit-word-dialog.tmpl.html",
            locals: {
                items: $scope.question
            },
            controller: DialogController
        });

        function DialogController($scope, $mdDialog) {
            $scope.cancel = function() {
                $mdDialog.hide();
            }

            $scope.addQuestion = function(nextQuestion) {
                if (nextQuestion === true) {
                    console.log($scope.question);
                    $scope.questionSet.push($scope.question);
                    console.log('added question - clearing object - waiting for next input');
                } else {
                    console.log($scope.questionSet);
                    console.log('added question - closing dialog box');
                    $mdDialog.hide();
                }
            }

            $scope.setAnswer = function(index) {
                $scope.question.correctIndex = index;
                console.log(index);
            }
        }
    };
}

As you can see questionSet is supposed to hold the questions, and is defined and initialised at the start of the controller.

Then in the addQuestion() function i try to push my JSON object, which has all the correct data inside, into the questionSet, and thats where the error is thrown.

I have checked all my data, all data-binding and it all is correct, It just wont push the JSON into the array. Please note, that I would like to rather avoid appending to the array, to make it simpler to manage. Please also note that I am quite new to Angular.

Thank you for all the help, and apologies for the long read.

Here's the code for the dialog box, in case the error lies there:

<md-dialog class="email-dialog" flex="80" flex-sm="100">
<md-toolbar class="toolbar-default" md-theme="{{triSkin.elements.toolbar}}" palette-background="myPurple:500">
    <div class="md-toolbar-tools">
        <h2>
          <span>Quiz</span>
        </h2>
        <span flex></span>
    </div>
</md-toolbar>
<md-divider></md-divider>
<md-dialog-content class="sticky-container">
    <div>
        <md-content>
            <md-input-container>
                <label for="question-text">Enter Question</label>
                <input type="text" id="quiz-question" label="quiz-question" name="quiz-question" ng-model="question.text">
            </md-input-container>
            <div style="float: right; width: 10%">
                <md-radio-group>
                    <md-radio-button value="0" aria-label="ans0" ng-click="setAnswer(0)"></md-radio-button>
                    <br/>
                    <br/>
                    <md-radio-button value="1" aria-label="ans1" ng-click="setAnswer(1)"></md-radio-button>
                    <br/>
                    <br/>
                    <md-radio-button value="2" aria-label="ans2" ng-click="setAnswer(2)"></md-radio-button>
                    <br/>
                    <br/>
                    <md-radio-button value="3" aria-label="ans3" ng-click="setAnswer(3)"></md-radio-button>
                </md-radio-group>
            </div>
            <div style="float: right; width: 80%;">
                <md-input-container>
                    <label for="answer-one">Enter answer</label>
                    <input type="text" id="quiz-answer-one" label="quiz-answer-one" name="quiz-answer-one" ng-model="question.answers[0]">
                </md-input-container>
                <md-input-container>
                    <label for="answer-two">Enter answer</label>
                    <input type="text" id="quiz-answer-two" label="quiz-answer-two" name="quiz-answer-two" ng-model="question.answers[1]">
                </md-input-container>
                <md-input-container>
                    <label for="answer-three">Enter answer</label>
                    <input type="text" id="quiz-answer-three" label="quiz-answer-three" name="quiz-answer-three" ng-model="question.answers[2]">
                </md-input-container>
                <md-input-container>
                    <label for="answer-four">Enter answer</label>
                    <input type="text" id="quiz-answer-four" label="quiz-answer-four" name="quiz-answer-four" ng-model="question.answers[3]">
                </md-input-container>
            </div>
            <div style="float:left;">
                <md-button class="md-primary" aria-label="AddQuestion" ng-click="addQuestion(true)">Add Question</md-button>
                &nbsp;
                <md-button class="md-secondary" aria-label="Save" ng-click="addQuestion(false)">Save</md-button>
            </div>
        </md-content>
    </div>
</md-dialog-content>
<div class="md-actions" layout="row">
    <span flex></span>
    <md-button class="md-primary" aria-label="Close" ng-click="cancel()">
        Close
    </md-button>
</div>

3
  • 2
    You are referencing the wrong $scope :) Add something like var parentScope = $scope; to the start of TestController and then use parentScope.questionSet.push instead. Commented Jul 10, 2016 at 16:08
  • 1
    You cannot access $scope.questionSet since DialogController's scope is different from your initial scope. Commented Jul 10, 2016 at 16:10
  • It did work! than you both! But can you tell me how come am I able to access the JSON object then, if it's outside of the scope of DialogController? Commented Jul 10, 2016 at 16:12

1 Answer 1

1

You define $scope.questionSet in your parent controller, not in the dialogcontroller.

MdDialog uses the isolated scope by default. You could use the parent controller scope by passing scope: $scope in the $mdDialog call in TestController.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.