return data after a service call - angularjs

I have a function which makes a service call. I have the code like below. But from success function i am unable to return the data back to calling function. How do i do this?
$scope.getData = function()
{
var successFunc = function(serverResponse)
{
if(serverResponse.header.status === "success" )
{
return serverResponse.data;
}
else
{
errorFunc("Error occured:");
}
}
var errorFunc = function(jsonResponse)
{
console.log( "Error occured:" + JSON.stringify(jsonResponse));
};
utils.svcall('abc/new', successFunc, errorFunc);
};
var data = $scope.getData();

Related

AngularJS .then on a promise -> cannot read property then of null / undefined

I have a question about the directives and the .then method.
Here is my controller code (I use it to pass variables to my directive) :
angular
.module('thermofluor')
.controller('ExperimentsController', ExperimentsController)
ExperimentsController.$inject = ['$state', '$stateParams', 'PlatesService', '$timeout', '$q', '$scope'];
function ExperimentsController($state, $stateParams, PlatesService, $timeout, $q, $scope) {
var exp = this;
//console.log($stateParams);
exp.barcode = $stateParams.barcode;
exp.plate = $stateParams.plate;
exp.current_user = "";
exp.users = [];
exp.curves = [];
exp.summary = [];
exp.selected_wells = [];
// liste experiments
console.log($stateParams.id);
getPlateById($stateParams.id);
function getUsers()
{
$timeout(function() {
exp.users = PlatesService.customShow(exp.plate.id, "users")
.then(getUsers)
.catch(getUsersFailed);
function getUsers ( data ) {
exp.users = data[0];
return exp.users;
}
function getUsersFailed ( e ) {
var newMessage = 'Failed To Retrieve the users';
if (e.data && e.data.description) {
newMessage = newMessage + '\n' + e.data.description;
}
console.log( e );
e.data = newMessage;
return $q.reject(e);
}
});
}
function getPlateById(id)
{
$timeout(function() {
exp.plate = PlatesService.show(id)
.then(getPlate)
.catch(getPlateFailed);
function getPlate ( data ) {
exp.plate = data;
exp.curves[exp.plate.experiments[0].well] = [exp.plate.experiments[0].points, exp.plate.experiments[0].tm];
getUsers();
return exp.plate;
}
function getPlateFailed ( e ) {
var newMessage = 'Failed To Retrieve the plate';
if (e.data && e.data.description) {
newMessage = newMessage + '\n' + e.data.description;
}
console.log( e );
e.data = newMessage;
return $q.reject(e);
}
});
}
}
1 - I have a simple directive :
angular
.module('thermofluor')
.directive('legend', legend)
legend.$inject = ['$timeout', '$q'];
function legend($timeout, $q) {
var directive = {
link: link,
restrict: 'E',
templateUrl: '/crims/thermofluor/experiments/legend.html',
scope: {
selected_wells: '=',
current_user: '=',
plate: '='
}
};
return directive;
function link(scope, element) {
console.log("TESTT");
console.log(scope);
scope.plate.then(function (res) {
console.log(scope.selected_wells);
});
}
}
What I don't understand is why the selected_wells and current_user are empty and the plate is not empty. And also why sometimes I have one of these two errors:
TypeError: Cannot read property 'then' of null
TypeError: Cannot read property 'then' of undefined
I thinks it's because the plate is not already loaded (it's loaded by an ajax call) but it's not the utility of the .then to launch the function after the object load ?
Edit:
Here is the PlateService (I use restangular) :
angular.module('thermofluor')
.factory( 'PlatesService', PlatesService);
PlatesService.$inject = ['Restangular', 'RepositoryService', '$cacheFactory', 'tmConfig', 'tmCache'];
function PlatesService( Restangular, RepositoryService, $cacheFactory, tmConfig, tmCache )
{
RepositoryService.extend( PlatesService )
return new PlatesService();
function PlatesService()
{
var service = this;
var cache = tmCache.plates();
//Restangular.setDefaultRequestParams({api_token: ChiefService.getCurrentToken()});
RepositoryService.call(service, Restangular.withConfig( config ), 'plates', cache );
return service;
function config( RestangularConfigurer )
{
Restangular.setDefaultHttpFields({cache: cache});
return RestangularConfigurer.setBaseUrl(tmConfig.api);
}
}
}
And this plateservice use this RepositoryService
function RepositoryService( $cacheFactory)
{
RepositoryService.prototype = {
all:all,
filterAll:filterAll,
show:show,
customShow:customShow,
store:store,
update:update,
destroy:destroy,
restore:restore,
};
RepositoryService.extend = function (repository) {
repository.prototype = Object.create(RepositoryService.prototype);
repository.prototype.constructor = repository;
};
return RepositoryService;
function RepositoryService(restangular, route, cache)
{
console.log( cache );
this.restangular = restangular;
this.route = route;
this.cache = cache;
}
function all()
{
return this.restangular.all(this.route).getList();
}
function filterAll( filters )
{
return this.restangular.all(this.route).customGETLIST('', filters );
}
function show(uuid)
{
return this.restangular.one(this.route, uuid ).get();
}
function customShow(uuid, extend)
{
return this.restangular.one(this.route, uuid).customGET( extend );
}
function store( resource )
{
clear( this.cache );
return this.restangular.all(this.route).post( resource );
}
function update( resource )
{
clear( this.cache );
return this.restangular.one(this.route, resource.uuid).customPUT( resource );
}
function destroy( resource )
{
clear( this.cache );
return this.restangular.one(this.route, resource.uuid).remove();
}
function restore( resource )
{
clear( this.cache );
return this.restangular.all(this.route + '/' + resource.uuid + '/restore' ).post();
}
function clear( cache )
{
if(_.isUndefined( cache )) {
return;
}
cache.removeAll();
}
}

Return value from Angular Service

Hi I do not understand why always I get empty array from this service when is invoked by my controller
angular
.module('dimecuba.services', [])
.factory('Contacts', function($cordovaContacts, $ionicPlatform) {
var contactsFound = [];
var contacts = {
all:function(){
var options = {};
options.multiple = true;
options.filter = "";
//options.fields = ['displayName'];
options.hasPhoneNumber = true;
$ionicPlatform.ready(function(){
$cordovaContacts.find(options).then(
function(allContacts){
angular.forEach(allContacts, function(contact, key) {
contactsFound.push(contact);
});
console.log("Contacts Found:" + JSON.stringify(contactsFound));
return contactsFound;
},
function(contactError){
console.log('Error');
}
);
});
}
}; //end contacts
console.log("Contacts:"+JSON.stringify(contacts));
return contacts;
});
Use return to chain promises. A return statement needs to be included at each level of nesting.
app.factory('Contacts', function($cordovaContacts, $ionicPlatform) {
var contacts = {
all:function(){
var options = {};
options.multiple = true;
options.filter = "";
options.hasPhoneNumber = true;
//return promise
return $ionicPlatform.ready().then(function() {
//return promise to chain
return $cordovaContacts.find(options)
}).then(function(allContacts){
var contactsFound = [];
angular.forEach(allContacts, function(contact, key) {
contactsFound.push(contact);
});
//return to chain data
return contactsFound;
}).catch(function(contactError){
console.log('Error');
//throw to chain error
throw contactError;
});
}
}; //end contacts
return contacts;
});
In the controller, use the promise returned.
app.controller("myCtrl", function($scope,Contacts) {
var contactsPromise = Contacts.all();
contactsPromise.then( function(contactsFound) {
$scope.contactsFound = contactsFound;
});
});

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

Angularjs/Ionic DB result with promise

I have a simple query that I am struggling with:
.factory('Config', function($http, DB) {
var self = this;
self.setValue = function(key,value) {
console.log('setValue(value)', value);
return DB.query("UPDATE config SET value = '"+value+"' WHERE key = '"+key+"'")
.then(function(result){
return DB.fetchAll(result);
});
}
self.getValue = function(key) {
return DB.query("SELECT value FROM config WHERE key = '"+key+"'")
.then(function(result){
return DB.fetchOne(result);
});
};
return self;
})
with the following code in controller.js under the heading:
.factory('DB', function($q, DB_CONFIG) {
var self = this;
self.db = null;
(I took the init part of the function away for the sake of simplicity. Also DB is working well when inserting, getting and updating data.)
self.fetchOne = function(result) {
var output = null;
output = angular.copy(result.rows.item(0));
return output;
};
self.query = function (sql, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
var deferred = $q.defer();
self.db.transaction(function (transaction) {
transaction.executeSql(sql, bindings, function (transaction, result) {
deferred.resolve(result);
}, function (transaction, error) {
deferred.reject(error);
});
});
return deferred.promise;
};
self.fetchAll = function (result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
};
Called like so:
$scope.config.recordar = Config.getValue("recordar");
Doing a console.log returns:
I am struggling to access the value: "true" which is highlighted in BLUE in the above image.
Any leads?
$scope.config.recordar = Config.getValue("recordar");
Does not work (ala JS). It has to be called like so:
Config.getValue("recordar").then(function(data) {
$scope.config.recordar
});
I assume that you shall change your function declaration from :
self.setValue = function(key,value) {
console.log('setValue(value)', value);
return DB.query("UPDATE config SET value = '"+value+"' WHERE key = '"+key+"'")
.then(function(result){
return DB.fetchAll(result);
});
}
to
self.setValue = function(key,value) {
console.log('setValue(value)', value);
DB.query("UPDATE config SET value = '"+value+"' WHERE key = '"+key+"'")
.then(function(result){
return DB.fetchAll(result);
});
}
You will return the result of your promise, not your promise
I have changed "return DB..." to "DB..."

Resources