angular service not being called in .then() - angularjs

I am having problem calling my $apartments service within this controller.
$scope.checkout = () => {
$scope.stripe_err = null;
if ($scope.subscription.type === '') {
$scope.stripe_err = 'No subscription selected';
return;
}
Stripe.card.createToken($scope.stripeToken, stripeResponse);
}
let stripeReponse = (status, response) => {
if (status !== 200) {
$scope.stripe_err = status;
return;
} else {
$stripe.checkout(token, response.id)
.then((result) => {
$scope.receipt = result.data.receipt / 100; // Stripe amount is in cents
$scope.totalPrice = '';
$scope.stripeToken = { number: '', cvc: '', exp_month: '', exp_year: '' };
})
.catch(err => console.error(err));
}
$apartments.postApt(token, $scope.userInfo); // The request finishes when my services is outside the .then()
};
but when I replace the parameters with the wrong one $apartments.postApt(result, $scope.userInfo);
then I get this error PUT http://localhost:7000/landlord-api/units/[object%20Object]?access_token=[object%20Object] 500 (Internal Server Error)
This is how my $apartments service looks like. I'm not sure if its my service because if I call it outside of $stripe.checkout() it will get invoke.
exports.$apartments = function ($http, $q) {
function postApt (landlord_id, newApt) {
var deferred = $q.defer();
$http.put('/landlord-api/units/' + landlord_id + '?access_token=' + landlord_id, newApt)
.then(function (result) {
return deferred.resolve(result);
})
.catch(err => deferred.reject(err));
return deferred.promise;
return {
postApt: postApt
}
}
UPDATE: I still haven't solved it. What I noticed is if I put my $apartments service in .then() the request just stays pending, but if I put it outside the .then() it finishes the request and I get the appropriate response.

Check your landlord_id, look at the response, you are sending an object:
access_token=[object%20Object]
Make a console.log of landlord_id so you get the structure.
A common posibility is that it is an array.

Try like this .
exports.$apartments = function ($http, $q) {
function postApt (landlord_id, newApt) {
var deferred = $q.defer();
angular.element(document.getElementById("YOUR_FORM_ID")).scope().getlandlord.then
(function (result)){
return deferred.resolve(result);
}).catch(err => deferred.reject(err));
return deferred.promise;
return {
postApt: postApt
}
}
scope.getlandlord(landlord_id,newApt){
return $http.post('/landlord-api/units/' + landlord_id + '?access_token=' + landlord_id, newApt).then(function(response) {
return response;
});
};

Well the problem probably exists here:
$stripe.checkout(token, response.id)
.then((result) => {
// your stuff
})
.then((result) => {
// your stuff
})
.catch((err) => { });
Remove the first .then() and see if you get the $result.data.success logic working in the second (now only) .then()

Related

How to call an asynchronous service N times

Promise in ForEach
I'm having a problem, I need to call a service N times and I've tried this:
This is my function that calls the service, I send a parameter that is "code" and returns a promise.
var get222 = function(codigo) {
var defer = $q.defer();
var cbOk = function(response) {
//console.log(response);
defer.resolve(response);
}
var cbError = function(error) {
//console.log(error);
defer.reject(error);
}
VentafijaAccessService.getProductOfferingPrice(codigo, cbOk, cbError);
return defer.promise;
}
After this function, I get the codes and I need to make a call N times and when they finish returning the promise to get the answer for each code I send.
var getProductOfferingPrice = function(_aCodigoOfertas) {
var deferred = $q.defer();
var results = [];
var promises = [];
angular.forEach(_aCodigoOfertas, function(codigo) {
promises.push(get222(codigo));
});
$q.all(promises)
.then(function(results) {
// here you should have all your Individual Object list in `results`
deferred.resolve({
objects: results
});
});
return deferred.promise;
};
The calls to the services IF THEY ARE EXECUTED, but never returns the promise, I can not get the response of each one.
EDIT
VentaDataService.js
var get222 = function(codigo) {
return $q(function(resolve, reject) {
VentafijaAccessService.getProductOfferingPrice(codigo, resolve, reject);
});
}
var getProductOfferingPrice = function(_aCodigoOfertas) {
return $q.all(_aCodigoOfertas.map(function(codigo) {
return get222(codigo);
}));
};
VentaFijaController.js
var cbOk2 = function(response) {
console.log(response);
}
var cbError2 = function(error) {
console.log(error);
}
VentafijaDataService.getProductOfferingPrice(codigoOfertas)
.then(cbOk2, cbError2)
There's no need to wrap a new promise around this. Just return the $q.all() promise:
VentafijaAccessService.getProductOfferingPriceAllPromise = function(_aCodigoOfertas) {
var promises = [];
angular.forEach(_aCodigoOfertas, function(codigo) {
promises.push(get222(codigo));
});
return $q.all(promises);
};
The resolved value of the returned promise will be an array of results.
VentafijaAccessService.getProductOfferingPriceAllPromise(...).then(results => {
console.log(results);
}).catch(err => {
console.log(err);
});
If _aCodigoOfertas is an array, you can further simply getProductOfferingPrice to this:
VentafijaAccessService.getProductOfferingPriceAllPromise = function(_aCodigoOfertas) {
return $q.all(_aCodigoOfertas.map(function(codigo) {
return get222(codigo);
}));
};
You can also vastly simplify get222() to this:
var get222 = function(codigo) {
return $q(function(resolve, reject)) {
// call original (non-promise) implementation
VentafijaAccessService.getProductOfferingPrice(codigo, resolve, reject);
});
}
Then, in the controller, you could do this:
VentafijaDataService.getProductOfferingPriceAllPromise(codigoOfertas).then(function(result) {
console.log(result);
}).catch(function(e) {
console.log('Error: ', e);
});

Call a controller with the data results of 2 functions

I am a newbie with Angularjs, and trying to figure it up:
in boardService there are 2 function
var getLiveCards = function () {
return $http.get(endpointService.getLiveCards(), {})
.then(function (response) {
return response.data;
}, function (error) {
return $q.reject(error.data.Message);
}
);
};
var getRelationshipTypes = function () {
return $http.get(endpointService.getRelationshipTypes(), {})
.then(function (response) {
return response.data;
}, function (error) {
return $q.reject(error.data.Message);
}
);
};
and
i am trying to call a controller, with the data received from both of the functions:
vm.relationsEdit = function (card) {
boardService.getLiveCards()
.then(function (data) {
vm.liveCards = data
boardService.getRelationshipTypes()
.then(function (types) {
vm.types = types;
cardRelationsModalService.relationsEdit(card, vm.liveCards, vm.types)
.then(function (response) {
console.log("Card edited: " + response);
});
})
}, onError);
}
When i put a break-point with chrome debugger, in that line: vm.liveCards = data, data contains data from getLiveCards but nothing is happen after that.
What am I doing wrong? how can i get data from the 2 functions and send it to cardRelationsModalService.relationsEdit function?

Convert promise in angular 1 to observable in angular 2

i'm still learning observable in angular 2, and has not been able to figure out how to convert my code in angular 1 to angular 2.
function promiseFunc() {
var deferred = $q.defer();
$http.post(url, something)
.then(function (response) {
if (response === 1) deferred.resolve(response.data);
else deferred.reject();
}).catch(function (e) {
deferred.reject(e);
});
return deferred.promise;
}
Can anyone tell me how i can convert this code with angular 2 observable?
EDIT:
And what if the http.post is optional?
function promiseFunc(param1) {
var deferred = $q.defer();
if (param1 === 1) {
deferred.resolve(1);
} else {
$http.post(url, something)
.then(function (response) {
if (response.x === 1) deferred.resolve(response);
else deferred.reject();
}).catch(function (e) {
deferred.reject(e);
});
}
return deferred.promise;
}
What i'm missing in observable is the ability to call resolve and reject. Can it be done in observable?
someMethod() {
if(param === 1) {
return Observable.of(1);
} else {
return this.http.post(url, something)
.map(
response => {
let data = response.json();
if(data === 1) {
return 1;
}
throw 'some error';
}
);
}
}
then use it like
this.someMethod().subscribe(
data => console.log(data),
error => console.log(error),
() => console.log('completed')
);

How can I find out how many records are in the list after AngularJS $resource query()

I'm struggling with something that I think should be pretty simple.
I want to see how many items are returned from a query() but using length isn't working for me.
This my code
getItems = function () {
// retrieve the list
theList = Users.query();
theList.$promise.then(function (res) {
console.log("success");
})
.catch(function (req) {
console.log("error");
})
.finally(function () {
});
return theList;
}
$scope.users = getItems();
console.log($scope.users.length);
This is my $resource:
.factory('Users', function ($resource) {
return $resource('https://example.com/:id', { id: '#id' }, {
update: { method: 'PUT' }
});
})
The console shows 0 even if there are items in the list.
Any idea what I'm doing wrong?
Try
getItems = function () {
// retrieve the list
theList = Users.query();
theList.$promise.then(function (res) {
console.log("success");
$scope.users = res;
console.log($scope.users.length);
})
.catch(function (req) {
console.log("error");
});
}
getItems();
Your getItem() is returning promise. So extract list from it and then try the length just you did inside your getItem();
//try this
getItems().then(function(result) {
$scope.users = result;
console.log('result: %o', $scope.users.length);
})

synchronous and asynchronous calling in angularJS with promise and defer

I created following controller with 2 service calling with services. Second response comes before then first. i want to do like i need first response first and second response second. but i just stuck with async and sync please help me for solving.
Second call is depends on first call. For example if first call returns 10 record then i have to call second web service 10 time taking id from first response. so i use for loop but it is not proper.
Controller
var mycompaigndata = [];
asyncService.loadDataFromUrls($http.get(WSURL + 'api/first/',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
asyncService.loadDataFromUrls($http.get(WSURL + 'api/second',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
Service
app.service('asyncService', function($http, $q)
{
return {
loadDataFromUrls: function(url)
{
var deferred = $q.defer();
var urlCalls = [];
urlCalls.push(url);
$q.all(urlCalls)
.then(
function(results)
{
deferred.resolve(results)
},
function(errors)
{
deferred.reject(errors);
},
function(updates)
{
deferred.update(updates);
});
return deferred.promise;
}
};
});
To make sure the second calls are executed after the first one is finished, put the second call within then of the first call. To make multiple 'second' calls depending on the number of results of the first call, use $q.all.
asyncService.loadDataFromUrls('api/first/')
.then(function(firstData) {
//assuming firstData is an array of 'x' items, do a call for each of these items:
console.log('results of first call holds ' + firstData.length + ' items');
var promises = [];
for(var i = 0; i<firstData.length; i++){
var id = firstData[i].id;//you can use this to pass to the second call
promises.push(asyncService.loadDataFromUrls('api/second'));
}
return $q.all(promises);
})
.then(function(results) {
//'results' is an array of results, the nth item holds the result of the 'nth' call to loadDataFromUrls
for(var i = 0; i<results.length; i++){
console.log('result nr. ' + i + ' :' + results[i])
}
});
By using return $q.all(promises), you're avoiding the promise pyramid of doom, and keep a flat structure.
Your service code doesn't need to loop anymore. As a sidenote, you can shorten the code of the service and avoid using the 'explicit promise construction antipattern' (see here) like this:
app.service('asyncService', function($http, $q)
{
return {
loadDataFromUrls: function(url)
{
return $http.get(WSURL + url, {
headers: {
"Authorization": 'Bearer <my-token>'
}
}).then(function(response){ return response.data; });
}
};
});
Your asyncService seems completely unnecessary and unuseful.
It sounds like you just need to learn how to chain promises and use $q.all correctly:
function queryApi(subUrl) {
return $http.get(WSURL + subUrl, {
headers: {
"Authorization":'Bearer <my-token>'
}
}).then(function (result) { return result.data; });
}
queryApi('api/first/')
.then(function (data) {
return $q.all(data.map(function (entry) {
return queryApi('api/second/' + entry.id);
}));
})
.then(function (results) {
console.log(results);
});
put second request inside first request promise:
var mycompaigndata = [];
asyncService.loadDataFromUrls($http.get(WSURL + 'api/first/',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
asyncService.loadDataFromUrls($http.get(WSURL + 'api/second',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
});
I think the best answer is to use loop since you need to iterate the response to get the id.
asyncService.loadDataFromUrls(WSURL + 'api/first/')
.then(function(data) {
//iterate to get the id
//call service again
asyncService.loadDataFromUrls(WSURL + 'api/first/')
.then(function(data) {
//code here
});
});
Service
app.service('asyncService', function($http, $q) {
return {
loadDataFromUrls: function(url) {
return $http.get(url, {
"Authorization":'Bearer <my-token>'
});
}
};
});

Resources