ngTable with data from web api not working - angularjs

I'm using ngTable for AngularJS and geting the data from a web api. The problem start when I tried to use the filters in the table.
If I do it this way, the table is filled with the data, but the filters don't works:
$scope.clientesTable = new NgTableParams({
page: 1,
count: 10
}, {
getData: function (params) {
var clientes = clientesService.getAll(baseUrl);
clientes.then(function (data) {
$scope.clientesTableData = data.data;
}, function (error) {
console.log("Error: " + error);
});
}
});
In the documentation the code is something like this:
$scope.clientesTable = new NgTableParams({
page: 1,
count: 10
}, {
getData: function (params) {
var clientes = clientesService.getAll(baseUrl);
clientes.then(function (data) {
params.total(data.inlineCount);
return data.results;
}, function (error) {
console.log("Error: " + error);
});
}
});
Doing it this way, I don't see the data in the frontend. If a look for data in clientesTable:
EDIT:
Response from web api:

You have to provide return keyword before clientes.then() inside getData method.

If I look at this answer https://stackoverflow.com/a/29629034/3177115 I see that NgTableParams is used differently. You need to use it with a promise which returns the data back into the NgTableParams object.
$scope.tableParams = new ngTableParams({
page: 1, count: 5,
}, {
getData: function ($defer, params) {
$http.get(testUrl, { params: params })
.then(function(res) {
$defer.resolve(res.data.items);
}, function(reason) {
$defer.reject();
}
);
},
});
Please see the full example for details, I have simplified the example a bit for better understanding.
EDIT:
I think the API of ng-tables has changed - it does not expect a deferer any more.
Looking now at your first code example again (which you say it works) I see why the filter is not working: You do not pass the filter information back to your service.
The ng-table docs say: http://ng-table.com/#/filtering/demo-filtering-basic
Got a getData function? In this case you'll need to apply the values
from NgTableParams.filters() to the data you want to display in your
table. This is typically the case when the data is being fetched from
the server
I don't know your service, but can you add the filter params to the service call?
var clientes = clientesService.getAll(baseUrl, params._params)
Btw: the docs of ng-table are a nightmare - all samples inherit from each other and use directives and injects.

Related

How can I save JSON data from an API service to cache?

I call the API service from the backend side. I want to save the JSON return data to the cache. What should I do? Is my format wrong?
The snippet code here:
// var localData = [];
var service = {
search: function(requestId) {
return $http.get('/api/mace/getRequest', {
params: {
id: requestId
},
cache:true
});
},
return service
I can't see that there's something wrong with your code. You did correctly set the cache variable to true in the http-call as described in the documentation from AngularJS.
$http.get(url, {
cache: true
}
You should get your JSON by calling your service function and waiting for the promise:
yourService.search(yourRequestId).then(function(response) {
console.log('result', response.data);
});

Angular ng-table loading from server with pagination

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

request timeout in node application

The request I make to my node api takes more than 4 minutes to respond. While the time the response is received. The angular app does not accept the response. On firebug, the url turns red.
How can I overcome this.
api.route('/allsearch')
.post(function(req,res){
var filters=req.body.everything;
var filterid=req.body.filterId;
var searchid=req.body.searchid;
var zipgroup=req.body.zipgroup;
var myObject = new Array();
function getData(docs, filters, filterid, callback) {
function loop(i) {
searchingalgo(docs[i], filters, filterid, function(pers){
myObject[i] = pers;
if (i < docs.length) {
loop(i + 1);
} else {
callback();
}
});
};
loop(0);
};//closing get data()
Searchradius.findOne({"searchid" : searchid, user: req.decoded.id}).exec(function(err, docs) {
// Array to hold async tasks
var asyncTasks = [];
// Loop through some items
zipgroup.forEach(function(item){
// We don't actually execute the async action here
// We add a function containing it to an array of "tasks"
asyncTasks.push(function(callback){
// Call an async function, often a save() to DB
console.log(item);
searchingalgo(item, filters, filterid, function(pers){
myObject[item] = pers;
// Async call is done, alert via callback
callback();
});
});
});
Async.parallel(asyncTasks, function(){
//console.log(myObject);
Searchradius.update({ _id: searchid }, { $set: { ucounteds: myObject , uzips: zipgroup }}, function(err, result){
if(err) {
res.send(err);
return;
}
var fields = ['city', 'state', 'zip','distance', 'count'];
var myresults = [];
var tc=0;
var newMyobj= new Array();
co=0;
zipgroup.forEach(function(item){
tc+=myObject[item];
//myresults.push(jobj);
});
for(i=0;i<zipgroup.length;i++){
newMyobj[i]=myObject[zipgroup[i]];
}
console.log(tc);
Searchfilter.update({ _id: filterid }, { $set: { counted_results: tc }}, function(err, resultupdate){
//console.log(resultupdate);
//console.log(tc);
});
// console.log(myObject);
// console.log(newMyobj);
res.json({
success: true,
zips: zipgroup,
states: docs.states,
cities: docs.cities,
distances: docs.distances,
counted_results : newMyobj,
});
}); //update searchradius
}); //getdata function
}); //searchradius findone
});
As requested, this is my node API. the zipgroup is a array of zips like
[37663, 37664, 37669, 37671, 37660, 37669, 37667, 37668, 37666, 37665, 37662, 37661]
Just to be clear the collection Consumer1s has more than 2900009876 documents. It is indexed properly and the query is taking the least time possible. But I am still facing this problem.
Any suggestions would be helpful.
This is my post request from angular controller.
$http.post('/api/allsearch',
{
"everything":$scope.filterSearch ,
"searchid":$routeParams.id,
"filterId": $scope.filterId,
"zipgroup" : $scope.zipgroup
})
.success(function(data){
for(var i=0; i<data.zips.length;i++){
oneset={
"zip": data.zips[i],
"state": data.states[i],
"city": data.cities[i],
"distance": data.distances[i],
"count": data.counted_results[i]
};
$scope.totalCount+=data.counted_results[i];
$scope.results.push(oneset);
}
angular.forEach($scope.results, function (result) {
result.distance = parseFloat(result.distance);
});
$rootScope.processing=false;
$scope.filterlinkdisplay=true;
});
There are at least several options:
set AngularJS $http timeout for 10 mins or so, so that AngularJS request doesn't time out, waiting for 4 mins to get the data
polling: 1) AngularJS app does initial request 2) Node.js server issues a unique token to AngularJS app for this request and starts working on collecting data 3) AngularJS app waits for several mins and does a request with previously received token to get data 4) If result is ready, you're done. If not, wait again and do another request from AngularJS
use WebSocket. On client side it is supported by many browsers, on server side use ws. It's a bi-directional protocol, so server can notify clients when data is ready.

How to use Angular Query resource

I'm using MEAN.JS 0.4 and I need some help with Angular Resource.
My problem is this:
I want to make this API and be able to filter data server side, but I dont know how to use this Query method.
I want to do something like this:
Products.query({
stock: 0
}, function(result){
console.log(result)
});
This is my actual Angular service:
//Discounts service used for communicating with the discounts REST endpoints
angular.module('discounts').factory('Discounts', ['$resource',
function ($resource) {
return $resource('api/discounts/:discountId', {
discountId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]);
Discounts.query({stock: 0}).$promise
.then(function(data) {
products = data; })
or
products = Discount.query({stock: 0}, function() {
//do something whith products
});

AngularJS reload data after PUT request

Should be a fairly easy one here for anyone who knows Angular. I am trying to update the data that is displayed after I make a PUT request to update the object. Here is some code:
Post service (services/post.js)
'use strict';
angular.module('hackaboxApp')
.factory('Post', function($resource) {
return $resource('/api/posts/:id', {id : '#id'}, {
'update': { method: 'PUT' }
})
});
Server side controller function that gets executed when trying to update data (lib/controllers/api.js)
exports.editsave = function(req, res, next) {
var posty = req.body;
console.log(posty._id.toString() + " this is posty");
function callback (err, numAffected) {
console.log(err + " " + numAffected);
if(!err) {
res.send(200);
//res.redirect('/forum');
}
}
Post.update(posty, { id: posty._id.toString() }, callback);
};
This is the console output for the above code:
53c54a0d4960ddc11495d7d7 this is posty
null 0
So as you can see, it isn't affecting any of the MongoDB documents, but it also isn't producing errors.
This is what happens on the client (Angular) side when a post is updated:
$scope.saveedit = function() {
console.log($scope.post._id + " post id");
// Now call update passing in the ID first then the object you are updating
Post.update({ id:$scope.post._id }, $scope.post, function() {$location.path('/forum')});
};
After the redirect, $location.path('/forum'), none of the data is displayed as being updated...when I look in the database...nothing has changed either...it is like I am missing the step to save the changes...but I thought that update (a PUT request) would do that for me.
I use ng-init="loadposts()" when the /forum route is loaded:
$scope.loadposts = function() {
$http.get('/api/posts').success(function (data) {$scope.posts = data});
};
Shouldn't all the new data be loaded after this? Any help would be appreciated. Thanks!
Your server side output indicate that the update query doesn't match any document in the database.
I'm guessing that you are using Mongoose in NodeJS server side code to connect to mongodb.
If that the case, your update statement seems incorrect.
Instead of { id: .. } it should be { _id: .. }
Also the conditions object and updated object are swapped.
The statement should be like this:
Post.update({ _id: posty._id.toString() }, posty, callback);
If you are not using Mongoose, please eloborate more on which library you are using or better than that, show the code where the Post variable is defined in your server side code.
Ok I got it.
the problem is that you are not using the Angular resource api correct.
This code need to be changed:
$scope.saveedit = function() {
console.log($scope.post._id + " post id");
Post.update({ id:$scope.post._id }, $scope.post, function() {$location.path('/forum')});
};
Into:
// Update existing Post
$scope.saveedit = function() {
var editedpost = new Post($scope.post); //New post object
editedpost.$update(function() {
$location.path('/forum');
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
And as for the server code (taken from my own working module):
exports.update = function (req, res) {
var post == req.post;
post = _.extend(post, req.body);
post.save(function (err) {
if (err) {
return res.send(400, {
message: getErrorMessage(err)
});
} else {
res.jsonp(post);
}
});
};

Resources