Angular ng-table loading from server with pagination - angularjs

I am trying to figure out how to populate an ng-table and apply the total value for the params. It appears there are examples that are showing almost what I'm doing - but not exactly and the total never gets set.
$scope.tableParams = new NgTableParams({page: 1, count: 25},
{
counts: [],
getData: function(params)
if (CompaniesView.ViewInitialized)
return CompaniesView.RetrieveCompanies($scope, $http, function ()
{
params.total($scope.RequestFilter.TotalCompanies);
return $scope.TableParams.data;
});
}
});
My RetrieveCompanies function retrieves he data - and will call a callback function on completion. I was under the impression at this point I could set the params.total, but is not working. I see that examples are doing similar, except they are performing a jQuery API operation directly. I am not sure why this does not work. I would have thought anytime setting the total would cause the table pagination controls to update - but it appears it has to be done within the detData call. But if you are making an async call how can we have the total set in the call since it won't have data until the async completes - which means the
getData call has already finished.
Probably missing some concept here -- but I am not an expert when it comes to jQuery or angular.
Peter
Update:
RetrieveCompanies function
RetrieveCompanies: function (scope, http,callback)
{
scope.IsLoading = true;
var Data =
{
AuthoirzationType: TokenRetrieval.SessionAuth,
SessionId: activeSession
};
var tokenRequest =
{
params: Data
};
performVeilabilityTokenRetrieval(http, tokenRequest,
function (response)
{
if (true)
{
if (!response.HasError)
{
scope.RequestFilter.State = scope.selectedState.Value
scope.RequestFilter.regionsearch = scope.selectedRegion.id;
scope.RequestFilter.checkadminStaff = scope.selectedAdmin.value;
//tableParams
scope.RequestFilter.Page = scope.tableParams.page();
scope.RequestFilter.PageCount = scope.tableParams.count();
var config =
{
headers:
{
Authorization: 'Bearer ' + response.RequestToken
},
params: scope.RequestFilter
}
http.get(CompaniesView.Companies_api_urls.loadCompaniesRequest, config)
.then(
function (response)
{
scope.RequestFilter.TotalCompanies = response.data.companieslistTotal;
scope.TableParams.data = response.data.companies;
if (callback != null) callback();
},
function (data, status, headers, config) //error
{
scope.IsLoading = false;
}
);
}
else
{
scope.request.requestToken = null;
//CreateExpenseView.PrepareRESTResults(data.RestResults);
}
}
else
{
scope.request.requestToken = null;
scope.request.error = data.replace(/\"/g, "");
}
});
}

Ok; finally found what was wrong. The ng-table getData operation requires a promise to be returned. My function was not configured as a deferred promise and once I realized this I put in place the required modification for my data retrieval to return a promise. One big point -- when I wrapped my call with a when - I completed with a done - and getData is operating off a then (from the promise). Once those changes were in place the pagination (total) operation worked.
Peter

Related

Angular Promise Conditional

My Angular v1.x directive calls a function when a button is clicked and depending on the input I set some variables:
$scope.offerRespond = function() {
if (offer.i.offerResponse == 1) {
// set some variables
}
else if (offer.i.offerResponse == 0) {
$http({method: 'GET', url: frontbaseurl+'/offer_types/' + id + '.json'})
.then(function successCallback(response) {
$scope.reason = response.data.data.name;
}, function errorCallback() {
$scope.reason = "Unknown";
}
);
$http.post(frontbaseurl+'/purchases.json', JSON.stringify(dataObj))
.then(function(response){
// continue....
}
}
As can be seen, I make a GET request if the offerResponse == 0. This seems risky because the code continues to execute without before a response from the request is received. I know the approach is to use a 'promise' but how does that apply in this case if the GET request may not be made?
The problem as I see it is if I add a promise and the offerResponse == 1 the promise can't be fulfilled since the GET request would not have been made.
Any suggestions please?
I've had to do something similar in our angular 1.x app, using Typescript, like this:
public myFunc = async (id): Promise<void> => {
return new Promise<void>(async (resolve, reject) => {
if (this.offer.i.offerResponse === 1) {
// set some variables
resolve();
}
else if (this.offer.i.offerResponse === 0) {
try {
const response = await services.getOfferTypes(id);
this.reason = response.data.data.name;
resolve();
} catch (errorResponse) {
this.reason = "Unknown";
reject();
}
}
});
}
Notice I "encapsulated" your http request in a service function. I like separating api calls into their own service, to keep things clean and easy to read. This code is untested, but if I remember correctly it should work something like this.

deferred promise not working

I am using promise in angular for my web app like this-
var deferred = $q.defer();
On Success -
deferred.resolve(profile); // profile = JSON object
On Failure -
deferred.reject(1); // 1 or no value returned
At end of function -
return deferred.promise;
Then I am handing for this returned Promise Object to call another method.But it doesn't call. While if i use Callback(error,success) it works fine.Can somebody suggest what is wrong with my promise.
Code Snippet-
function open() { // for initializing DB,getting called from service
var deferred = $q.defer();
var options = {
Encryption: {
encryptKey: false, // optional encrypt primary key
secrets: [{
name: 'dddd',
key: 'xxxxxxxxxx'
}]
}
};
var schema = {
stores:[{
name:'profile',
encrypted: true
}]
};
var db = new ydn.db.Storage('nowconferdb', schema, options);
db.onReady(function() {
console.log('DB is initialized'); // getting this
profilestorage.setDB(db); // getting called and setting DB in profilestorage service
deferred.resolve(true);
});
db.addEventListener('fail', function (event) {
var err = event.getError();
if (err.name == 'versionchange') {
console.log('The application is updated, please refresh to upgrade.');
profilestorage.setup(db);
} else {
console.log('connection failed with ' + err.name + ' by ' + err.message);
db = null; // no operation can be placed to the database instance
}
deferred.reject(false);
});
return deferred.promise;
}
This is my calling method -
storageservice.open().then(function() {
console.log('post initializing storageservice'); // not getting it.
});
Thanks a lot for your sincere efforts.
What you should do is to call your function inside the success callback of the promise. Assumming you assign your promise to deferred variable:
deferred.then(
function (data) {
// Here you call your other function/method
// It will be called when 'deferred' promise is resolved
anotherFunction();
},
function (error) {
// Handle the error
}
);
I hope this helps, even though the information you give is not enough.

Ionic Framework Using Phonegap Facebook Connect Plugin API cant make pagination of friends work

My ionic view uses infinite scroll for friends view and here is the controller:
$scope.friends = [];
$scope.after = "";
var getFriends = function(after)
{
var friends = $q.defer();
UserService.getUser().then(function (d) {
var url = '/me?fields=taggable_friends&access_token='+ d.authResponse.accessToken;
if (after != "")
{
url += "&limit=25&after="+after;
}
facebookConnectPlugin.api(url, null,
function (response) {
console.log(response);
friends.resolve(response);
},
function (response) {
console.log(response);
friends.reject(response);
}
);
});
return friends.promise;
};
$scope.loadMoreData = function()
{
getFriends($scope.after).then(function(d)
{
$scope.friends = $scope.friends.concat(d.taggable_friends.data);
$scope.after = d.taggable_friends.paging.cursors.after;
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
The first call is executed to url:
"/me?fields=taggable_friends&access_token=myAccessToken" and I receive an object as follows:
object
{
id: "string"
taggable_friends
{
data
{
[n]objects
}
paging
{
cursors
{
after: "string"
before: "string"
}
next: "string"
}
}
}
The second call url is:
/me?fields=taggable_friends&access_token=myAccessToken&after=QWFKVko1NlJmWUREajBTeERZAbmFJUzlLUWp5ZA3o5cDA5SWVHc1BKblJ6ODMweDd4TzdxMlJyOTdKNDlUb0NHQWl1M3FJbXdjbkpWc2NwSlNiS25peV8zYV9vdTdGbXFPMG5YNnpDSW1jWkVNX0EZD
In both cases I get the same object. With exactly the same Data. When I use browser for the 2 URLs, i get different (correct) data.
I even tried to request /me?fields=taggable_friends&access_token=myAccessToken&after=QWFKVko1NlJmWUREajBTeERZAbmFJUzlLUWp5ZA3o5cDA5SWVHc1BKblJ6ODMweDd4TzdxMlJyOTdKNDlUb0NHQWl1M3FJbXdjbkpWc2NwSlNiS25peV8zYV9vdTdGbXFPMG5YNnpDSW1jWkVNX0EZD in first call, but still I get the same data.
Finally i found the solution!
I don't know what the reason is, but API call like "/me?fields=taggable_friends&access_token=..." don't work when "after" parameter is added.
It should be used this way: "/me/taggable_friends?access_token=...", this way it works.

Chaining Angular Promises

I am having some trouble chaining promises in Angular. What I want to do is fetch my project object from the API, then check if the project owner has any containers, if they do, trigger the another GET to retrieve the container. In the end the container assigned to scope should either be null or the object retrieved from the API.
Right now, this example below resolves immediately to the second then function, and I get the error, TypeError: Cannot read property 'owner' of undefined. What am I doing wrong?
$http.get('/api/projects/' + id).then(function (data) {
$scope.project = data.project;
return data.project;
}).then(function (project) {
var containers = project.owner.containers;
if (containers.length) {
return $http.get('/api/containers/' + containers[0]);
} else {
return null
}
}).then(function (container) {
$scope.container = container;
});
Ah, turns out the data from passed into then is inside a field, so I needed to do
$scope.project = data.data.project;
return data.data.project;
Your example code works, but what if the $http call fails because of a 404? Or you want to later want to add some extra business logic?
In general you want to handle 'negative' cases using a rejecting promise, to have more control over the chaining flow.
$http.get('/api/projects/' + id).then(function (data) {
$scope.project = data.data.project;
return data.data.project;
}).then(function (project) {
var containers = project.owner.containers;
if (containers.length) {
return $q.reject('containers empty');
}
return $http.get('/api/containers/' + containers[0]);
}).then(function (container) {
$scope.container = container;
}).except(function (response) {
console.log(response); // 'containers empty' or $http response object
$scope.container = null;
});

Is there a way I can pass in arguments to $http as part of an object?

I am using the following call:
$scope.retrieve = function () {
$resource('/api/Test/Retrieve')
.query({
subjectId: $scope.config.subjectId,
examId: $scope.config.examId,
userId: $scope.config.createdById
},
function (result) {
$scope.grid.data = angular.copy(result);
},
function () {
$scope.grid.data = null;
});
};
Is there a way that I could pass in the arguments through an object like this and use an $http call instead of a $resource. Also how could I move the success and error code blocks to there own functions?
Code below should work for posting with data.
$http.post("/api/Test/Retrieve", {
subjectId:$scope.config.subjectId,
examId:$scope.config.examId,
userId:$scope.config.createdById
}).success(
function(res){
//Some success handler here
}).error(
function(res){
//Some error handler here
});
There are lots of details you may want to include, if you need a GET with parameters check out the config parameter and it's properties:
http://docs.angularjs.org/api/ng/service/$http
//Same sample with handler functions moved out for ease of reading etc.
var successFunction = function(res){
}
var errorFunction = function(res) {
}
var params = {
subjectId:$scope.config.subjectId,
examId:$scope.config.examId,
userId:$scope.config.createdById
};
$http.post("/api/Test/Retrieve", params).
success(successFunction).
error(errorFunction);

Resources