web-dev-qa-db-fra.com

Comment utiliser HTTP.GET dans AngularJS correctement? En particulier, pour un appel d'API externe?

J'ai le code suivant dans le 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();
});

Mais, je pense que je me trompe probablement avec la question liée à la SCRO. Pouvez-vous m'indiquer la bonne façon de passer cet appel? Merci beaucoup!

37
Anand Ram

Tout d'abord, votre gestionnaire success() renvoie simplement les données, mais celles-ci ne sont pas renvoyées à l'appelant de getData() car elles figurent déjà dans un rappel. $http est un appel asynchrone qui renvoie un $promise. Vous devez donc enregistrer un rappel lorsque les données sont disponibles.

Je vous conseillerais de consulter Promises et la bibliothèque $ q dans AngularJS, car ils constituent le meilleur moyen de transmettre des appels asynchrones entre services.

Par souci de simplicité, voici votre même code réécrit avec une fonction de rappel fournie par le contrôleur appelant:

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;
    });
});

Désormais, $http renvoie déjà une promesse $, ceci peut donc être réécrit:

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;
    });
});

Enfin, il existe de meilleurs moyens de configurer le service $http pour gérer les en-têtes pour vous en utilisant config() pour configurer le $httpProvider. Consultez la documentation $ http pour des exemples.

77
Kevin Stone

Je vous suggère d'utiliser 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;
  }
});

donc dans votre contrôleur, vous pouvez utiliser la méthode

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

les promesses sont une fonctionnalité puissante de angularjs et il est particulièrement pratique si vous voulez éviter les rappels imbriqués. 

9
Emil Reña Enriquez

Pas besoin de promettre avec $ http, je l'utilise seulement avec deux déclarations:

 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 ;
      });
   }
 });

Dans le contrôleur 

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

Essaye ça

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

Il ne suffit pas de définir useXDomain = true. Les demandes AJAX sont également envoyées avec l'en-tête X-Requested-With, qui les indique comme étant AJAX. La suppression de l'en-tête est nécessaire pour que le serveur ne rejette pas la demande entrante.

2
ShibinRagh

Vous devez donc utiliser ce que nous appelons une promesse. Lisez comment angular le traite ici, https://docs.angularjs.org/api/ng/service/ $ q. Tourne nos promesses de support $ http de manière inhérente, donc dans votre cas, nous ferons quelque chose comme ça,

(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])

}())
1
kishanio

Utilisez Google Finance comme exemple pour récupérer le dernier prix de clôture du ticker ainsi que la date et l'heure mises à jour. Vous pouvez visiter YouTiming.com pour l'exécution au moment de l'exécution.

Le 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
      };
    }
  ]
);

Le controlle:

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
    }
  ]
);

Le HTML:

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

En haut de la page d'accueil de YouTiming.com, j'ai placé les notes sur la désactivation de la stratégie CORS sur Chrome et Safari.

1
Daniel C. Deng

Lorsque vous appelez une promesse définie dans un service ou dans une usine, assurez-vous d'utiliser le service, car je ne pouvais pas obtenir de réponse d'une promesse définie dans une usine. C’est ainsi que j’appelle une promesse définie dans un service. 

myApp.service('serverOperations', function($http) {
        this.get_data = function(user) {
          return $http.post('http://localhost/serverOperations.php?action=get_data', user);
        };
})


myApp.controller('loginCtrl', function($http, $q, serverOperations, user) {        
    serverOperations.get_data(user)
        .then( function(response) {
            console.log(response.data);
            }
        );
})
0
Lukáš Černý