1

I have the problem that my function doesn't wait for the response of http request and go further. I know that I can use promise to wait but I don't understand the concept.

I have a data service that have all http request :

function GetGroupIdFromBakery(bakeryId, successCallback, errorCallback) {
        $http.get(service.baseUrl + "BakeriesGroup/Bakeries/" + bakeryId)
            .then(function (result) { successCallback(result.data); }, errorCallback);
    }

From another service, I call the data service :

var hasPermission = function (permission, params) {
            permissionRoute = permission;
            setIdEntity(params);
            for (var i = 0; i < permissions.length; i++) {
                if (permissionRoute.Name === permissions[i].Name) {
                    if (permissions[i].Scope == "System")
                        return true;
                    else if (permissions[i].Scope == permissionRoute.Scope && permissions[i].IdEntity == permissionRoute.IdEntity) 
                        return true;
                }
            }
            return false;
        }



var setIdEntity = function (params) {
            if (permissionRoute.Scope == "Bakery")
                permissionRoute.IdEntity = parseInt(params.bakeryId);
            else if (permissionRoute.Scope == "Group") {
                if (params.bakeriesGroupId)
                    permissionRoute.IdEntity = parseInt(params.bakeriesGroupId);
                else {
                    getGroupOfBakery(parseInt(params.bakeryId));   
                }

                console.log(permissionRoute.IdEntity);
            }
        }

var getGroupOfBakery = function (bakeryId) {
            DataService.GetGroupIdFromBakery(bakeryId, function (groupId) {
                permissionRoute.IdEntity = groupId;
            }, function (error) {
                console.error("something went wrong while getting bakery");
                alert("Une erreur s'est produite lors de la récupération de la boulangerie");
            });

        }

I must wait for the response of DataService.GetGroupIdFromBakery(). With this code, permission.EntityId is undefined when I call getGroupByBakery().

Can somebody help me, please?

Liline
  • 29
  • 1
  • 7
  • 2
    You can't do that. You need to use promises. – SLaks Jul 25 '17 at 14:24
  • 1
    Is it possible to use callback? – Liline Jul 26 '17 at 08:05
  • Maybe I am wrong, but, to me, a promise ***is*** a callback. I am sure that they are the same under the hood. Anyway, you say "`I know that I can use promise to wait but I don't understand the concept`"; nor did i at first, then I started thinking of them as fucntionallly identical, and it clciked. Purists may well disagree ;-) but, if it helps you, think of pronises as callbacks – Mawg says reinstate Monica Nov 15 '20 at 11:12

3 Answers3

1

You can add a watcher to your response data. I think it is EntityId in your case. It get executed as soon as your EntityId changes. After getting the response data you can call the function, this time EntityId will not be undefined.

$scope.$watch(function () {
            return EntityId  
        }, function (newEntityId) {
            if(newEntityId != undefined {
                // now you can call your function
             }
            }
        }, true);
Sagar Hani
  • 146
  • 2
  • 8
0

Exactly, you have to use promises, because $http module is asynchronus. I built a service for that:

.service('RequestService', function($q, $http){
  return {
    call: function(htmlOptions){
      var d = $q.defer();
      var promise = d.promise;
      $http(htmlOptions)
        .then(function(response){
          d.resolve(response.data);
         }, function(response){
          d.reject(response.data);
        });
      promise.success = function(fn) {
       promise.then(fn);
        return promise;
      };
      promise.error = function(fn) {
       promise.then(null, fn);
       return promise;
      };
      return promise;
    }
  }
})

And then:

RequestService.call({
   method: 'POST' //GET, DELETE ...
   data: data,
   url: 'http://someurl.com/'
  });
0

you should use defer. create a new defer object in GetGroupIdFromBakery method,in success part resolve the defer and in failed part reject it, and return the promise of defer at the end.

function GetGroupIdFromBakery(bakeryId, successCallback, errorCallback, $q) {
    var defer = $q.defer();
    $http.get(service.baseUrl + "BakeriesGroup/Bakeries/" + bakeryId)
        .then(function (result) { 
           successCallback(result.data);
              defer.resolve(result.data); 
           }, function(){
              defer.reject(); 
           });
   return defer.promise;
}

This successfully return you a promise that you can call with .then() and receive as a value in the service where you need to have the data of GetGroupIdFromBakery.

getGroupOfBakery(parseInt(params.bakeryId), $q).then(function(data){
    // here you have data
})

Be aware you should inject $q, here I supposed that we have $q in service and I passed it to method.