尝试从服务加载数据时,出现以下错误消息:Error: undefined is not an object (evaluating 'ProfileService.getProfile(1).then

ProfileController

错误发生在这里...

vm.user = {};

vm.loadProfile = function() {
  ProfileService.getProfile(1).then(function(profileData) {
    console.log(profileData);
    vm.user = profileData;
  })
};

vm.loadProfile()


ProfileService

function getProfile(id) {
  var profile = [];

  $log.debug('Getting profile with id: ' + id);
  StubFactory.getProfileData().then(function(result) {
    for(var i = 0; i < result.data.profiles.length; i++) {
      if(result.data.profiles[i].id === id) {
        profile = result.data.profiles[i];
      }
    }

    $log.debug('Getting contacts for profile with id: ' + id);
    profile.contacts = [];
    StubFactory.getContactsData().then(function(result) {
      for(i = 0; i < profile.contactMapper.length; i++) {
        for(var j = 0; j < result.data.contacts.length; j++) {
          if(profile.contactMapper[i] === result.data.contacts[j].id) {
            profile.contacts.push(result.data.contacts[j]);
          }
        }
      }
    });

    $log.debug('Getting documents for profile with id: ' + id);
    profile.documents = [];
    StubFactory.getDocumentsData().then(function(result) {
      for(i = 0; i < profile.documentMapper.length; i++) {
        for(var j = 0; j < result.data.documents.length; j++) {
          if(profile.documentMapper[i] === result.data.documents[j].id) {
            profile.documents.push(result.data.documents[j]);
          }
        }
      }
    });
    $log.debug('Completed load for profile with id: ' + id);
    $log.info(profile);
    return profile;
  });
}


存根工厂

function getContactsData() {
  return $http.get('data/contacts.json');

}

function getProfileData() {
  return $http.get('data/profiles.json');
}

function getDocumentsData() {
  return $http.get('data/documents.json');
}


日志如下...

[Warning] Unexpected CSS token: : (main.css, line 4919)
[Warning] Unexpected CSS token: : (main.css, line 8199)
[Warning] Unexpected CSS token: : (main.css, line 8207)
[Debug] Getting profile with id: 1 (angular.js, line 14326)
[Error] Error: undefined is not an object (evaluating 'ProfileService.getProfile(1).then')
loadProfile@http://localhost:9000/scripts/controllers/profile.js:17:35
http://localhost:9000/scripts/controllers/profile.js:22:19
$controllerInit@http://localhost:9000/bower_components/angular/angular.js:10717:40
nodeLinkFn@http://localhost:9000/bower_components/angular/angular.js:9594:45
compositeLinkFn@http://localhost:9000/bower_components/angular/angular.js:8903:23
publicLinkFn@http://localhost:9000/bower_components/angular/angular.js:8768:45
link@http://localhost:9000/bower_components/angular-route/angular-route.js:1222:11
invokeLinkFn@http://localhost:9000/bower_components/angular/angular.js:10274:15
nodeLinkFn@http://localhost:9000/bower_components/angular/angular.js:9663:23
compositeLinkFn@http://localhost:9000/bower_components/angular/angular.js:8903:23
publicLinkFn@http://localhost:9000/bower_components/angular/angular.js:8768:45
update@http://localhost:9000/bower_components/angular-route/angular-route.js:1171:36
$broadcast@http://localhost:9000/bower_components/angular/angular.js:18343:33
http://localhost:9000/bower_components/angular-route/angular-route.js:733:40
processQueue@http://localhost:9000/bower_components/angular/angular.js:16689:39
http://localhost:9000/bower_components/angular/angular.js:16733:39
$digest@http://localhost:9000/bower_components/angular/angular.js:17827:36
$apply@http://localhost:9000/bower_components/angular/angular.js:18125:31
done@http://localhost:9000/bower_components/angular/angular.js:12233:53
completeRequest@http://localhost:9000/bower_components/angular/angular.js:12459:15
requestLoaded@http://localhost:9000/bower_components/angular/angular.js:12387:24 – "<div ng-view=\"\" class=\"ng-scope\">"
    (anonymous function) (angular.js:10859)
    invokeLinkFn (angular.js:10276)
    nodeLinkFn (angular.js:9663)
    compositeLinkFn (angular.js:8903)
    publicLinkFn (angular.js:8768)
    update (angular-route.js:1171)
    $broadcast (angular.js:18343)
    (anonymous function) (angular-route.js:733)
    processQueue (angular.js:16689)
    (anonymous function) (angular.js:16733)
    $digest (angular.js:17827)
    $apply (angular.js:18125)
    done (angular.js:12233)
    completeRequest (angular.js:12459)
    requestLoaded (angular.js:12387)
[Debug] Getting contacts for profile with id: 1 (angular.js, line 14326)
[Debug] Getting documents for profile with id: 1 (angular.js, line 14326)
[Debug] Completed load for profile with id: 1 (angular.js, line 14326)
[Info] {id: 1, firstName: "Robert", lastName: "Emery", address: "95 Guild Street, London, N14 3UF", type: "tenant", …} (profile.js, line 115)


profile.js, line 115ProfileService中的以下代码行:$log.info(profile);

最佳答案

您的问题与promise的异步行为有关,这很好。因此,要获取数据,您有两种方法:

第一种方法是链接.then事件并从最后一个callbackfunction调用promise result
代码如下所示:

ProfileController

vm.user = {};
vm.loadProfile = function() {
     ProfileService.getProfile(1, callBackfunc); // pass callback function
};

function callBackfunc(profileData){
     vm.user = profileData;
}
vm.loadProfile();


ProfileService

function getProfile(id, callBackfunc) {
      var profile = [];
      // chain .then events
      $log.debug('Getting profile with id: ' + id);
      StubFactory.getProfileData().then(function(result) {
        for(var i = 0; i < result.data.profiles.length; i++) {
          if(result.data.profiles[i].id === id) {
            profile = result.data.profiles[i];
          }
        }

        $log.debug('Getting contacts for profile with id: ' + id);
        profile.contacts = [];
        StubFactory.getContactsData().then(function(result) {
          for(i = 0; i < profile.contactMapper.length; i++) {
            for(var j = 0; j < result.data.contacts.length; j++) {
              if(profile.contactMapper[i] === result.data.contacts[j].id) {
                profile.contacts.push(result.data.contacts[j]);
              }
            }
          }

        $log.debug('Getting documents for profile with id: ' + id);
        profile.documents = [];
        StubFactory.getDocumentsData().then(function(result) {
          for(i = 0; i < profile.documentMapper.length; i++) {
            for(var j = 0; j < result.data.documents.length; j++) {
              if(profile.documentMapper[i] === result.data.documents[j].id) {
                profile.documents.push(result.data.documents[j]);
              }
            }
          }
        $log.debug('Completed load for profile with id: ' + id);
        $log.info(profile);
        callBackfunc(profile); // callback function called.
        });
      });
    });
}


第二种方法是使用$q服务并利用它的$q.all()方法。

那么您的代码将类似于:

let promises = [promisegetProfileData(), promisegetContactsData(), promisegetDocumentsData()];

$q.all(promises).then((values) => {
    var profile = [];
    // assign ProfileData values[0]
    // assign ContactData values[1]
    // assign DocumentData values[2]

    callBackFunc(profile);
});


Read more here for $q

07-24 17:55