Resolving Muliple Promise Node-JS - angularjs

I have array of promises.
var defered = q.defer();
// promises is a array which will have different promises
var promises = [];
q.all(promises).then(function(response){
// SUSSECCFULLY RESOLVED ALL PROMISE THEN EXECUTION COME HERE
}, function(error){
// IF ANY PROMISE FAILED THEN EXECUTION COME HERE
});
I want to process all promises whether they fail or they resolved.

Use case 1:
You want to handle errors to be handled separately and success on all not called:
var myApp = angular.module('myApp', []);
function MyCtrl($scope, $q, $timeout) {
function prOne(){
var d = $q.defer();
setTimeout(function(){
d.reject();
}, 100);
return d.promise;
}
function prTwo(){
var d = $q.defer();
setTimeout(function(){
d.resolve();
}, 100);
return d.promise;
}
$q.all([prOne().catch(function(){ console.log('fail for one'); return $q.reject() }), prTwo()]).then(function(){
console.log('success');
return $q.resolve();
}).catch(function(){
console.log('error');
});;
}
myApp.controller('MyCtrl', MyCtrl);
Use case 2:
You want to handle errors to be handled separately and success on all called anyway:
var myApp = angular.module('myApp', []);
function MyCtrl($scope, $q, $timeout) {
function prOne(){
var d = $q.defer();
setTimeout(function(){
d.reject();
}, 100);
return d.promise;
}
function prTwo(){
var d = $q.defer();
setTimeout(function(){
d.resolve();
}, 100);
return d.promise;
}
$q.all([prOne().catch(function(){ console.log('fail for one'); return $q.resolve() }), prTwo()]).then(function(){
console.log('success');
return $q.resolve();
}).catch(function(){
console.log('error');
});;
}
myApp.controller('MyCtrl', MyCtrl);

Related

ui-router resolve use angular-loading-bar?

What I want to do is to use the ui-router resolution angular install-bar.
How can I run the codes given in Resolve?
resolve: {
return {
loadedData: function($rootScope, $q) {
var deferred = $q.defer();
$rootScope.$on('cfpLoadingBar:completed', function() {
console.log("complete");
deferred.resolve();
});
return deferred.promise;
}
};
}
In terms of being an example;
greeting: function($q, $timeout){
var deferred = $q.defer();
$timeout(function() {
deferred.resolve('Hello!');
}, 1000);
return deferred.promise;
}
Instead of
I want to run this code, it works every timeout.
Rootscope.on works only when the page is loaded.
greeting: function($q, $rootScope){
var deferred = $q.defer();
$rootScope.$on('cfpLoadingBar:completed', function(){
deferred.resolve('Hello!');
});
return deferred.promise;
}

Is it possible to test $resource success and error callbacks in a controller?

I would like to test $resource success and error callbacks in my controller. I don’t want to use $httpBackend as that would be used to test the data service. It seems that there is no way to do it though - the only solution I have found is to use promises instead which I could either resolve or reject. Does this sound right? Anyway, here is what I have at the moment - currently it only tests whether the $resource get() is called:
The controller:
angular
.module('myModule')
.controller('MyCtrl', MyCtrl);
MyCtrl.$inject = [
'dataService'
];
function MyCtrl(
dataService
) {
var vm = this;
vm.getData = getData;
function getData() {
dataService.getData().get(function(response) {
// stuff to test
},
function(error) {
// stuff to test
});
}
The test:
describe('Controller: MyCtrl', function() {
var MyCtrl;
var rootScope;
var scope;
var dataServiceMock = {
getData: jasmine.createSpy('getData')
};
beforeEach(function()
inject(function($controller, $rootScope) {
rootScope = $rootScope;
scope = $rootScope.$new();
MyCtrl = $controller('MyCtrl as vm', {
dataService: dataServiceMock,
});
});
});
describe('vm.getData()', function() {
beforeEach(function() {
dataServiceMock.getData.and.returnValue({
get: jasmine.createSpy('get')
});
});
it('gets the data', function() {
scope.vm.getData();
expect(dataServiceMock.getData().get).toHaveBeenCalled();
});
});
});
Try this
function getData (query) {
var deferred = $q.defer();
var httpPromise = $resource(query,{},{
post:{
method:"GET",
isArray: false,
responseType: "json"
}
});
httpPromise.post({}, {},
function(data) {
try {
var results = {}
results.totalItems = data.response;
deferred.resolve(results);
} catch (error) {
console.log(error.stack);
deferred.reject();
}
},
function(error) {
deferred.reject();
}
);
return deferred.promise;
}

every method of angular service have same line of code for promise ($deferred)

I am first time using angular JS so kindly bear my question. While creating service in angular JS I have to write var deferred = $q.defer(); and then return deferred.promise; in every method of service which use $http()
Is there any shorthand or alternative way to do so?
for eg:
(function() {
'use strict';
angular
.module('app')
.service('AuthService', function($q, $http, $interval, $timeout, BASE_URL) {
var service = {
login: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/getLogin', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
},
signup: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/register', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
},
forgot: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/forgot', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
}
}
return service;
});
here you can see I have to rewrite the same line of code in every method of service
use $http methods without any other code:
return $http.post(BASE_URL + '/api/getLogin', formdata)
all $http methods return promise by default

How can I use angularjs promise chain in a service and controller?

I found this plnkr link on the web but I need use it with 2 or 3 more ajax calls which doesn't require an argument from the first ajax call. How can I do it with error handling?
var app = angular.module("app", []);
app.service("githubService", function($http, $q) {
var deferred = $q.defer();
this.getAccount = function() {
return $http.get('https://api.github.com/users/haroldrv')
.then(function(response) {
// promise is fulfilled
deferred.resolve(response.data);
return deferred.promise;
}, function(response) {
// the following line rejects the promise
deferred.reject(response);
return deferred.promise;
});
};
});
app.controller("promiseController", function($scope, $q, githubService) {
githubService.getAccount()
.then(
function(result) {
// promise was fullfilled (regardless of outcome)
// checks for information will be peformed here
$scope.account = result;
},
function(error) {
// handle errors here
console.log(error.statusText);
}
);
});
http://plnkr.co/edit/kACAcbCUIGSLRHV0qojK?p=preview
You can use $q.all
var promises=[
$http.get(URL1),
$http.get(URL2),
$http.get(URL3),
$http.get(URL4)
];
$q.all(promises).then(function(response){
console.log('Response of Url1', response[0]);
console.log('Response of Url2', response[1]);
console.log('Response of Url3', response[2]);
console.log('Response of Url4', response[3]);
}, function(error){
});
I have forked your plunkr with $q
First you should make deferred variable local for each ajax call you want to return a promise. So, you have to create 2-3 functions (as many as your ajax calls) and keep them in an array. Then you should use:
$q.all([ajax1,ajax2,ajax3]).then(function(values){
console.log(values[0]); // value ajax1
console.log(values[1]); // value ajax2
console.log(values[2]);}); //value ajax3
example:
function ajax_N() {
var deferred = $q.defer();
http(...).then((response) => {
deferred.resolve(response);
}, (error) => {
deferred.reject(error);
});
return deferred.promise;
}
$q.all([
ajax_1,ajax_2,ajax_3
]).then(function(values) {
console.log(values);
return values;
});
Use $q.all in this case. It will call getAccount and getSomeThing api same time.
var app = angular.module("app", []);
app.service("githubService", function($http, $q) {
return {
getAccount: function () {
return $http.get('https://api.github.com/users/haroldrv');
},
getSomeThing: function () {
return $http.get('some thing url');
}
};
});
app.controller("promiseController", function($scope, $q, githubService) {
function initData () {
$q.all([githubService.getAccount(), githubService.getSomeThing()])
.then(
function (data) {
$scope.account = data[0];
$scope.someThing = data[1];
},
function (error) {
}
);
}
});

Angular unit testing promises

I am new to promises and seem to have the actual code working, but trying to write a unit test too...
Heres my controller:
appModule.controller('MyController', function($scope, myService, $timeout, mySecondService) {
$scope.accept = false;
$scope.loading = false;
$scope.text = 'Some text';
$scope.testCall = function() {
$scope.person = true;
$scope.text = '';
$scope.loading = true;
myService.getWeather()
.then(function(data) {
if (data.valid===true) {
$timeout(function(){
$scope.loading = false;
$scope.accept = true;
$timeout(function(){
$scope.customer.cart = false;
}, 1400);
}, 1500);
}
else {
$scope.person = false;
$scope.newMessage = mySecondService.getItem();
}
}, function(error) {
$scope.person = false;
$scope.newMessage = mySecondService.getItem();
});
}
});
ControllerSpec:
beforeEach(module('myApp'));
describe("MyController Tests", function() {
var scope;
var ctrl;
var customerInfo = {
"ID" : "212143513",
"firstName" : "Lewis",
"lastName" : "Noel"
};
beforeEach(inject(function($rootScope, $controller, myService) {
scope = $rootScope.$new();
rootScope = $rootScope;
mockMyService = myService;
ctrl = $controller('MyController', {$scope:scope, myService:mockMyService});
spyOn(scope, 'testCall').and.callThrough();
}));
it("On controller load, initialise variables", function() {
expect(scope.text).toEqual('Some text');
expect(scope.loading).toEqual(false);
expect(scope.accept).toEqual(false);
});
});
The above tests the initailisation of the $scope, but nothing within the service...
Here's my service:
appModule.factory('myService', function ($http, $q) {
return {
getWeather: function() {
return $http.get('/cart/customerCart/546546')
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
}
else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});
If you're asking how to test services in general, here's what I do:
describe("myService", function() {
var myService;
beforeEach(inject(function($rootScope, _myService_) {
myService = _myService_;
}));
it("On controller load, initialise variables", function() {
var result;
myService.getWeather().then( function (data) {
result = data;
});
$rootScope.$apply();
expect(result).toEqual(whatever);
});
});
Notes:
You can use the _myService_ underscore trick to get the service myService without it creating a local variable with that name (see docs).
You need to call $rootScope.$apply() to flush promises in tests. see docs
EDIT:
You're using promises wrongly, I would refactor your factory as so (untested):
appModule.factory('myService', function ($http, $q) {
return {
getWeather: function() {
var defer = $q.defer();
$http.get('/cart/customerCart/546546')
.then(function(response) {
if (typeof response.data === 'object') {
defer.resolve(response.data);
}
else {
// invalid response
defer.reject(response.data);
}
}, function(response) {
// something went wrong
defer.reject(response.data);
});
return defer.promise;
}
};
});

Resources