Nested promises in ui-router resolve

╄→尐↘猪︶ㄣ 提交于 2019-12-13 02:37:36

问题


I have been struggling for a while with the following problem:

I would like to get some data before the view shows, (resolve). But some of the data is dependend on the result of another promise.

It goes like this: I get the job id (index) from the $stateParams and look up the data in my Service. Once it is completed, from this result (the job), I can look up the settings and floors (each from a different service), both return a promise.

What I've came up so far

jobinfo: function(Jobs, Floor, JobSetting, $stateParams, $q) {

    var defer = $q.defer();

        Jobs.getByIndex($stateParams.index)
        .then(function(job) {
            console.log('got jobs');
            $q.all({floors: Floor.getByJob(job), settings: JobSetting.getByJob(job)})
            .then(function(info) {
                console.log('got info');
                defer.resolve([job, info.floors, info.settings]);
            });
        });

    return defer.promise;
}

Take 2

jobinfo: function(Jobs, Floor, JobSetting, $stateParams, $q) {

    return Jobs.getByIndex($stateParams.index)
        .then(function(job) {
            console.log('got jobs');
            return $q.all({floors: Floor.getByJob(job), settings: JobSetting.getByJob(job)})
            .then(function(info) {
                console.log('got info');
                return [job, info.floors, info.settings];
            });
        });
}

Both seem to fail, I do not even get a console.log back.

PS: I left the rest of the code out, obviously they are wrapped in an

resolve: {
...
}

and defined in the right place.

Could someone be so gentle to point me out in the right direction ?


The solution I ended up with was the following: (thanks to avcajaraville)

job: function(Jobs, $stateParams) {
    return Jobs.getByIndex($stateParams.index);
},

floors: function(Floor, job) {
    return Floor.getByJob(job);
},

settings: function(JobSetting, job) {
    return JobSetting.getByJob(job);
}

回答1:


I like to separate the resolvers.

You can inject the value on each resolver this way:

job : function( Jobs, $stateParams, $q ) {
    var defer = $q.defer();
    Jobs.getByIndex( $stateParams.index, function( job ) {
        defer.resolve( job );
    });
    return defer.promise;
},

floor : function( Floor, job, $q ) {
    var defer = $q.defer();
    Floor.getByJob( job, function( floor ) {
        defer.resolve( floor );
    });
    return defer.promise;
},

settings : function( JobSetting, job, $q ) {
    var defer = $q.defer();
    JobSetting.getByJob( job, function( settings ) {
        defer.resolve( settings );
    });
    return defer.promise;
},

From ui-router documentation:

The resolve property is a map object. The map object contains key/value pairs of

  • key – {string}: a name of a dependency to be injected into the controller.
  • factory - {string|function}:

[...]

if function, then it is injected and the return value is treated as the dependency. If the result is a promise, it is resolved before the controller is instantiated and its value is injected into the controller.




回答2:


Try this

jobinfo: function(Jobs, Floor, JobSetting, $stateParams, $q) {

              var defer = $q.defer();

              Jobs.getByIndex($stateParams.index)
                  .then(function(job) {
                      console.log('got jobs');
                      var floors = Floor.getByJob(job);
                      var settings = JobSetting.getByJob(job);
                      $q.all([floors, settings])
                      .then(function(info) {
                          console.log('got info');
                          defer.resolve([job, info[0], info[1]]);
                      });
                  });

              return defer.promise;
          }


来源:https://stackoverflow.com/questions/30895140/nested-promises-in-ui-router-resolve

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!