web-dev-qa-db-fra.com

HTTP angulaire renvoie à l'état $$

J'ai défini les paramètres d'usine suivants:

angular.module("account").factory("users",["$http",
    function(a){
      return {
         getUser: function(){
            return a.get("/user/me").then(function(r){
                return r.data;
            });
        }
    };
  }
]);

Et mon contrôleur:

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        a.user = u.getUser();
        console.log(a.user);
}]);

Voici le fichier console.log:

 d {$$state: Object, then: function, catch: function, finally: function} $$state: Object status: 1 value: Object user: Object__v: 0 _id: "54c1fg29f36e117332000005" temp: "1ce3793175e0b2548fb9918385c2de09"  __proto__: Object __proto__: Object __proto__: Object __proto__: Object

Le code ci-dessus renvoie un objet state au lieu de l'utilisateur. Mais à partir du journal, l'objet d'état a l'objet utilisateur dans la valeur. Comment puis-je obtenir l'objet utilisateur? Ou est-ce que je fais cela complètement faux?

Je sais que l’autre méthode consiste à renvoyer $ http.get et à appeler la méthode then () dans le contrôleur. Mais j'utiliserai fréquemment l'objet utilisateur et si j'appelle la méthode then () dans le contrôleur, c'est presque la même chose que d'utiliser $ http.get dans le contrôleur au lieu de l'usine.

16
wdphd

JavaScript I/O est généralement, y compris dans ce cas asynchrone. Votre appel getUser renvoie un $ q promise. Pour le dérouler, vous devez le chaîner, puis le dérouler comme tel:

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        u.getUser().then(function(user){
            a.user = user;
            console.log(a.user);
        });
}]);

Si vous utilisez le routage, vous pouvez également consulter l'option resolve de la route. Voir aussi cette question connexe .

25
Benjamin Gruenbaum
angular.module("account").factory("users",["$http",
    function(a){
      var factObj = {
         user: null,
         getUser: function(){
            return a.get("/user/me").then(function(r){
                factObj.user = r.data;
            });
        }
      factObj.getUser();

      return factObj;
    };
  }
]);

angular.module("test.controllers",["account"])
.controller("TestCtrl",["$scope","users",
    function(a,u){
        a.userService = u;
}]);

À votre avis

<div ng-controller="TestCtrl as test">{{test.userService.user}}</div>

Les modifications basées sur les commentaires sont vraies, cela ne fonctionnerait pas avec le contrôleur ou la vue comme vous les aviez probablement, mais ce modèle fonctionne bien et supprime la nécessité d’avoir .then dans chaque contrôleur pouvant réutiliser les données.

Le stockage typique de votre modèle dans l'usine ou le service chargé de l'extraction des données facilite l'accès à ces données dans toutes les vues où vous en avez besoin. Inconvénient: vous récupérerez l'utilisateur lorsque cette usine est référencée au lieu d'activer explicitement la fonction getUser à partir du contrôleur. Si vous souhaitez vous assurer que vous pouvez stocker la promesse dès la première demande dans la fonction getUser et la renvoyer pour tous les appels suivants, si elle est déjà définie, vous pouvez appeler getUser plusieurs fois sans répéter la demande d'API.

2
shaunhusain

J'ai ici un scénario similaire .. J'espère que cela aidera quelqu'un ... 

mon usine .. 

 angular.module('programList.services',[])
    .factory('PROGRAMS', function($http) {
     return {
       getprogramList: function() {
       return $http.get('/api/programs/list').then(function(result) {
       return result.data[0];
       });
      }
     };
    });

Ceci est mon contrôleur ..

 angular.module('programList.services'])
 .controller('tviProgramsController',
    function($scope,$state,$stateParams,PROGRAMS){
        //this is the call to access the list as answered by Benjamin Above using then on success 
        PROGRAMS.getprogramList().then(function(list){
                  $scope.programlist = list;
              });
  });

;

C'est sur le routeur côté serveur ...

  var express     = require('express'),
     programscontroller = require(path + 'programservercontroller'),
     router         = new express.Router();
     router.get('/api/programs/list', programscontroller.programlist);

Ceci est le module pour l'appel mysql

var con   = require('../../database/dbcon'),
mysql = require('mysql');

module.exports.programlist = function(req, res){
 var data = req.params.data;
 var sql = "CALL `sp_programlist`";
  con.query(sql, function(err, result) {
      if(err){
          throw err;
      } else {
          res.send(JSON.stringify(result));
      }
     });
};
0
sireken