web-dev-qa-db-fra.com

AngularJS utilisant le service $ resource. La promesse n'est pas résolue par la demande GET

Disons un service comme celui-ci:

   services.factory('User', function($resource){
        return $resource('/rest/usersettings/:username', {}, {
            get:    {method: 'GET'},
            update: {method: 'POST'}
        });
    });

Il est donc censé être utilisé comme ceci:

        scope.user = User.get( {username: 'bob'}  );    // GET

        console.log( JSON.stringify(scope.user) )       // {"$promise":{},"$resolved":false} 

Ainsi, lorsque j'envoie une demande GET, cela se passe bien, en créant ces paramètres ur +:

http://localhost:9000/rest/usersettings/bob

Question, pourquoi j'ai:{"$promise":{},"$resolved":false}

Si ma demande GET conduit à une réponse json du serveur: {"username":"bob","email":"[email protected]"} alors je m'attends à avoir mon scope.user rempli de données.

Dois-je attendre que la promesse soit prête/résolue?

28
ses

User.get( {username: 'bob'} ) ne renvoie pas immédiatement vos données réelles. Il renvoie quelque chose contiendra vos données lorsque l'ajax revient. À ce sujet (le $promise), vous pouvez enregistrer un rappel supplémentaire pour enregistrer vos données.

Vous pouvez changer votre code pour:

   scope.user = User.get( {username: 'bob'}  );    // GET
   scope.user.$promise.then(function(data) {
       console.log(data);
   });
60
Kos Prov

Vous y obtiendrez vos données, mais pas immédiatement. Lisez les docs sur ngResource :

Il est important de réaliser que l'invocation d'une méthode d'objet $ resource retourne immédiatement une référence vide (objet ou tableau selon isArray). Une fois les données renvoyées par le serveur, la référence existante est remplie avec les données réelles. C'est une astuce utile car généralement la ressource est affectée à un modèle qui est ensuite rendu par la vue. Le fait d'avoir un objet vide n'entraîne aucun rendu, une fois que les données arrivent du serveur, l'objet est rempli avec les données et la vue se restitue automatiquement en affichant les nouvelles données. Cela signifie que dans la plupart des cas, il n'est jamais nécessaire d'écrire une fonction de rappel pour les méthodes d'action.

12
Stewie

Pour l'instant j'utilise ceci (il semble que je duplique cette question)

User.get({
    username: 'bob'
}, function(user) {

    user.$update(
        function(data, headers) {
            console.log("GOOD");
        },
        function(err, headers) {
            console.log("BAD");
        }
    );
});
3
ses

Cela devrait fonctionner:

User.get( {username: 'bob'} ).$promise.then(function(data) {
    scope.user = data.toJSON();
});

toJSON () nettoie les propriétés internes d'Angular ($$).

2
devside