Angularjs:TypeError:无法读取未定义的属性_____

时间:2014-10-17 06:52:10

标签: javascript json angularjs

我正在创建一个简单的应用程序来自学Angular,我将应用程序分解为主app.js以及services.js和controllers.js。

在services.js文件中,我试图从JSON中获取数据并将其传递给我的controller.js,然后简单地将JSON中的一个值吐出到console.log中。

奇怪的是,将我的服务中的整个数据对象放入控制台会吐出整个对象(对于Chrome开发人员工具中的混乱格式,很抱歉,希望这只是一个想法)...

console.log(questions);在控制台中返回:

Objectconfig: Objectdata: Array[4]0: Objectanswers: Array[4]correctAnswer: "question_1_answers_1"question: "What did Coltrane play?"__proto__: Object1: Objectanswers: Array[4]correctAnswer: "question_2_answers_2"question: "What did Miles play?"__proto__: Object__defineGetter__: function __defineGetter__() { [native code] }__defineSetter__: function __defineSetter__() { [native code] }__lookupGetter__: function __lookupGetter__() { [native code] }__lookupSetter__: function __lookupSetter__() { [native code] }constructor: function Object() { [native code] }hasOwnProperty: function hasOwnProperty() { [native code] }isPrototypeOf: function isPrototypeOf() { [native code] }propertyIsEnumerable: function propertyIsEnumerable() { [native code] }toLocaleString: function toLocaleString() { [native code] }toString: function toString() { [native code] }valueOf: function valueOf() { [native code] }get __proto__: function __proto__() { [native code] }set __proto__: function __proto__() { [native code] }2: Objectanswers: Array[4]correctAnswer: "question_3_answers_4"question: "What did Monk play?"__proto__: Object3: Objectanswers: Array[4]correctAnswer: "question_4_answers_3"question: "What did Ray Brown play?"__proto__: Objectlength: 4__proto__: Array[0]headers: function (name) {arguments: (...)get arguments: function ThrowTypeError() { [native code] }set arguments: function ThrowTypeError() { [native code] }caller: (...)get caller: function ThrowTypeError() { [native code] }set caller: function ThrowTypeError() { [native code] }length: 1name: ""prototype: Object__proto__: function Empty() {}<function scope>status: 200statusText: "OK"__proto__: Object__defineGetter__: function __defineGetter__() { [native code] }__defineSetter__: function __defineSetter__() { [native code] }__lookupGetter__: function __lookupGetter__() { [native code] }__lookupSetter__: function __lookupSetter__() { [native code] }constructor: function Object() { [native code] }hasOwnProperty: function hasOwnProperty() { [native code] }isPrototypeOf: function isPrototypeOf() { [native code] }propertyIsEnumerable: function propertyIsEnumerable() { [native code] }toLocaleString: function toLocaleString() { [native code] }toString: function toString() { [native code] }valueOf: function valueOf() { [native code] }get __proto__: function __proto__() { [native code] }set __proto__: function __proto__() { [native code] }

但是,尝试访问单个值,例如:

console.log(questions[0].correctAnswer);

...给了我以下错误:

TypeError: Cannot read property 'correctAnswer' of undefined at new <anonymous> (http://local.testingspace.com/js/global.js:49:33) at invoke (http://local.testingspace.com/js/lib.js:15265:17) at Object.instantiate (http://local.testingspace.com/js/lib.js:15276:23) at $get (http://local.testingspace.com/js/lib.js:18580:28) at link (http://local.testingspace.com/js/lib.js:34222:26) at nodeLinkFn (http://local.testingspace.com/js/lib.js:18010:13) at compositeLinkFn (http://local.testingspace.com/js/lib.js:17404:13) at publicLinkFn (http://local.testingspace.com/js/lib.js:17300:30) at $get.boundTranscludeFn (http://local.testingspace.com/js/lib.js:17424:21) at controllersBoundTransclude (http://local.testingspace.com/js/lib.js:18031:18) <ng-view class="ng-scope">

看一下下面的代码,有谁知道为什么我会遇到这个问题?

谢谢!

-Doron

以下是相关代码:

app.js

(function() {

    var JazzQuiz = angular.module('JazzQuiz', ['JazzQuiz.services', 'JazzQuiz.controllers', 'ngRoute']);

    JazzQuiz.config(['$routeProvider', function($routeProvider) {

        $routeProvider
        .when('/', {
            templateUrl: '/partials/quiz.html',
            controller: 'QuizCtrl',
            resolve: {
                questions: function (quizFactory) {
                    return quizFactory.getQuestions();
                },
                responses: function (quizFactory) {
                    return quizFactory.getResponses();

                }
            }
        })
        .when('/score', {
            templateUrl: '/partials/score.html',
            controller: 'ScoreCtrl',
            resolve: {
                responses: function(quizFactory) {
                    return quizFactory.getResponses();
                }
            }
        });

        $routeProvider.otherwise({redirectTo: '/'});

    }]);

})();

services.js

var services = angular.module('JazzQuiz.services' ,[]);

services.factory('quizFactory', ['$http', function($http){
    var resp;
    resp = {
        getQuestions: function (){
            var promise = $http({
                method: 'GET',
                url: '../json/questions.json'
            })
            .success(function (data) {
                return data;
            });
            return promise;

        },
        getResponses: function (){
            var promise = $http({
                method: 'GET',
                url: '../json/submissionResponses.json'
            })
            .success(function (data) {
                return data;
            });
            return promise;
        }
    };

    return resp;
}]);

controllers.js

var ctrl = angular.module('JazzQuiz.controllers', []);

// controller that handles the display of questions and handling of answers
ctrl.controller('QuizCtrl', function ($scope, $http, $location, $rootScope, $timeout, questions, responses){

    $scope.quizContent = questions;
    $scope.quizResponses = responses;

    //this spits out the entire object in the console
    console.log(questions);

    //this gives me an error
    console.log(questions[0].correctAnswer);

    // more to come...
});

questions.json

[
        {
            "question": "What did Coltrane play?",
            "answers": [
                "saxophone",
                "trumpet",
                "guitar",
                "french horn"
            ],
            "correctAnswer": "question_1_answers_1"
        },
        {
            "question": "What did Miles play?",
            "answers": [
                "drums",
                "trumpet",
                "guitar",
                "french horn"
            ],
            "correctAnswer": "question_2_answers_2"
        },  
        {
            "question": "What did Monk play?",
            "answers": [
                "trombone",
                "tabla",
                "drums",
                "piano"
            ],
            "correctAnswer": "question_3_answers_4"
        },
        {
            "question": "What did Ray Brown play?",
            "answers": [
                "saxophone",
                "drums",
                "bass",
                "guitar"
            ],
            "correctAnswer": "question_4_answers_3"
        }                
]

1 个答案:

答案 0 :(得分:0)

查看您的日志输出,我认为您的问题是,success请求的$http处理程序返回的值未在promise链中返回,因此您的success handler实际上并没有做任何事情,你在控制器中收到的promise值是整个$http响应,而不仅仅是结果数据。尝试更改您的服务:

    getQuestions: function (){
        return $http({
            method: 'GET',
            url: '../json/questions.json'
        })
        .then(function (response) {
            return response.data;
        });
    },
    getResponses: function (){
        return $http({
            method: 'GET',
            url: '../json/submissionResponses.json'
        })
        .then(function (response) {
            return response.data;
        });
    }

并查看是否会产生影响。

本着学习的精神,请注意您的错误信息实际上是:

Cannot read property 'correctAnswer' of undefined

注意,您正在评估的表达式是

questions[0].correctAnswer

这意味着questions不是未定义的部分 - 它是questions[0],所以问题是:

  • 一个空数组(因为即使只有一个已定义的元素也意味着将填充索引0 - 忽略一些古怪的极端情况)
  • 一个数组,其中包含一个未定义的值作为其第一个元素(可能,但在这种情况下不太可能)
  • 根本不是数组

有了这个以及questions确实具有已定义值的知识,您可以弄清楚其余部分:您的questions对象具有“数据”,“标题”和“状态”等属性,表明它是$http响应对象。