Reputation: 151
Hi I am trying to implement Promise Chaining Using q-library in my angular project below are my 2 methods and the way they are chained.I have also posted method implementations to understand my problem. Now in pathUserDataFromAuthService
method I would like to access the Etag value that i have set in the first Promise i.e getUserDataFromAuthServer
using setEtag()
method , The problem here is getEtag()
method is called before the first promise data is resolved .
How would ensure that correct Etag value is coming up
Any help in this regard would be great
getUserDataFromAuthServer(user)
.then(pathUserDataFromAuthService(user))
and the method code is as below
getUserDataFromAuthServer = function(user){
var defer=$q.defer();
$http.get(autherizationURL+'/'+'api/users/'+user.username)
.then(function(response){
var ETag =response.headers().etag;
console.log("etag"+ETag)
setEtag(ETag)
console.log("Etag Set changed");
defer.resolve(response.data);
},function(error){
defer.reject(error.statusText);
});
return defer.promise;
};
var pathUserDataFromAuthService = function (user){
var defer=$q.defer();
var passwordtobesaved ={
"firstName": user.firstName,
"lastName": user.lastName
};
var tag = getEtag();
$http.put(autherizationURL+'/'+'api/users/'+user.username,passwordtobesaved,{
headers:{
"If-Match": tag
}
}).then(function(response){
defer.resolve(response.data);
},function(error){
defer.reject(error.statusText);
});
return defer.promise;
};
Upvotes: 0
Views: 241
Reputation: 19288
As already pointed out, the main issue is that then()
accepts function(s).
After that, the need to pass user
makes things slightly awkward but nothing that javascript can't cope with.
A number of approaches are possible. Here are two.
1. Pass user
and etag
separately, with the help of .bind()
It's maybe not obvious how this works because the two parameters user
and etag
are passed by different mechanisms :
user
: is "bound"etag
: is delivered by the promise chain to the function returned by .bind()
getUserDataFromAuthServer(user).then(pathUserDataFromAuthService.bind(null, user));
getUserDataFromAuthServer = function(user) {
return $http.get(autherizationURL + '/api/users/' + user.username).then(function(response) {
return response.headers().etag;
});
};
var pathUserDataFromAuthService = function(user, etag) {
return $http.put(autherizationURL + '/api/users/' + user.username, {
"firstName": user.firstName,
"lastName": user.lastName
}, {
headers: { "If-Match": etag }
}).then(function(response) {
return response.data;
});
};
2. Deliver user
and etag
as properties of a single object
This is probably more intuitive. The promise chain delivers a single object to pathUserDataFromAuthService
as data
.
getUserDataFromAuthServer(user).then(pathUserDataFromAuthService);
getUserDataFromAuthServer = function(user) {
return $http.get(autherizationURL + '/api/users/' + user.username).then(function(response) {
return {
user: user,
etag: response.headers().etag
};
});
};
var pathUserDataFromAuthService = function(data) {
return $http.put(autherizationURL + '/api/users/' + data.user.username, {
"firstName": data.user.firstName,
"lastName": data.user.lastName
}, {
headers: { "If-Match": data.etag }
}).then(function(response) {
return response.data;
});
};
In both solutions setEtag()
/ getEtag()
disappear on the assumption that they existed (in the question) solely as a mechanism for passing ETag
. If necessary for other reasons (eg side-effects), they can be reintroduced without consequence (unless they throw).
Upvotes: 0
Reputation: 3297
No need to use defer, this is an anti-pattern. You can simply pass on the promise by returning the http request.
Here's how it should be:
getUserDataFromAuthServer = function(user){
return $http.get(autherizationURL+'/'+'api/users/'+user.username)
.then(function(response){
var ETag =response.headers().etag;
console.log("etag"+ETag)
setEtag(ETag)
console.log("Etag Set changed");
return response.data;
}
};
Same thing can be done in your second function, although I don't see why it's needed since you do nothing when it ends.
var pathUserDataFromAuthService = function (user){
var passwordtobesaved ={
"firstName": user.firstName,
"lastName": user.lastName
};
var tag = getEtag();
return $http.put(
autherizationURL + '/' + 'api/users/' + user.username,
passwordtobesaved,
{ headers: { "If-Match": tag } }
)
};
Upvotes: 1