1

I created following controller with 3 differents $http GET calls to a rest-api.

$http({method: 'GET', url: REST_CONFIG.url+'/api/lims/data/runs/list'})
        .success(function(data, status, headers, config) {
            form.runs = data;
        })
        .error(function(data, status, headers, config) {
            form.runs = [];
        });
        form.data.analysis = {"analysisName": "","analysisprofile": {"workflows": []},"run": ""};
        //Get all Default Workflows
        $http({method: 'GET', url: REST_CONFIG.url+'/api/workflows/default/list'})
        .success(function(data, status, headers, config) {
            form.workflows = data;
        })
        .error(function(data, status, headers, config) {
            form.workflows = [];
        });
        //Get all databases
        $http({method: 'GET', url: REST_CONFIG.url+'/api/list-databases'})
        .success(function(data, status, headers, config) {
            form.databases = data;
        })
        .error(function(data, status, headers, config) {
            form.databases = [];
        });

Sometimes I have the same results from query1 and query2 (query2 have the result from query1). In that case the rest-api do 2 times the query1. My browser say that the http queries are good (3 differents url). This is weird and really annoying. I also tried to do:

        //Get all runs
         runs =  $http({method: 'GET', url: REST_CONFIG.url+'/api/lims/data/runs/list'});
         //Get all Default workflows
         defaultWorkflows = $http({method: 'GET', url: REST_CONFIG.url+'/api/workflows/default/list'});
         //Get all databases
         databases = $http({method: 'GET', url: REST_CONFIG.url+'/api/list-databases'});
         $q.all([runs, defaultWorkflows, databases]).then(function(values) {
            form.runs = values[0].data;
            form.workflows = values[1].data;
            form.databases  = values[2].data;
         });

Nothing worked. Is it coming from the rest-api? Or I am doing something wrong?

EDIT Problem solved. The key point was the use of $q with promise and deffer(). This plunkr helped me a lot: http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p=preview

I use the following code:

    var getInfo = function(){
        var promises = [];
        var urls = [];
        urls.push(REST_CONFIG.url+'/api/lims/data/runs/list');
        urls.push(REST_CONFIG.url+'/api/workflows/default/list');
        urls.push(REST_CONFIG.url+'/api/list-databases');
        angular.forEach(urls, function(url){
            var deffered = $q.defer();
            $http({method: 'GET', url: url})
            .then(function successCallback(response) {
                deffered.resolve(response.data);
            }, function errorCallback(response) {
                deffered.reject();
            });
            promises.push(deffered.promise);
        })
        return $q.all(promises);
    }


     var init = function(){
         var promiseInfo = getInfo();
         promiseInfo.then(function(datas){
             form.runs = datas[0];
             form.workflows = datas[1];
             form.databases = datas[2];
         })
    };
JBeghain
  • 13
  • 3
  • In your first example, how/where are you using `forms`? It sounds like you're just using it before the calls have completed, but we can't tell, because you haven't shown that. – T.J. Crowder Apr 12 '17 at 13:49
  • What version of angular are you using? From version 1.6 success and error for $http was removed... http://www.codelord.net/2015/05/25/dont-use-%24https-success/ – OB Kenobi Apr 12 '17 at 13:53
  • 1
    you shouldn't use `.success`. It has been deprecated, and removed from the most current angular releases. http://stackoverflow.com/a/35331339/2495283 – Claies Apr 12 '17 at 13:54
  • Thank you very much for the feedback :) I am using angular 1.5.7 – JBeghain Apr 13 '17 at 09:08
  • I don't see how "deffered" could work, as the correct is "deferred" – Gianmarco Apr 13 '17 at 09:18
  • Answers don't go *in* the question, one important aspect of SO's model is a clear separation between questions and answers (and comments). It's fine (actually encouraged) to post an answer to your own question if you have one. (In this case, as it's building on an existing answer, you would probably do what you've done and accept the existing answer even if expanding on it in your own). But also note that you don't need to use `$q.defer()` at all. Just use the promises you already have from `$http`. Great job on simplifying the code, though, that's definitely worth putting in an answer. – T.J. Crowder Apr 13 '17 at 09:26
  • @Gianmarco: That's just a variable name. It could be `fred`. – T.J. Crowder Apr 13 '17 at 09:34
  • Beware that the `init` function in your edit ignores rejections. JavaScript engines are starting to report unhandled rejections to the console as errors, just like unhandled exceptions (because that's what they are). – T.J. Crowder Apr 13 '17 at 09:35

1 Answers1

0

You need to be sure to wait for all of the requests to finish before using forms, for instance, by using $q.all. Also, be sure to use then and catch; success and error were deprecated back in v1.5:

function getInfo() {
    // Assuming `form` exists here...
    var promises = [];
    promises.push(
        $http({method: 'GET', url: REST_CONFIG.url+'/api/lims/data/runs/list'})
            .then(function(data, status, headers, config) {
                form.runs = data;
            })
            .catch(function(data, status, headers, config) {
                form.runs = [];
            })
    );
    form.data.analysis = {"analysisName": "","analysisprofile": {"workflows": []},"run": ""};
    //Get all Default Workflows
    promises.push(
        $http({method: 'GET', url: REST_CONFIG.url+'/api/workflows/default/list'})
            .then(function(data, status, headers, config) {
                form.workflows = data;
            })
            .catch(function(data, status, headers, config) {
                form.workflows = [];
            })
    );
    //Get all databases
    promises.push(
        $http({method: 'GET', url: REST_CONFIG.url+'/api/list-databases'})
            .then(function(data, status, headers, config) {
                form.databases = data;
            })
            .catch(function(data, status, headers, config) {
                form.databases = [];
            })
    );
    return $q.all(promises).then(() => form);
}

That returns a promise that will resolve to form when all three of the requests are complete (it won't reject, because rejections are turned into resolutions via the catch handlers, in keeping with your original code).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875