Declare a function inside another function - angularjs

i have this function:
charCtrl.loadDataFromToMonth= function (from,to,year) {
var url = servername+'admin/dashboard/getIncidentDepartByMonthFromTo/'+from+'/'+to+'/'+year;
//alert(url);
function onSuccess(response) {
console.log("+++++getIncidentDepartByMonthFromTo SUCCESS++++++");
if (response.data.success != false) {
$scope.payloadgetIncidentDepartByMonthFromTo = response.data.data;
var getIncidentDepartByMonthFromTo= $scope.payloadgetIncidentDepartByMonthFromTo;
// alert('dddd'+JSON.stringify(loadedDataByMission));
$scope.labelsf = [];
$scope.qsd = [];
$scope.dataf = [];
getIncidentDepartByMonthFromTo.forEach(function(data) {
var monthNumber=$filter('date')(data.la_date, "MM");
$scope.labelsf.push($filter('monthName')(monthNumber));
$scope.dataf.push(data.number);
$scope.qsd.push('ff','ff','ff');
//alert($scope.labelsf );
});
//alert( $scope.dataf );
charCtrl.loadDataFromToMonthArrivee(from,to,year);
} else {
alert("failure");
}
// $scope.stopSpin('spinner-0');
};
function onError(response) {
console.log("-------getIncidentDepartByMonthFromTo FAILED-------");
//$scope.stopSpin('spinner-0');
console.log(response.data);
console.log("Inside getIncidentDepartByMonthFromTo error condition...");
};
//----MAKE AJAX REQUEST CALL to GET DATA----
ajaxServicess.getData(url,username,password, 'GET', '').then(onSuccess, onError);
};
this function return for exemple: $scope.dataf = ['45','48','255'];
I have a second function, by the way its the same function but it gets data from other Rest service:
charCtrl.loadDataFromToMonthArrivee= function (from,to,year) {
var url = servername+'admin/dashboard/getIncidentArriveeByMonthFromTo/'+from+'/'+to+'/'+year;
//alert(url);
function onSuccess(response) {
console.log("+++++getIncidentDepartByMonthFromTo SUCCESS++++++");
if (response.data.success != false) {
$scope.payloadgetIncidentArriveeByMonthFromTo = response.data.data;
var getIncidentArriveeByMonthFromTo= $scope.payloadgetIncidentArriveeByMonthFromTo;
// alert('dddd'+JSON.stringify(loadedDataByMission));
$scope.labelsf = [];
$scope.qsd = [];
$scope.dataf = [];
getIncidentArriveeByMonthFromTo.forEach(function(data) {
var monthNumber=$filter('date')(data.la_date, "MM");
$scope.labelsf.push($filter('monthName')(monthNumber));
$scope.dataf.push(data.number);
//$scope.qsd.push('ff','ff','ff');
//alert($scope.labelsf );
});
alert('aqsz'+$scope.dataf );
} else {
alert("failure");
}
// $scope.stopSpin('spinner-0');
};
function onError(response) {
console.log("-------getIncidentDepartByMonthFromTo FAILED-------");
//$scope.stopSpin('spinner-0');
console.log(response.data);
console.log("Inside getIncidentDepartByMonthFromTo error condition...");
};
//----MAKE AJAX REQUEST CALL to GET DATA----
ajaxServicess.getData(url,username,password, 'GET', '').then(onSuccess, onError);
};
this function return for exemple: $scope.dataf = ['69','50','96'];
my question is: is there a way to declare the second function in the first fuction and get a result like this:
this function return for exemple: $scope.dataf = [['45','48','255'],['69','50','96']];

I would use promises to wait for the second call to respond and update a variable in the function scope (sibling to the function). Something like this:
var aggregate = [];
charCtrl.loadDataFromToMonth()
.then(function(resp){
return new Promise(resolve, reject){
aggregate.push(resp.data); // push the response from the first call
charCtrl.loadDataFromToMonthArrivee()
.then(function(resp) {
aggregate.push(resp.data); // push the result from the second call
resolve(resp)
})
}
})
.then(function(resp){
console.log(aggregate); // should have both results
})
Or better yet, you can use Promise.all (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)

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);
});

Then is not a function error in angularjs

I have simple function which returns employee data. But getting then is not a function error how to retrieve response from function
function getdata(criteria) {
return angularService.GetData(criteria, $scope.year, $scope.selectedYearType.name);
}
Which is called in below function
$scope.GetEmployeeData = function (criteria) {
$scope.searchMethod = getdata;
$scope.searchMethod().then(function (response) {----------> Error here
var totalEmployeeAmount = 0;
for (var i = 0; i < response.data.results.length; i++) {
var summaryData = response.data.results[i];
totalEmployeeAmount += (summaryData.totalEmployeeAmount);
}
return response
}, function (response) {
// This is to see if has any error
//console.log(response);
});
}
My angular service
function getData(criteria, year, yearType) {
var url = apiService.ApiUrl + "/Employees/EmployeeHistory/GetData/" + year + "/" + yearType;
return apiService.DeferredPost(url, criteria);}
Deferred Post Method
function deferredPost(url, params) {
var deferred = $q.defer();
$http.post(url, params)
.then(function (data) {
deferred.resolve(data);
}, function (resp) {
deferred.reject(resp);
}).catch(function (data) {
deferred.reject(data);
});
return deferred.promise;
}
API
var api = {
DeferredPost: deferredPost
};
return api;
Should be calling .then on searchMethod instead of searchMethod() - assuming getdata returns a promise as you can't call .then on a function that doesn't return a promise. Also I'm guessing you should be passing in the criteria as a parameter to getdata:
$scope.GetEmployeeData = function (criteria) {
$scope.searchMethod = getdata;
$scope.searchMethod.then(function (response) {
var totalEmployeeAmount = 0;
for (var i = 0; i < response.data.results.length; i++) {
var summaryData = response.data.results[i];
totalEmployeeAmount += (summaryData.totalEmployeeAmount);
}
return response
}, function (response) {
// This is to see if has any error
//console.log(response);
});
}
As #William Hampshire said, you should be using $scope.searchMethod.then(function ... ) instead of $scope.searchMethod().then(function ... )
$scope.GetEmployeeData = function (criteria) {
$scope.searchMethod = getdata(criteria);
$scope.searchMethod.then(function (response) {
var totalEmployeeAmount = 0;
for (var i = 0; i < response.data.results.length; i++) {
var summaryData = response.data.results[i];
totalEmployeeAmount += (summaryData.totalEmployeeAmount);
}
return response
}, function (response) {
// This is to see if has any error
//console.log(response);
});
}
The reason why your code is still failing is that you have a typo in your service name.
function getdata(criteria) {
return angularService.GetData(criteria, $scope.year, $scope.selectedYearType.name);
}
It should be GetData instead of getData.
function GetData(criteria, year, yearType) {
var url = apiService.ApiUrl + "/Employees/EmployeeHistory/GetData/" + year + "/" + yearType;
return apiService.DeferredPost(url, criteria);}

Angular Promise - $q.all not returning result and calling Post method several times not working

Am trying to call a Post method and then depending on the result I am going to call same Post method multiple times and return the result, using $q.all.
My Post method is :
getData: function (params, callback) {
$http.post('service/myService', params)
.success(function (data) {
callback(null, data);
}).error(function (error) {
callback(error);
});
}
I am calling it in below function, this function is recursive so if it contains nextUrl I am doing same thing until there is no object for paging:
var result = [];
var promises = [];
var checkForPaging = function (nextUrl, service, $q) {
var deferred = $q.defer();
var criteria = {
url: url
}
var promise = service.getData(criteria, function (error, data) {
if (data.statusCode == 200) {
for (var i = 0; i < data.body.items.length; i++) {
result.push(data.body.items[i]);
}
if (data.body.paging != null && data.body.paging.next != null) {
checkForPaging(data.body.paging.next.url, service, $q);
} else{
deferred.resolve(result);
}
}
});
promises.push(promise);
$q.all(promises)
return deferred.promise;
}
Then am calling this function from below and want to get the result back once all calls are complete:
checkForPaging(data.body.paging.next.url, myService, $q).then(function (data) {
console.log(data)
});
The issue I am having is that it never hits the callback function above : console.log(data). But I can see it calling the Post method several times.
If I resolve it like below then I can see after first Post it is hitting the callback above:
$q.all(promises).then(function (results) {
deferred.resolve(result);
}, function (errors) {
deferred.reject(errors);
});
Am I doing it right? How can I get the result back and call the Post method several times?
Let me know if it is not clear or have any questions!
Try something like this with proper promise chaining:
var result = [];
var checkForPaging = function(nextUrl, service) {
var criteria = {
url: url
}
return service.getData(criteria, function(error, data) {
if (data.statusCode == 200) {
for (var i = 0; i < data.body.items.length; i++) {
result.push(data.body.items[i]);
}
if (data.body.paging != null && data.body.paging.next != null) {
return checkForPaging(data.body.paging.next.url, service);
} else {
return result;
}
}
});
}
checkForPaging(data.body.paging.next.url, myService).then(function(data) {
console.log(data)
});
And getData:
getData: function(params) {
return $http.post('service/myService', params)
.then(function(response) {
return response.data;
});
}
Here is solution: https://plnkr.co/edit/HqkFNo?p=preview I rewrited logic a bit.
You can catch the main idea.
UPDATE added promiseless solution
1) Your service should return only promise:
this.getData = function(url, params){
return $http.post(url, params); //You're just returning promise
}
2) You don't need $q.all, you can use single promise:
var result = [];
var deferred;
var checkForPaging = function (url) {
if(!deferred){
deferred = $q.defer();
}
//resolvind service promise
newService.getData(url).then(
//if ok - 200
function(response){
for (var i = 0; i < data.body.items.length; i++) {
result.push(data.body.items[i]);
}
if (data.body.paging != null && data.body.paging.next != null){
{
return checkForPaging(data.body.paging.next.url);
} else{
deferred.resolve(result);
}
},
//handle errors here
function(error) {
}
);
return deferred.promise;
}
3) You should call it like this:
checkForPaging('url').then(function(data){
//here will be resolved promise
console.log(data);
});

Nested $promise undefined error

I am getting the error Cannot read property of '$promise' of undefined.
Here is the code that is throwing it:
var myPromise = sharedDataService.getData($scope.entityId).$promise;
resolvePromise(myPromise, 'entityData');
the resolvePromise method:
function resolvePromise(promise, resultObject){
promise.then(function(response){
$scope[resultObject] = result;
});
promise['catch'](function(error){
//error callback
});
promise['finally'](function(){
//finally callback
});
sharedDataService looks like this:
var publicInterface = {
getData: getData
};
var storedData;
function getData(entityId) {
if(storedData.entityId === entityId){
return storedData;
}else{
var entityDataPromise = dataAccessService.getEntityData(entityId).$promise;
entityDataPromise.then(function (response) {
storedData = response;
return storedData ;
});
entityDataPromise['catch'](function(error) {
//throw error;
});
entityDataPromise['finally'](function(done) {
//do finally
});
}
}
return publicInterface;
finally, the dataAccessService:
var publicInterface = {
getEntityData: getEntityData
}
var entityData = $resource(apiUrl + 'Entity', {}, {
'getEntityData': {
method: 'GET',
url: apiUrl + 'Entity/getEntityDataById'
}
}
function getEntityData(entityId){
return entityData.getEntityData({entityId: entityId})
}
return publicInterface;
the original promise is throwing an error. When I put breakpoints various places, I can see my data is being returned sometimes. The functionality of sharedDataService is almost one of a chaching service.
Why is my original promise returning undefined?
Your getData() method doesn't have a return when if is false. So you would need to return entitiyDataPromise.
But, that would mean one condition returns a promise and the other returns an object
So both conditions need to return a promise and we can use $q for the first condition
function getData(entityId) {
if(storedData.entityId === entityId){
// return to getData()
return $q.resolve(storedData);
}else{
var entityDataPromise = dataAccessService.getEntityData(entityId).$promise;
// return to getData()
return entityDataPromise.then(function (response) {
storedData = response;
return storedData ;
});
entityDataPromise['catch'](function(error) {
//throw error;
});
entityDataPromise['finally'](function(done) {
//do finally
});
}
}
Be sure to inject $q in service.
In controller would be:
var myPromise = sharedDataService.getData($scope.entityId);
resolvePromise(myPromise, 'entityData');

GET call to REST API returns null

I am trying to make a GET call to test a REST API but it keeps returning null, is there anything I am doing wrong:
Making the call in controller.js
function ConsumerSearchCtrl($scope, BusinessCategoryService) {
console.log(BusinessCategoryService);
}
127.0.0.1:8000/api/category/ works perfectly fine
Code in services.js for API
/**
*
*/
function BusinessCategoryService(WenzeyAPI, $q) {
var scope = this;
scope.categories = categories;
function categories() {
var q = $q.defer();
WenzeyAPI.get('http://127.0.0.1:8000/api/category/').then(function success (res) {
q.resolve(res.data);
}, function failure (err) {
q.reject(err);
})
return q.promise;
}
}
/**
*
*/
function WenzeyAPI() {
var scope = this,
ip = "http://127.0.0.1:8000";
scope.get = get;
scope.post = post;
function get(url, data) {
data = data || {};
var req = {
method: 'GET',
url: url,
data: data
}
var q = $q.defer();
$http(req).then(function success(response) {
q.resolve(response);
}, function failure(err) {
q.reject(err);
});
return q.promise;
}
function post(url, data) {
data = data || {};
var req = {
method: 'POST',
url: url,
data: data
}
var q = $q.defer();
$http(req).then(function success(response) {
q.resolve(response);
}, function failure(err) {
q.reject(err);
});
return q.promise;
}
}
Removing WenzeyAPI and using $http resolved it.
function BusinessCategoryService($http) {
this.getAllData = function () {
return $http({
method: 'GET',
url: 'http://127.0.0.1:8000/api/category/',
});
}
}

Resources