Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use HTTP.GET in AngularJS correctly? In specific, for an external API call?

I have the following code in the controller.js,

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
delete $http.defaults.headers.common['X-Requested-With'];
this.getData = function() {
    $http({
        method: 'GET',
        url: 'https://www.example.com/api/v1/page',
        params: 'limit=10, sort_by=created:desc',
        headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
     }).success(function(data){
         return data
    }).error(function(){
        alert("error");
    });
 }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
  $scope.data = dataService.getData();
});

But, I think I m probably making a mistake with CORS related issue. Can you please point me to the correct way to make this call? Thanks much!

like image 355
Anand Ram Avatar asked Dec 04 '13 07:12

Anand Ram


People also ask

What is http get in AngularJS?

In angularjs get ($http. get()) service or method is used to get data from remote HTTP servers. In angularjs get is a one of the shortcut method in $http service. In other ways, we can say that $http. get service or method in $http service is used to get data from the given URI.

How do we pass data and get data using http in angular?

get request Method Syntax: $http. get(url, { params: { params1: values1, params2:values2, params3:values3...... } });

Which object does the http GET () function return?

response : interceptors get called with http response object. The function is free to modify the response object or create a new one. The function needs to return the response object directly, or as a promise containing the response or a new response object.


6 Answers

First, your success() handler just returns the data, but that's not returned to the caller of getData() since it's already in a callback. $http is an asynchronous call that returns a $promise, so you have to register a callback for when the data is available.

I'd recommend looking up Promises and the $q library in AngularJS since they're the best way to pass around asynchronous calls between services.

For simplicity, here's your same code re-written with a function callback provided by the calling controller:

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
    delete $http.defaults.headers.common['X-Requested-With'];
    this.getData = function(callbackFunc) {
        $http({
            method: 'GET',
            url: 'https://www.example.com/api/v1/page',
            params: 'limit=10, sort_by=created:desc',
            headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
        }).success(function(data){
            // With the data succesfully returned, call our callback
            callbackFunc(data);
        }).error(function(){
            alert("error");
        });
     }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData(function(dataResponse) {
        $scope.data = dataResponse;
    });
});

Now, $http actually already returns a $promise, so this can be re-written:

var myApp = angular.module('myApp',[]);

myApp.service('dataService', function($http) {
    delete $http.defaults.headers.common['X-Requested-With'];
    this.getData = function() {
        // $http() returns a $promise that we can add handlers with .then()
        return $http({
            method: 'GET',
            url: 'https://www.example.com/api/v1/page',
            params: 'limit=10, sort_by=created:desc',
            headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
         });
     }
});

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData().then(function(dataResponse) {
        $scope.data = dataResponse;
    });
});

Finally, there's better ways to configure the $http service to handle the headers for you using config() to setup the $httpProvider. Checkout the $http documentation for examples.

like image 130
Kevin Stone Avatar answered Oct 02 '22 04:10

Kevin Stone


I suggest you use Promise

myApp.service('dataService', function($http,$q) {

  delete $http.defaults.headers.common['X-Requested-With'];
  this.getData = function() {
     deferred = $q.defer();
     $http({
         method: 'GET',
         url: 'https://www.example.com/api/v1/page',
         params: 'limit=10, sort_by=created:desc',
         headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
     }).success(function(data){
         // With the data succesfully returned, we can resolve promise and we can access it in controller
         deferred.resolve();
     }).error(function(){
          alert("error");
          //let the function caller know the error
          deferred.reject(error);
     });
     return deferred.promise;
  }
});

so In your controller you can use the method

myApp.controller('AngularJSCtrl', function($scope, dataService) {
    $scope.data = null;
    dataService.getData().then(function(response) {
        $scope.data = response;
    });
});

promises are powerful feature of angularjs and it is convenient special if you want to avoid nesting callbacks.

like image 32
Emil Reña Enriquez Avatar answered Oct 02 '22 04:10

Emil Reña Enriquez


No need to promise with $http, i use it just with two returns :

 myApp.service('dataService', function($http) {
   this.getData = function() {
      return $http({
          method: 'GET',
          url: 'https://www.example.com/api/v1/page',
          params: 'limit=10, sort_by=created:desc',
          headers: {'Authorization': 'Token token=xxxxYYYYZzzz'}
      }).success(function(data){
        return data;
      }).error(function(){
         alert("error");
         return null ;
      });
   }
 });

In controller

 myApp.controller('AngularJSCtrl', function($scope, dataService) {
     $scope.data = null;
     dataService.getData().then(function(response) {
         $scope.data = response;
     });
 }); 
like image 23
AlainIb Avatar answered Oct 02 '22 03:10

AlainIb


Try this

myApp.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }
]);

Just setting useXDomain = true is not enough. AJAX request are also send with the X-Requested-With header, which indicate them as being AJAX. Removing the header is necessary, so the server is not rejecting the incoming request.

like image 41
ShibinRagh Avatar answered Oct 02 '22 05:10

ShibinRagh


So you need to use what we call promise. Read how angular handles it here, https://docs.angularjs.org/api/ng/service/$q. Turns our $http support promises inherently so in your case we'll do something like this,

(function() {
  "use strict";
  var serviceCallJson = function($http) {

      this.getCustomers = function() {
        // http method anyways returns promise so you can catch it in calling function
        return $http({
            method : 'get',
            url : '../viewersData/userPwdPair.json'
          });
      }

  }

  var validateIn = function (serviceCallJson, $q) {

      this.called = function(username, password) {
          var deferred = $q.defer(); 
          serviceCallJson.getCustomers().then( 
            function( returnedData ) {
              console.log(returnedData); // you should get output here this is a success handler
              var i = 0;
              angular.forEach(returnedData, function(value, key){
                while (i < 10) {
                  if(value[i].username == username) {
                    if(value[i].password == password) {
                     alert("Logged In");
                    }
                  }
                  i = i + 1;
                }
              });
            }, 
            function() {

              // this is error handler
            } 
          );
          return deferred.promise;  
      }

  }

  angular.module('assignment1App')
    .service ('serviceCallJson', serviceCallJson)

  angular.module('assignment1App')
  .service ('validateIn', ['serviceCallJson', validateIn])

}())
like image 26
kishanio Avatar answered Oct 02 '22 03:10

kishanio


Using Google Finance as an example to retrieve the ticker's last close price and the updated date & time. You may visit YouTiming.com for the run-time execution.

The service:

MyApp.service('getData', 
  [
    '$http',
    function($http) {

      this.getQuote = function(ticker) {
        var _url = 'https://www.google.com/finance/info?q=' + ticker;
        return $http.get(_url); //Simply return the promise to the caller
      };
    }
  ]
);

The controller:

MyApp.controller('StockREST', 
  [
    '$scope',
    'getData', //<-- the service above
    function($scope, getData) {
      var getQuote = function(symbol) {
        getData.getQuote(symbol)
        .success(function(response, status, headers, config) {
          var _data = response.substring(4, response.length);
          var _json = JSON.parse(_data);
          $scope.stockQuoteData = _json[0];
          // ticker: $scope.stockQuoteData.t
          // last price: $scope.stockQuoteData.l
          // last updated time: $scope.stockQuoteData.ltt, such as "7:59PM EDT"
          // last updated date & time: $scope.stockQuoteData.lt, such as "Sep 29, 7:59PM EDT"
        })
        .error(function(response, status, headers, config) {
          console.log('@@@ Error: in retrieving Google Finance stock quote, ticker = ' + symbol);
        });
      };

      getQuote($scope.ticker.tick.name); //Initialize
      $scope.getQuote = getQuote; //as defined above
    }
  ]
);

The HTML:

<span>{{stockQuoteData.l}}, {{stockQuoteData.lt}}</span>

At the top of YouTiming.com home page, I have placed the notes for how to disable the CORS policy on Chrome and Safari.

like image 39
Daniel C. Deng Avatar answered Oct 02 '22 05:10

Daniel C. Deng