Angular UI Client Side Pagination - node.js

I would like to enable pagination and I'm torn between client side and server side pagination. In the long term (more data) it is probably better to do server side pagination, but I haven't found a good tutorial on it.
I use Angular/Express/Mongo. I have the Boostrap UI in use, and would like to use their pagination directive for pagination. I have read some articels on how to kind of do it, but they are outdated and I cannot get it to work. http://fdietz.github.io/recipes-with-angular-js/common-user-interface-patterns/paginating-through-client-side-data.html
Could anybody help me get that example to work with Bootstrap UI for Angular?

If you have a set number of items per page, you could do it this way :
Define an angular service to query the data on your server.
.factory('YourPaginationService', ['$resource',
function($resource) {
return $resource('baseUrl/page/:pageNo', {
pageNo: '#pageNo'
});
}
]);
Call it via the angular controller. Don't forget to inject your service, either globally or in the controller.
$scope.paginationController = function($scope, YourPaginationService) {
$scope.currentPage = 1;
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
YourPaginationService.query({
pageNo: '$scope.currentPage'
});
};
};
On express 4 (if you have it), set up your route.
app.route('/articles/page/:pageNo')
.get(data.listWithPagination) //random function name
Then you need to wire that function with the desired Mongo request in your Node controller. If you have Mongoose, it works like this :
exports.listWithPagination = function(req, res) {
var pageLimit = x; //Your hardcoded page limit
var skipValue = req.params.pageNo*pageLimit;
YourModel.find() //Your Mongoose model here, if you use Mongoose.
.skip(skipValue)
.limit(pageLimit)
.exec(function(err, data) {
if (err) {
return res.send(400, {
message: getErrorMessage(err)
});
} else {
res.jsonp(data);
}
});
};
That's how I would do it on a typical MEAN stack. If you're working with different libraries/technologies, you might need to adapt a few things.

Related

why am I getting favicon.ico when i am using findOne method for express params routes?

when i am using list.save() method a object other than customList name which is favicon.ico is also
saving as record in following cod, Why am i gatting favicon.ico as object.
app.get('/:listRoute',function (req,res) {
const customList=(req.params.listRoute);
List.findOne({name:customList }, function (err,result) {
if (!err) {
if (!result) {
const list=new List({
name: customList,
items: defaultItems
})
list.save();
} else {
console.log(result);
res.render('list', {
listTitle: result.name,
latestItems: result.items})
}
}
});
})
When you visit a website (any URL on that website), a browser will typically also send a request to that same domain for /favicon.ico so see if the web site offers an icon to be a visual representation of the site.
Since you are using a wildcarded top level route:
app.get('/:listRoute', ...)
That will get hit by the request for /favicon.ico. Some other urls you also may need to watch out for being requested are: /robots.txt, /humans.txt, /sitemap.xml, /ads.txt.
There are a number of ways to work around this:
Your wildcard route can first check req.url or req.params.listRoute to see if it's something it should ignore.
You can place other top level routes that you want to keep out of your wildcard route in a position before this route so they don't end up in this one.
Don't use a top level wildcard route. Instead, use something like /list/:listRoute so it won't automatically match any top level http request. Your use of a top level wildcarded route interferes with other future uses of your site and can create backwards compatibility going forward when you want to add other top level routes to your site. Imagine if sometime in the future, you want to add /contact or /login or /logout. Those all conflict with /:listRoute.
Try to add a callback function to the list.save();
Let me know if this works. The reason is maybe because of sync issues. eg: time taken by mongoDB to update the first document & save > the time taken by the 'Get' method to redirect to itself. Therefore by adding this callback it kinda make sure the code gets saved first and err checked before the redirect.
eg:
list.save(function(err){
if(!err) {
console.log("list is successfully saved"); //log is optional
res.redirect("/" + listRoute);
}
});
When fetching route data using params with express,the entered data easily we can log.But if not adding top-level route and just trying to get the required route eg:
app.get("/:requireddata",function(req,res){
const data = req.params.requireddata;
});
in this case, when loading main page the favicon.ico will generate as a result.
So for getting an exact result, that's when only loading requireddata route we can get the result by using higher level route.
In case there is no higher-level route add just an additional route before requireddata as shown below:
app.get("/add/:requireddata",function(){});
Here /add/ is an additional route for avoiding favicon.ico
For me this worked, so if this information is useful just go head.
Hey there I also came across this exact issue.
So here is my solution to that.
Just enclose everything in a if block and there you go. DONE !!!!
app.get("/:name", function (req, res) {
if (req.params.name != "favicon.ico") {
const name = _.capitalize(req.params.name);
List.findOne({ name: name }, (err, foundList) => {
if (!err) {
//new list with default items created
if (!foundList) {
const list = new List({
name: name,
items: defaultItems,
});
list.save();
res.redirect("/" + name);
} else {
res.render("list", {
listTitle: foundList.name,
newListItem: foundList.items,
});
}
}
});
}
});
P.s.:- It will throw some error from mongo but that'll not affect the overall working.
Hope this helps.

What is the reason for using GET instead of POST in this instance?

I'm walking through the Javascript demos of pg-promise-demo and I have a question about the route /api/users/:name.
Running this locally works, the user is entered into the database, but is there a reason this wouldn't be a POST? Is there some sort of advantage to creating a user in the database using GET?
// index.js
// --------
app.get('/api/users/:name', async (req, res) => {
try {
const data = (req) => {
return db.task('add-user', async (t) => {
const user = await t.users.findByName(req.params.name);
return user || t.users.add(req.params.name);
});
};
} catch (err) {
// do something with error
}
});
For brevity I'll omit the code for t.users.findByName(name) and t.users.add(name) but they use QueryFile to execute a SQL command.
EDIT: Update link to pg-promise-demo.
The reason is explained right at the top of that file:
IMPORTANT:
Do not re-use the HTTP-service part of the code from here!
It is an over-simplified HTTP service with just GET handlers, because:
This demo is to be tested by typing URL-s manually in the browser;
The focus here is on a proper database layer only, not an HTTP service.
I think it is pretty clear that you are not supposed to follow the HTTP implementation of the demo, rather its database layer only. The demo's purpose is to teach you how to organize a database layer in a large application, and not how to develop HTTP services.

How to render data coming from Server side (DB call) Meteor method to template Meteor

I am using Meteor in one of my project where i need to simply show the data on meteor template say inventory.html. I have a method at server side which hit a query and get the data from mongoDb . I call the server side method from client side and getting all the data at client side as well but as the data coming to client side takes some time on the mean time the template is rendered without any values so how would i show the values in the template or there is any technique so that i can show my values or data.
Currently i am using a service to setting and getting data i.e testService.
var testservice = require('./TestService');
Template.allInventory.rendered = function() {
Template.allInventory.helpers({
productDetails: function() {
return testservice.getData();
}
})
}
channels.js where i am setting the data coming from DB
var testservice = require('./TestService');
Template.channels.rendered = function(){
Meteor.call('getDetialsFromDB',function(err, res){
if(res){
console.log("res is...getAllProductDetail.."+res);
testservice.setData(res);
}
if(err){
console.log("Error while calling getAllProductDetail");
}
})
if i call the above method without using the service than its render the template without any data because data coming from backend taking some time like:
Template.allInventory.rendered = function() {
Template.allInventory.helpers({
productDetails: function() {
var data;
Meteor.call('getDetialsFromDB',function(err, res){
if(res){
console.log("res is...getAllProductDetail.."+res);
data = res;
}
if(err){
console.log("Error while calling getAllProductDetail");
}
})
return res;
}
})
so i just want to render my data coming from one of Meteor .method of server side calling from client side or please give any example
Any help would be appriciated!
Thanks
You can use SSR Package for server side rendering.
Template.someTemplate.onCreated(function(){
this.someVar = new ReactiveVar(null)
let self = this
Meteor.call('someMethod',function(err,res){
if(!err){
self.someVar.set(res)
}
})
})
We captured the result of meteor method into reactive variable so as to execute helper function until the method retrieves the result
now make helpers to get the result of the meteor method
Template.someTemplate.helpers({
getSomeVar:function(){
if(Template.instance().someVar.get())
return Template.instance().someVar.get()
}
})

How to mock external service when testing a NodeJS API

I have JSON API built with koa which I am trying to cover with integration tests.
A simple test would look like this:
describe("GET: /users", function() {
it ("should respond", function (done) {
request(server)
.get('/api/users')
.expect(200, done);
});
});
Now the issue comes when the actions behind a controller - lets say saveUser at POST /users - use external resources. For instance I need to validate the users phone number.
My controller looks like this:
save: async function(ctx, next) {
const userFromRequest = await parse(ctx);
try {
// validate data
await ctx.repo.validate(userFromRequest);
// validate mobile code
await ctx.repo.validateSMSCode(
userFromRequest.mobile_number_verification_token,
userFromRequest.mobile_number.prefix + userFromRequest.mobile_number.number
);
const user = await ctx.repo.create(userFromRequest);
return ctx.data(201, { user });
} catch (e) {
return ctx.error(422, e.message, e.meta);
}
}
I was hoping to be able to mock the ctx.repo on the request object but I can't seem to able to get a hold on it from test, which means that my tests are actually hitting the phone number verification service.
Are there any ways I could go around hitting that verification service ?
Have you considered using a mockup library like https://github.com/mfncooper/mockery?
Typically, when writing tests requiring external services, I mock the service client library module. For example, using mocha:
mockery = require('mockery');
repo = require('your-repo-module');
before(function() {
mockery.enable();
repo.validateSMSCode = function() {...};
mockery.registerMock('your-repo-module', repo);
}
This way, every time you require your-repo-module, the mocked module will be loaded rather than the original one. Until you disable the mock, obviously...
app.context is the prototype from which ctx is created from. You may
add additional properties to ctx by editing app.context. This is
useful for adding properties or methods to ctx to be used across your
entire app, which may be more performant (no middleware) and/or easier
(fewer require()s) at the expense of relying more on ctx, which could
be considered an anti-pattern.
app.context.someProp = "Some Value";
app.use(async (ctx) => {
console.log(ctx.someProp);
});
For your sample your re-define app.context.repo.validateSMSCode like this, assuming that you have following setup lines in your test:
import app from '../app'
import supertest from 'supertest'
app.context.repo.validateSMSCode = async function(ctx, next) {
// Your logic here.
};
const request = supertest.agent(app.listen())
After re-defining app.context.repo.validateSMSCode method that your will define in your test, will work, instead of original method.
https://github.com/koajs/koa/blob/v2.x/docs/api/index.md#appcontext
https://github.com/koajs/koa/issues/652

node.js - mean.io implicit/hidden parameters

i'm fairly new to node.js so this could potentially a total noob question. Anyway. I discovered the mean.io Project. In the official article-example on Github, there is the following method in the article-controller.
exports.update = function(req, res) {
var article = req.article;
article = _.extend(article, req.body);
article.save(function(err) {
if (err) {
return res.jsonp(500, {
error: 'Cannot update the article'
});
}
res.jsonp(article);
});
};
With a corresponding route
module.exports = function(Articles, app, auth) {
app.route('/articles')
.get(articles.all)
.post(auth.requiresLogin, articles.create);
app.route('/articles/:articleId')
.get(articles.show)
.put(auth.requiresLogin, hasAuthorization, articles.update)
.delete(auth.requiresLogin, hasAuthorization, articles.destroy);
// Finish with setting up the articleId param
app.param('articleId', articles.article);
};
So I'm confused. When and where does the route pass the req/res parameters to the articles.update, or any other articles function? Is there some hidden mechanism in node/express/mean I've missed out?
Thanks in advance.
app.route('/articles/:articleId')
.get(articles.show);
This means express will invoke articles.show method with request and response as first two parameters when a GET request comes with matching path
.

Resources