Mon service est:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var deferred;
deferred = $q.defer();
this.initialized = deferred.promise;
this.user = {
access: false
};
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: '[email protected]',
access: 'institution'
};
return deferred.resolve();
};
}
]);
J'appelle cela dans mon fichier config
via:
myApp.run([
'$rootScope', 'userService', function($rootScope, userService) {
return userService.isAuthenticated().then(function(response) {
if (response.data.user) {
return $rootScope.$broadcast('login', response.data);
} else {
return userService.logout();
}
});
}
]);
Cependant, il se plaint que then
ne soit pas une fonction. Est-ce que je ne retourne pas la promesse résolue?
De votre méthode de service:
function serviceMethod() {
return $timeout(function() {
return {
property: 'value'
};
}, 1000);
}
Et dans votre contrôleur:
serviceName
.serviceMethod()
.then(function(data){
//handle the success condition here
var x = data.property
});
Promesse résolue:
return $q.when( someValue ); // angular 1.2+
return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6
Promesse rejetée:
return $q.reject( someValue );
Retournez votre promesse, retournez différé.promise.
C'est l'API de promesse qui a la méthode 'then'.
https://docs.angularjs.org/api/ng/service/$q
L'appel à résoudre ne renvoie pas une promesse, il signale seulement la promesse que la promesse est résolue afin qu'il puisse exécuter la logique "then".
Modèle de base comme suit, rincer et répéter
http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@*" data-semver="1.3.0-beta.5"
src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="test">
<button ng-click="test()">test</button>
</div>
<script>
var app = angular.module("app",[]);
app.controller("test",function($scope,$q){
$scope.$test = function(){
var deferred = $q.defer();
deferred.resolve("Hi");
return deferred.promise;
};
$scope.test=function(){
$scope.$test()
.then(function(data){
console.log(data);
});
}
});
angular.bootstrap(document,["app"]);
</script>
Voici le code correct pour votre service:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var user = {
access: false
};
var me = this;
this.initialized = false;
this.isAuthenticated = function() {
var deferred = $q.defer();
user = {
first_name: 'First',
last_name: 'Last',
email: '[email protected]',
access: 'institution'
};
deferred.resolve(user);
me.initialized = true;
return deferred.promise;
};
}
]);
Ensuite, votre contrôleur doit s’aligner en conséquence:
myApp.run([
'$rootScope', 'userService', function($rootScope, userService) {
return userService.isAuthenticated().then(function(user) {
if (user) {
// You have access to the object you passed in the service, not to the response.
// You should either put response.data on the user or use a different property.
return $rootScope.$broadcast('login', user.email);
} else {
return userService.logout();
}
});
}
]);
Quelques points à noter sur le service:
Exposer dans un service uniquement ce qui doit être exposé. L'utilisateur doit être conservé en interne et être accessible uniquement aux accesseurs.
Lorsque vous êtes dans des fonctions, utilisez 'me', le service permettant d'éviter les cas Edge avec javascript.
J'ai deviné ce que initialisé était censé faire, n'hésitez pas à me corriger si je me suis trompé.
Pour retourner une promesse résolue, vous pouvez utiliser:
return $q.defer().resolve();
Si vous devez résoudre quelque chose ou renvoyer des données:
return $q.defer().resolve(function(){
var data;
return data;
});
Pour un code JavaScript plus court, utilisez ceci:
myApp.service('userService', [
'$q', function($q) {
this.initialized = $q.when();
this.user = {
access: false
};
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: '[email protected]',
access: 'institution'
};
return this.initialized;
};
}
]);
Vous savez que vous perdez la liaison à userService.user en la remplaçant par un nouvel objet au lieu de définir uniquement les propriétés de l'objet?
Voici ce que je veux dire comme exemple de mon exemple de code plnkr.co (exemple de travail: http://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview ):
angular.module('myApp', []).service('userService', [
'$http', '$q', '$rootScope', '$location', function ($http, $q, $rootScope, $location) {
this.initialized = $q.when(null);
this.user = {
access: false
};
this.isAuthenticated = function () {
this.user.first_name = 'First';
this.user.last_name = 'Last';
this.user.email = '[email protected]';
this.user.access = 'institution';
return this.initialized;
};
}]);
angular.module('myApp').controller('myCtrl', ['$scope', 'userService', function ($scope, userService) {
$scope.user = userService.user;
$scope.callUserService = function () {
userService.isAuthenticated().then(function () {
$scope.thencalled = true;
});
};
}]);
Essaye ça:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var deferred= $q.defer();
this.user = {
access: false
};
try
{
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: '[email protected]',
access: 'institution'
};
deferred.resolve();
};
}
catch
{
deferred.reject();
}
return deferred.promise;
]);