6

I want to write a function in AngularJS that returns a value (actually it is a string). That value is returned by a http request, but async is driving me crazy.

My first attempt was:

this.readParameter = function(key) {
  $http({
    method: "GET",
    url: "XXXXXXX",
    headers: { 'Content-Type': 'application/json' }
  }).then(function successCallback(response) {
    return response.data;
  }, function errorCallback(response) {
    throw new Error("Error");
  })
};

But of course it does not work because of Angular async features (response.data is undefined)

What is the way to do it? I just want to return the value (string), so I can use this function like

var a = readParameter("key1")
Muhammad Usman
  • 1,366
  • 5
  • 18
  • 33
Carlos
  • 1,638
  • 5
  • 21
  • 39
  • There is no other way than to return the `$http` promise and use `then()` with `readParameter()` to get the data you received asynchronously. – ryeballar Oct 12 '15 at 12:10
  • But is it possible to wrap it into a function so I can use it directly like var a = readParameter("myKey")? Or must I forget it? Thank you – Carlos Oct 12 '15 at 12:26
  • 1
    No. Don't treat asnychronous as if it is synchronous, you might need some refresher on **[what asynchronous and synchronous is](http://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-does-it-really-mean)**. – ryeballar Oct 12 '15 at 12:31

3 Answers3

8

What you can do is define some variable with initial value outside function and on response set value inside success function instead of returning it.

Delegator pattern works great here to assign $http task to some service and use callback method for response.

Controller (Call Service for specific request) -> Service (Manage request params and other things and return factory response to Controller) -> Factory (Send request and return it to Service)

Basic example of Callback

var myVariable = '';
function myFunction (key, callback) {
  $http({
    method: "GET",
    url: "XXXXXXX",
    headers: { 'Content-Type': 'application/json' }
  }).then(function successCallback(response) {
      callback(response);
  }, function errorCallback(response) {
    throw new Error("Error");
  })
};

function myCallbackFunction(response) {
   myVariable = response.data; // assign value to variable
   // Do some work after getting response
}

myFunction('MY_KEY', myCallbackFunction);

This is basic example to set value but instead use callback pattern from above example.

var myvariable = '';
function myFunction (key) {
  $http({
    method: "GET",
    url: "XXXXXXX",
    headers: { 'Content-Type': 'application/json' }
  }).then(function successCallback(response) {
      myvariable = response.data; // set data to myvariable
      // Do something else on success response
  }, function errorCallback(response) {
    throw new Error("Error");
  })
};
myFunction('MY_KEY');
Sarjan Desai
  • 3,683
  • 2
  • 19
  • 32
  • I have tested it and response.date is still undefined in that way. I will study delegator pattern anyway, maybe the solution is there. Thank you – Carlos Oct 12 '15 at 12:27
  • Use `response.data`, not `response.date` if by mistake you have written than ignore it. If problem doesn't solve then make a [fiddle](http://jsfiddle.net) and add link at here. – Sarjan Desai Oct 12 '15 at 12:32
  • It works. I was not understanding well the callback, but you are right. – Carlos Oct 14 '15 at 20:50
3

Don't try to mix async and sync programming. Instead use a callback to use like

readParameter("key1", callback)

for example:

    this.readParameter = function(key, callback) {
  $http({
    method: "GET",
    url: "XXXXXXX",
    headers: { 'Content-Type': 'application/json' }
  }).then(function successCallback(response) {
    callback(response)
  }, function errorCallback(response) {
    throw new Error("Error");
  })
};
Hüseyin Zengin
  • 1,216
  • 11
  • 23
0

I resolve this by using promise:

Example :

in Service (invoicesAPIservice => invoicesapiservice.js) you use:

angular.module('app')
.service('invoicesAPIservice', function ($http) {
     this.connectToAPI= function () {

     return new Promise(function(resolve,reject){
            var options = {
                method:'GET',
                url :'',
                headers:{
                    'X-User-Agent': '....',
                    'Authorization': '....',
                }
            };

           $http(options).then(function successCallback(response) {
                    resolve(response);
                //console.log(response);
            },function errorCallback(response) {
                reject(response);
            })
     });
});

});

and in your Controller (mainCtrl=> mainCtrl.js):

angular.module('app').controller('mainCtrl', function($scope,invoicesAPIservice) {
  $scope.connectToAPI=function () {           
      invoicesAPIservice.connectToAPI().then(function (content) {
           console.log(content.statusText);
      }.catch(function (err) {
        //console.log(err);
        alert("Server is Out");
    });
 }

});

And in your page : index.html:

<button ng-click="connectToAPI()"></button>

:)