deferred.resolve() is not iterating the last element inside a forloop - angularjs

in the model.findone i'm getting a array which consists of 3 elements. In the else part i'm looping through each item & fetching offering head of that particular item.
But i'm able to get only 2 offering heads.Not able to fetch the last offering head.
Is there any problem with my code??
function getOfferingsHeads(id) {
var deferred = Q.defer();
var offeringHeads = [];
model
.findOne({ _id: id })
.exec(function (err, item) {
if(err) {
console.log(err);
deferred.reject(err);
}
else {
// deferred.resolve(item.offerings);
// var offeringsList = [];
// offeringsList = item.offerings;
for (var i = 0; i < item.offerings.length; i++) {
executivesModel
.findOne({offName: item.offerings[i] })
.exec(function(err1, item1) {
if(err1){
console.log(err1);
deferred.reject(err1);
}
else{
offeringHeads.push(item1.offHead);
deferred.resolve(offeringHeads);
}
});
}
}
});
return deferred.promise;
}

You can't resolve a deferred more than once, and in general you shouldn't be using deferreds at all. Since mongoose has a promise-friendly API, you should just use that. It will make your code much much cleaner:
function getOfferingHead(offName) {
return executivesModel
.findOne({offName: offName })
.exec()
.then(function (item) {
return item.offHead;
});
}
function getOfferingsHeads(id) {
return model
.findOne({ _id: id })
.exec()
.then(function (item) {
return Q.all(item.offerings.map(getOfferingHead));
});
}
To use the function:
getOfferingsHeads('myId').then(function (heads) {
console.log(heads);
});

Not sure this is what you intended but you are resolving the same promise more than once.
The latest version of mongoose lets you set the Promise library to use.
Here's a correction to what I believe you meant to do:
//Somewhere near mongoose definition
mongoose.Promise = require('q').Promise;
function getOfferingsHeads(id) {
var offeringHeads = [];
return model
.findOne({ _id: id })
.then(function (item) {
if(!item) {
//Handle no results
return Q.reject()
}
else {
return Q.all(item.offerings.map(function(offering){
executivesModel
.findOne({offName: offering.name})
}));
}
});
}
//Now you can use
getOfferingsHeads('someId').then(function (offerings) {
...
});

Related

How to make a double GET on angular 1.x

I want to do a doble Get using the return of the first one as input for the second one, is there a way to do this?
ExpedienteService.getExpediente(id).then(function(data) {
vm.expediente = data;
}).then(AutoService.getAuto1a5(vm.expediente).then(function(data) {
vm.autos = data;
})
);
thats what i got so far.
ExpedienteService.getExpediente(id).then(function(data) {
vm.expediente = data;
return AutoService.getAuto1a5(vm.expediente);
}).then(function(data) {
vm.autos = data;
});
You were close.
Say if you didn't want to save the first data into vm.experiente you could do.
ExpedienteService.getExpediente(id)
.then(AutoService.getAuto1a5)
.then(function(data) {
vm.autos = data;
})
function yourNewFunction() {
var deferred = $q.defer();
ExpedienteService.getExpediente(id).then(
function getExpSuccess(resp) {
var vm = {
expediente = resp.data;
};
AutoService.getAuto1a5(vm.expeidente).then(
function getAutoSuccess(resp) {
vm.autos = resp.data;
deferred.resolve(vm);
},
deferred.reject
}
},
deferred.reject
);
return deferred.promise;
}

Delay loading data in Angular JS

I have code like this
(function (app) {
app.controller('productListController', productListController)
productListController.$inject = ['$scope', 'apiService', 'notificationService', '$ngBootbox', '$filter'];
function productListController($scope, apiService, notificationService, $ngBootbox, $filter) {
$scope.products = [];
$scope.page = 0;
$scope.pagesCount = 0;
$scope.getProducts = getProducts;
$scope.keyword = '';
$scope.search = search;
$scope.deleteProduct = deleteProduct;
$scope.selectAll = selectAll;
$scope.deleteMultiple = deleteMultiple;
function deleteMultiple() {
var listId = [];
$.each($scope.selected, function (i, item) {
listId.push(item.ID);
});
var config = {
params: {
checkedProducts: JSON.stringify(listId)
}
}
apiService.del('/api/product/deletemulti', config, function (result) {
notificationService.displaySuccess('Deleted successfully ' + result.data + 'record(s).');
search();
}, function (error) {
notificationService.displayError('Can not delete product.');
});
}
$scope.isAll = false;
function selectAll() {
if ($scope.isAll === false) {
angular.forEach($scope.products, function (item) {
item.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.products, function (item) {
item.checked = false;
});
$scope.isAll = false;
}
}
$scope.$watch("products", function (n, o) {
var checked = $filter("filter")(n, { checked: true });
if (checked.length) {
$scope.selected = checked;
$('#btnDelete').removeAttr('disabled');
} else {
$('#btnDelete').attr('disabled', 'disabled');
}
}, true);
function deleteProduct(id) {
$ngBootbox.confirm('Are you sure to detele?').then(function () {
var config = {
params: {
id: id
}
}
apiService.del('/api/product/delete', config, function () {
notificationService.displaySuccess('The product hase been deleted successfully!');
search();
}, function () {
notificationService.displayError('Can not delete product');
})
});
}
function search() {
getProducts();
}
function getProducts(page) {
page = page || 0;
var config = {
params: {
keyword: $scope.keyword,
page: page,
pageSize: 20
}
}
apiService.get('/api/product/getall', config, function (result) {
if (result.data.TotalCount == 0) {
notificationService.displayWarning('Can not find any record.');
}
$scope.products = result.data.Items;
$scope.page = result.data.Page;
$scope.pagesCount = result.data.TotalPages;
$scope.totalCount = result.data.TotalCount;
}, function () {
console.log('Load product failed.');
});
}
$scope.getProducts();
}
})(angular.module('THTCMS.products'));
So my problem is when i loading data the application take me some time to load data.
I need load data as soon as
Is the any solution for this?
Since you are loading data via api call, there will be a delay. To handle this delay, you should display a loading screen. Once the data is loaded, the loading screen gets hidden and your main screen is visible. You can achieve this using $http interceptors.
See : Showing Spinner GIF during $http request in angular
The api-call is almost certainly causing the delay. Data may be received slowly via the api-call so you could display any sort of loading text/image to notify the use that the data is being loaded.
If u want the data ready at the time when controller inits, u can add a resolve param and pass the api call as a $promise in the route configuration for this route.

Empty var in second service function

I have a service:
.service('VacanciesService', function($http) {
var vacancies = [];
var usedVacancies = [];
return {
getVacanciesForUniversity: function(university_id) {
return $http.get("http://jobs.app/api/vacancies/" + university_id).then(function(response){
vacancies = response.data.vcancies;
return vacancies;
}, function(error){
return error;
});
},
getRandomVacancy: function() {
console.log(vacancies);
}
}
})
This is the calling controller
.controller('jobsCtrl', function($ionicLoading, locker, UniversitiesService, VacanciesService) {
var vm = this;
user = locker.get('userDetails');
UniversitiesService.getUniversity(user.university.id).then(function(university) {
vm.university = university.university;
});
VacanciesService.getVacanciesForUniversity(user.university.id).then(function(vacancies) {
vm.vacancies = vacancies;
}, function error(error) {
});
vm.addCard = function(name) {
newVacancy = VacanciesService.getRandomVacancy();
};
vm.addCard();
})
And I can't figure out why the vacancies variable in in the console.log is empty in the second function? I assumed as it was set in the initial function (called prior) that it should be populated?
TIA!
if you call getVacanciesForUniversity getRandomVacancy like below, you will get empty array
VacanciesService.getVacanciesForUniversity(uniId)
VacanciesService.getRandomVacancy() //you will get empty
you must getRandomVacancy inside getVacanciesForUniversity returned promise
VacanciesService.getVacanciesForUniversity(uniId).then(function(){
VacanciesService.getRandomVacancy()
})
alo you misstype response.data.vcancies; instead response.data.vacancies;
The answer is READ YOUR CODE PROPERLY.
There was a glaringly obvious typo in my code that I missed from staring at it too long.
Big thanks to Daniel Dawes and aseferov for attempting to help!
In your service :
getVacanciesForUniversity: function(university_id) {
return $http.get("http://jobs.app/api/vacancies/" + university_id);
}
In your controller :
$scope.getVacancies = function () {
your_service.getVacanciesForUniversity().then(
function(response) {
if (response.status = 200) {
$scope.vacancies = response.data.vacancies;
}, function errorCallback (response) {
...
}
);
};
$scope.getVacancies(); // you call one time your function here
$scope.getRandomVacancy : function() {
console.log($scope.vacancies);
};

Controller behavior(different data from Factory) which depends on view

This is the Factory.
angular
.module('WordsFactory', [])
.factory('WordsFactory', WordsFactory);
function WordsFactory($http) {
exports = {
basics1Data: null
};
exports.getWordsBasics1 = function () {
return $http.get('data/basics1.json')
.success(function (data) {
exports.basics1Data = data;
})
.error(function (data) {
console.log('There was an error!', data);
});
};
exports.getWordsBasics2 = function () {
return $http.get('data/basics2.json')
.success(function (data) {
exports.basics1Data = data;
})
.error(function (data) {
console.log('There was an error!', data);
});
};
return exports;
}
Controller:
angular
.module('app.words', ['WordsFactory'])
.controller('WordsController', WordsController);
function WordsController(WordsFactory) {
var vm = this;
WordsFactory.getWordsBasics1()
.then(core);
function core(res){
//json data binds to variable
vm.basics1Data = res.data;
vm.points = 0;
getRandom();
//check if words are correct
vm.wordCheck = function () {
if(vm.wordInput === vm.test) {
alert('good');
getRandom();
vm.points++;
} else {
alert('bad');
getRandom();
}
};
function getRandom() {
var random = Math.floor(Math.random() * 6);
vm.test = vm.basics1Data[random];
}
}
}
In this project I will have multiple views. Every view will have the same structure and gonna do the same thing.
Views are something like categories.
-cat1
-cat2
-cat3
-and so on...
Only thing that would be different is json file.
for ex.
cat1 will have cat1.json
cat2 cat2.json etc.
Controller gonna do the same operations in every view, only on different data. How can I achieve that without copy and paste methods in controller f.ex.
WordsFactory.getWordsBasics1...
WordsFactory.getWordsBasics2...
The code that I have works, but I want to avoid copy-paste things.
Thank you in advance for any help.

Getting the phoneNumber using $cordovaContacts

I'm trying to get all the contacts in the phone using ng-cordova, I success to do that like the following, I create a service in AngularJS:
.factory("ContactManager", function($cordovaContacts) {
return {
getContacts: function() {
var options = {};
options.filter = "";
options.multiple = true;
//get the phone contacts
return $cordovaContacts.find(options);
}
}
})
Also the method find in the ng-cordova is't like the following:
find: function (options) {
var q = $q.defer();
var fields = options.fields || ['id', 'displayName'];
delete options.fields;
navigator.contacts.find(fields, function (results) {
q.resolve(results);
},
function (err) {
q.reject(err);
},
options);
return q.promise;
}
And did the following inside the controller:
ContactManager.getContacts().then(function(result){
$scope.users= result;
}, function(error){
console.log(error);
});
I noticed that in the $scope.users I find the formatted, middleName ..., but I can't find the phoneNumber, how can I get also the phoneNumbers?
If you log the contacts you should see an object with a phoneNumbers array in it.
ContactManager.getContacts().then(function(result){
$scope.users= result;
console.log(result);
...
If you don't it's something else.
I also made a somewhat close mock json of what the return looks like.

Resources