在我的服务中,我想通过另一个服务加载路径

时间:2014-07-29 14:50:29

标签: java angularjs http service

我有一个有角度的网络应用程序。

它有一个服务将查询同一服务器上的简单节点api。 该api将环境变量的名称作为参数,并返回与该环境变量匹配的java api的路径。

servicesModule.factory('EnvVarApi', function($http){
    var url = 'http://localhost:8080/api/variable_env/';
    return {
        getUrlApi : function(var_env, callbackSuccess) {
            $http.get(url+ var_env).success(callbackSuccess);
        }
    }
});

这很好用。它返回一个形式的对象: {“cle”:API_KEY,“valeur”:API_PATH}

现在我想创建另一个服务,它将查询java api(我最后会有3个)... 我将如何仅检索ONCE的API路径?一旦加载就返回正确的资源。它失败了,因为返回的资源在回调之前有一个空路径。

servicesModule.factory('ApiRef', function($resource, EnvVarApi){
    var url = null;
    EnvVarApi.getUrlApi('APIREF_KEY', function(data) {
        if (data) {
            url = data.valeur;
        }
    });

    return $resource(url, {'cle' : '@cle'}, {
        put : {method : 'PUT'}
    });
});

第一个调用正常并返回路径,但是正如预期的那样它会中断,因为我首先返回一个带有空url的$资源。 也许有更好的方法可以做到这一点,而不是在第二次服务中注入我的第一个服务。

编辑:修复,感谢答案标记为吼叫。

这里是最终代码:

servicesModule.factory('EnvVarApi', function($http){
    var url = 'http://localhost:8080/api/variable_env/';
    return {
        getUrlApi : function(var_env) {
            return $http.get(url+ var_env);
        }
    }
});

并且

servicesModule.factory('ApiRef',['$q','$http', 'EnvVarApi',function ($q,$http, EnvVarApi) {

    var defer = $q.defer();
    EnvVarApi.getUrlApi('APIREF_KEY').then(function (resp) {
        defer.resolve($http.get(resp.data.valeur));
    });
    return defer.promise;
}]);

2 个答案:

答案 0 :(得分:1)

您可以使用$ q服务,请检查以下代码

app.factory('call2',['$q','$http',function ($q,$http) {
    var url = 'whatever url';
    var defer = $q.defer();
    $http.get(url).then(function (resp) {
        defer.resolve($http.get(resp.data)); 
        //resp.data contains the returned by $http request URL object
    });
    return defer.promise;
}]);

在Controller o Directive方面(记得将服务注入控制器)

call2.then(function (resp) {
    $scope.response = resp.data;
    //resp.data will contain the response of '$http.get(resp.data)'
})

你可以使用$ resource而不是$ http.get,见下文

app.factory('call2', ['$q', '$resource', function ($q, $resource) {
   var url = 'whatever url';
   var defer = $q.defer();
   $resource(url).get(function (resp) {
   defer.resolve($resource(resp.url).get().$promise);
  });
  return defer.promise;
}]);

答案 1 :(得分:0)

$ http.get返回一个承诺,简单的做法是解决控制器中的承诺...而不是在工厂中。在工厂中意味着没有.success()...仅在控制器中

如果你在服务中需要这个......就像这样:

servicesModule.factory('ApiRef', function($resource, EnvVarApi){
    var url = null;

    // this is ASYNC, meaning it will got to the return statement below and wait until the promise is resolved to assign the url
    EnvVarApi.getUrlApi('APIREF_KEY', function(data) {
        if (data) {
            url = data.valeur;
            $resource(url, {'cle' : '@cle'}, { // url defined here, gets put correctly
                put : {method : 'PUT'}
            });
        }
    });

    return $resource(url, {'cle' : '@cle'}, {
        put : {method : 'PUT'}
    });
});