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

后端 未结 7 1410
轻奢々
轻奢々 2020-11-29 16:58

I have the following code in the controller.js,

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

myApp.service(\'dataService\', function($http) {
delete $http.def         


        
相关标签:
7条回答
  • 2020-11-29 17:21

    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;
         });
     }); 
    
    0 讨论(0)
  • 2020-11-29 17:21

    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])
    
    }())
    
    0 讨论(0)
  • 2020-11-29 17:31

    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.

    0 讨论(0)
  • 2020-11-29 17:32

    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.

    0 讨论(0)
  • 2020-11-29 17:32

    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.

    0 讨论(0)
  • 2020-11-29 17:45

    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.

    0 讨论(0)
提交回复
热议问题