문제

Yesterday i had a problem with my mobile app. I'm using angularjs and at first I thought it was angulars fault so i tried everything that could be tried. Well in the end the solution was to change equality operator from === to == (type checking). Well I was totaly confused by what happened. I dont know much about javascript but this I gotta know. Since my old SO question (AngularJS How to get data to controller via $rootScope?) has only angularjs tag i'm bringing this question to javascript. Why would this code (with ===) return error "TypeError: Cannot read property 'ID' of undefined":

dndetail.controller('dndetailCtrl', ['$rootScope', '$scope', '$routeParams', '$localStorage', function ($rootScope, $scope, $routeParams, $localStorage) {

    var mjav = [];
    $scope.$storage = $localStorage;
    var lslist = $scope.$storage.dnlist;
    var id = $routeParams.dnid;
    $scope.$storage.test1 = $scope.$storage.dnlist[1].ID;

    for (var i = 0; i <= $scope.$storage.dnlist.length; i++) {
        if ($scope.$storage.dnlist[i].ID === id) {
            $scope.data = $scope.$storage.dnlist[i];
            break;
        }
    }
    //$scope.data = $rootScope.dnlist[$rootScope.getIndex($routeParams.dnid)];
}]);

And the code with == works as expected. I'm a relatively new Javascript user (3months), before I had some experience with VB/C#.net.

EDIT: forgot to mention I have tested both variables with typeof and they both return integer.

도움이 되었습니까?

해결책

Let's break this down a bit to make sense of it.

  • The error - TypeError: Cannot read property 'ID' of undefined is applicable when using both the == (type conversion comparison) and the === (strict comparison) because there seems to be an issue with $scope.$storage.dnlist[i].ID. But due to the difference between the two comparisons the problem is being masked when using the == (type conversion comparison).

  • == is a loosely equal to or non strict check, it will use type conversion to convert both values to the same type before checking if they are equal. In your scenario because $scope.$storage.dnList[i].ID is returning undefined. undefined is considered a falsy value in JavaScript (converts to false when coerced) so when the == comparison uses type conversion, in this instance, undefined is being coerced (forced) to a 0 as this is another falsy value. Now that both values are integers it can perform it's equality check

  • === on the other hand is a strict equality check meaning that no type conversions are made. It will simply check if both values are exactly equal in both type and value. Which in this case is no, one is an integer and one is undefined and therefore your error is thrown.

More info on equality checks here and truthy and falsy values here.

다른 팁

In your for loop you seem to be starting the index from 0 and using <= instead use:

for (var i = 0; i < $scope.$storage.dnlist.length; i++) { ... }

Do you understand that $scope.$storage.dnlist[i] is not defined (does not exist) so you can not reference the id property of it?

To me, the issue is that you are going through your loop one too many times and on the last time through $scope.$storage.dnlist[i] does not exist and js throws the exception when you try to reference the id property of a non-existent object.

The comparison in your for statement should be "i<" rather than "i<=" so you do not go past the end of the array.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top