You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS 1.6.6中Cannot read property 'length' of undefined问题排查

解决AngularJS异步请求导致下拉列表填充报错的问题

你遇到的核心问题是异步请求的执行顺序没有控制好,导致onCourses函数运行时,$scope.Courses还没从服务器拿到数据(还是undefined),这时候访问$scope.Courses.length就会触发报错。

问题根源分析

看你的控制器代码,这三个异步请求是并行发起的:

CourseService.getCourseClasses(IdSessionCourse).then(...);
CourseService.getCurrentSessionCourses().then(function (courses) { $scope.Courses = courses });
CourseService.courses().then(onCourses);

JavaScript的异步操作不会等待前一个完成再执行下一个,所以onCourses很可能在getCurrentSessionCourses返回数据、给$scope.Courses赋值之前就运行了,这时候$scope.Courses是undefined,自然会报错。

解决方案:控制异步请求的执行顺序

我们需要确保$scope.Courses已经被赋值后,再执行CourseService.courses().then(onCourses),把后续逻辑嵌套到getCurrentSessionCourses的回调里即可:

修改后的AddStudentController.js代码:

(function(){ 
  var myApp = angular.module("myApp"); 
  var AddStudentController = function ($scope, StudentService, CourseService) { 

    var onCourses = function (data) { 
      var result = []; 
      // 此时$scope.Courses已经被成功赋值,不会是undefined
      for (var i = 0; i < $scope.Courses.length; i++) { 
        for (var j = 0; j < data.length; j++) { 
          if (data[j].IdCourse === $scope.Courses[i].idCourse) { 
            if (result.indexOf(data[j]) === -1) { 
              result.push(data[j]); 
            } 
          } 
        } 
      } 
      $scope.courses = result; 
      // 增加空值判断,避免result为空时selectedCourse是undefined
      if (result.length > 0) {
        $scope.selectedCourse = result[0]; 
        var IdCourse = $scope.selectedCourse.IdCourse; 
        // 用find简化查找逻辑(如果你的环境支持ES6)
        var matchedCourse = $scope.Courses.find(course => course.idCourse === IdCourse);
        var IdSessionCourse = matchedCourse ? matchedCourse.idSessionCourse : null;

        if (IdSessionCourse) {
          CourseService.getCourseClasses(IdSessionCourse).then(function (classes) { 
            $scope.classes = classes; 
            $scope.selectedClass = classes.length > 0 ? classes[0] : undefined; 
          }); 
        }
      }
    }; 

    // 先获取CurrentSessionCourses,拿到数据后再执行后续逻辑
    CourseService.getCurrentSessionCourses().then(function (courses) { 
      $scope.Courses = courses; 
      // 确保$scope.Courses存在后,再调用courses()并处理结果
      CourseService.courses().then(onCourses); 
    }); 
  }; 
  myApp.controller("AddStudentController", AddStudentController) 
}());

额外优化建议

  1. 增加空值安全判断:在访问数组元素或对象属性前,先检查是否存在,避免因空数据导致的报错。
  2. 简化数组操作:用find、filter等数组方法替代嵌套for循环,让代码更简洁可读(如果你的AngularJS环境支持ES6语法)。
  3. HTML下拉列表优化:给select标签添加默认空选项,提升用户体验:
<!-- 第一个下拉列表 -->
<select ng-model="selectedCourse" ng-change="change()" class="form-control" ng-options="course.IdCourse as course.Name for course in courses">
  <option value="">-- 选择课程 --</option>
</select>

<!-- 第二个下拉列表 -->
<select ng-model="selectedClass" class="form-control" ng-options="class.idClass as class.className +' : '+class.campusName for class in classes">
  <option value="">-- 选择班级 --</option>
</select>

这样调整后,就能保证第一个下拉列表的填充逻辑在数据准备好之后执行,彻底解决异步请求导致的undefined报错问题。

内容的提问来源于stack exchange,提问作者Junaid Farooq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:02:52