I am trying to add paging using express-paginate module. But i am getting limit parameter in url like this: http://example.com:3010/feeds?page=2&limit=10.
But i don't want to use limit in url. How i can remove limit from url?
Below is my pug file code.
if paginate.hasPreviousPages || paginate.hasNextPages(pageCount)
.navigation.well-sm#pagination
ul.pager
if paginate.hasPreviousPages
li.previous
a(href=paginate.href(true)).prev
i.fa.fa-arrow-circle-left
| Previous
if pages
each page in pages
a.btn.btn-default(href=page.url)= page.number
if paginate.hasNextPages(pageCount)
li.next
a(href=paginate.href()).next
| Next
i.fa.fa-arrow-circle-right`
I think you can add this by creating a simple middleware function, e.g.
const app = express();
const DEFAULT_PAGE_COUNT = 10;
// Intercept all calls and add a default page count.
app.use(function(req, res, next) {
if (!("limit" in req.query)) {
req.query.limit = DEFAULT_PAGE_COUNT;
}
next();
});
And actually, I believe the module supplies this middleware function, e.g.
// keep this before all routes that will use pagination
// paginate.middleware(limit, maxLimit)
const paginate = require('express-paginate');
app.use(paginate.middleware(10, 50));
Related
app.js
app.get('/save', function(req,res){
var switchInput = {
sw1: req.query.switch1,
sw2: req.query.switch2,
sw3: req.query.switch3,
sw4: req.query.switch4,
sw5: req.query.switch5,
sw6: req.query.switch6,
}
console.log(switchInput);
module.exports = switchInput
res.send(switchInput);
});
simulate.js
var mongoose = require('mongoose');
var suit = require('../app')
...
function batteryLife(t){
var elapsed = Date.now() - t;
t_remaining = fullTime - elapsed;
t_battery = secondsToHms(Math.floor(t_remaining/1000));
//console.log(Math.floor(elapsed/1000) + ' s');
console.log(suit.sw1);
return t_battery;
};
Console Log:
{ sw1: 'true',
sw2: 'true',
sw3: 'true',
sw4: 'true',
sw5: 'true',
sw6: 'true' }
--------------Simulation started--------------
undefined
undefined
undefined
undefined
--------------Simulation stopped--------------
When I try to access these values from a different js file they print as undefined I am using postman to simulate values
The values will log from here but print undefined from the other js file
Is there a way to correct this I'm not sure what I am doing wrong
the values are loading into "inputSwitch" but are not coming out on the simulate.js side
First of all, while using youre favorite webserver like Express, you request aka (req) will/could flow amongst middleware before reaching your specific endpoint. Which means your req params are accessible at anytime there which could help you for specific code logic middleware-the-core-of-node-js-apps.
I agree with vibhor1997a, you should not export something there, basically you only module.exports "things" at the end of a file, not something at run-time.
You could do if you really want to deal with switchInput in another file do :
do what vibhor1997a suggest (sync or async function)
have a middleware before reaching your endpoint
raised an event with your switchInput as argument example
You're exporting on an event which isn't a good idea. What you can do instead is call a function in the other file where you need values with the values.
Example
app.js
const simulate = require('./simulate');
app.get('/save', function(req,res){
var switchInput = {
sw1: req.query.switch1,
sw2: req.query.switch2,
sw3: req.query.switch3,
sw4: req.query.switch4,
sw5: req.query.switch5,
sw6: req.query.switch6,
}
simulate(switchInput);
res.send(switchInput);
});
simulate.js
module.exports = function(input){
//have all your functions and code that require input here
function foo(){...}
function bar(){...}
}
You have an application created in express and angular that allows the user to perform a search. The URL is built based upon the search that was just performed. So if you perform a search on “Will” the url looks like http://localhost.com:9000/search/query?q=Will Everything works fine but you forgot that the app previously performed searches without the /query?= and now all of your old links like http://localhost.com:9000/search/will or http://localhost.com:9000/search/roberto no longer work.
What would be the correct approach to get the old links working again?
Should you use JavaScript on the frontend to look for /query?= missing in the URL and add after the search path but before the queried text?
It'd be easier to do a redirect on the Express back-end.
Say your code for the /search/query path is initially like this :
app.get("/search/query", function (req, res) {
// Do your query validation and fetch your search result.
// Here, I just check if a query value was given or not for the q param.
// I recommend you use better ways to check for empty queries.
// (ex: lodash's `isEmpty()` function)
if (req.query.q) {
// Serve the page !
res.send("What you want to render if the search result finds something.");
}
else {
// Return an error !
res.status(404).send("Nothing was found with the criterias entered.");
}
});
This is probably similar to what you have. Now, here is the answer to your question, based on the initial implementation above :
app.get("/search/query", function (req, res, next) {
// Check if a query value was given AND if the value isn't equal to "query".
// The later condition is to prevent infinite loops.
if (req.query.q && req.query.q !== "query") {
// Redirect using the value assigned to the q query param.
res.redirect("/search/" + req.query.q);
}
else {
// Since there is no query parameter named `q` in the request,
// we can be sure that `query` reffers to a search term.
next();
}
});
app.param("srchterm", function (req, res, next, value) {
// Check, for example, if the value isn't empty.
if (value) {
// Do your query validation and fetch your search result HERE.
// Add those results in an array in the res.locals object.
// Those results can be used later.
res.locals.results = ["all", "your", "search", "results"];
}
next();
});
app.get("/search/:srchterm", function (req, res) {
console.log("another blah");
// We don't need to fetch the data here anymore, since it's handled by the param parser above!
// However, it's still necessary to check if the search gave back some results.
if (res.locals.results) {
// Serve the results !
res.send("A total of " + res.locals.results.length + " results were found for " + req.params['srchterm']);
}
else {
// Return an error !
res.status(404).send("Nothing was found with the criterias entered.");
}
});
So from now on, every query using /search/query?q=123 will redirect towards /search/123. It even lets you use query as the search term!
Just use a regex and redirect
app.use(function(req, res, next) {
var searchRegEx = /\/search/g;
var searchedTerm = req.originalUrl.replace(searchRegEx, '');
var queryPath = req.originalUrl.match(/\/query[?]q=/);
if(!queryPath) {
var regexSlash = /\//g;
res.redirect('query?q=' + searchedTerm.replace(regexSlash, ''));
}
else {
next();
}
});
I am making a project with node, express, and jade. I want to access content through:
/Page/foo/bar
and
/Page?Foo=foo&Bar=bar
I want the top to be an alias for the bottom.
This is the solution I have now:
server.js
// some stuff
app.get('/Page/:Foo/:Bar',function(req,res){
res.render('Page.jade', {Foo: req.params.Foo, Bar: req.params.Bar});
});
app.get('/Page',function(req,res){
res.render('Page.jade', {Foo: req.query.Foo, Bar: req.query.Bar});
});
// more stuff
Page.jade
doctype html
html
head
script var foo = "!{Foo}"; bar = "!{Bar}";
script(src="/Page.js")
// stuff
Page.js
// stuff with foo and bar, such as:
console.log(foo);
console.log(bar);
The thing I don't like about this solution is that it forces me to handle the params and query separately with express (which is almost duplicate code, but not quite close enough to reduce it), pass it to jade, which stores it in a variable for the sole purpose of having a linked javascript file use those variables.
Normally just using query strings I would only have to touch it in Page.js. Is there a way to set up express to effectively interpret the first URL as a query string, like the second URL, so the jade file doesn't have to touch the variables?
Option 1: If you just want to reduce code redundancy, maybe you could save your controllers in an external file, so you will end up with something like this:
controllers/fooBarController.js:
exports.fooBarQueryOrParams = function(req, res) {
res.render('Page.jade', {
Foo: req.params.Foo || req.query.Foo,
Bar: req.params.Bar || req.query.Bar
});
}
You could also add a default value with another || operator if undefined is not valid four you.
server.js:
var fooBarController = require('controllers/fooBarController');
app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams);
app.get('/Page', fooBarController.fooBarQueryOrParams);
Option 2: Same thing, but using res.locals, so now there's no need to pass any object to Page.js, all your views will see res.locals properties just by its names, in this case Foo and Bar (not res.locals.Foo and res.locals.Bar).
controllers/fooBarController.js:
exports.fooBarQueryOrParams = function(req, res) {
res.locals.Foo = req.params.Foo || req.query.Foo;
res.locals.Bar = req.params.Bar || req.query.Bar;
res.render('Page.jade');
}
server.js:
var fooBarController = require('controllers/fooBarController');
app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams);
app.get('/Page', fooBarController.fooBarQueryOrParams);
Option 3: Always expose everything thought res.locals:
controllers/fooBarController.js:
exports.fooBarQueryOrParams = function(req, res) {
res.render('Page.jade');
}
server.js:
var fooBarController = require('controllers/fooBarController');
app.use(function(req, res, next) {
for (var key in req.params) res.locals[key] = req.params[key];
for (var key in req.query) res.locals[key] = req.query[key];
next();
});
app.get('/Page/:Foo/:Bar', fooBarController.fooBarQueryOrParams);
app.get('/Page', fooBarController.fooBarQueryOrParams);
I would go for the first option as I suppose you don't really need to use Foo and Bar in all your views, so there's no point in using res.locals to expose them to all your views instead of just to the ones that really need them.
You could just set the object properties yourself and continue to the next route etc
app.use('/Page/:Foo/:Bar',function(req, res, next){
for (var key in req.params) {
req.query[key] = req.params[key];
}
next();
});
var s_bookingController = require('s/controllers);
app.get('/dashboard/:page/:param', s_bookingController.index)
app.get('/dashboard/show/:id', s_bookingController.show);
Controllers:
exports.index = function(req, res, next) {
var page = parseInt(req.param("id"));
data = {};
data.page = page;
data.nextPage = page + 1;
data.prevPage = page - 1;
MyModel.find().sort('brand').skip((page-1)*11).limit(11).exec(function(err, result) {
res.render('index', {
data: data,
booking: result,
});
});
};
And
exports.show = function(req, res, next) {
var id = req.param("id");
res.send(id);
};
I'm using this controllers, but there is something wrong with the code of the exports.index, because it's stuck in the code.
If I change the routes to:
app.get('/dashboard/:page', s_bookingController.index)
(Note that I'm take off the second parameter that I was passing)
the show will work, but if I use the second parameter, the show will not run, it will be stuck in the index page.
Why is this? I was wondering if I need use the next();.
Expanding my comment:
You should have the following order of the routes:
app.get('/dashboard/show/:id', s_bookingController.show);
app.get('/dashboard/:page/:param', s_bookingController.index);
Express routing requires that a more specific route should be placed above the more general one.
The /dashboard/show/:id is more specific in this case as /dashboard/:page/:param covers it, so that /dashboard/show is handled by it. When the route is handled next routes are not executed.
I am looking for a way to route different subdomains to different plugins. I looked through the API docs, and didn't find anything helpful.
I ended up making a simple class to create plugins that only work on certain subdomains. Here it is.
var Plugin = function(attributes, routes) {
// Add our routes to the server
this.register = function(plugin, options, next) {
// Loop through the selected servers and add the routes
plugin.servers.forEach(function(server) {
// Loop through the routes and add the vhost option
routes.map(function(route) {
route.vhost = attributes.vhosts.map(function(vhost) {
return vhost + "." + server.info.host;
});
});
// Add the routes
server.route(routes);
});
next();
};
// Add our attributes
this.register.attributes = attributes;
};
Then you can make a new plugin and specify the subdomains easily. Example:
var plugin = new Plugin([
// Your route or routes here
], {
vhosts: ["array", "of", "subdomains"]
});