expressjs not passing req.params through middleware - express

Similar to this
I have the following route:
app.get('/blogpost/:link', middleware.loginCheck, blog.postBlogs);
Using req.params.link returns the link parameter.
When I ask for the req.params.link in middleware.loginCheck I receive an undefined.
It seems that req.params.link is not being passed through to the middleware because I can access it like so:
app.get('/blogpost/:link', function(req, res){console.log(req.params.link)});
Whats the problem with my middleware?
FINAL
a(href='/post/#{post.link}') #{comments} renders /post/myPostLink
{#post.link} only renders the variable substitute and does not add an extra /
a(href='/post#{post.link}') #{comments} renders '/postmyPostLink'
a(href='/post/' + post.link) #{comments} renders /post/myPostLink
So both #{post.link} or post.link work the same and req.params.link works on both calls.
UPDATE_2
I am using jade to render the web page. Inside there I have an anchor tag written as so: a(href='/post/#{post.link}) #{comments}
The achor tag works fine and directs me to the correct page. But express does not like this representation. Instead, if I change the anchor tag to a(href='/post/' + post.link) #{comments} req.params.link works fine.
UPDATE_1
req.param('link') works for this case.
There is no problem with the middleware.
But why wouldn't req.params.link work?

OK, we went back and forth in the comments a bit, but now my guess is that the problem is double slashes in your URL
a(href='/post/#{post.link}') #{comments}
That is A) missing a closing quote, but I assume that is a typo just in your question here, not in your code. and B) the real problem is that post.link includes a leading slash, so you end up with this HTML:
<a href='/post//post_link_name'>42</a>
Thus express is parsing that as an empty :link parameter. Change your jade to this:
a(href='/post#{post.link}') #{comments}
and you should get back in business.

In recent versions of express you can use router.param() as your middleware to specifically work on the req.params:
var router = express.Router();
router.param( "nickname", function (req, res, next, nickname) {
console.log( "nickname: ", nickname );
next();
});
router.get( "/user/:nickname", myController.method );

what does the signature of middleware.loginCheck look like? It needs to return a function(req, res, next)

Related

Is it possible to change url using vue-router without going to the page?

There is a shop on nuxtjs and on the /catalog page I need to make a "Load more" button. By clicking on it, products should be loaded and the url should be changed to /catalog/page_2 (?page=2 is not suitable).
If I change the url through $router.push nuxt goes to this page, but I need to change the url, but not go anywhere.
Is it possible to somehow undo the reloading but save the changes in the url?
history.pushState copes with the task, but in this case nuxt does not know that the url has changed and when clicking forward / backward in the browser nuxt does not load the goods needed for this page
Paginations logically belong to the main page so It's good to consider them in URL queries, like ?page=2.
also you can use router.replace to change queries.
this.$router.replace({
query: { ...this.$route.query, page: this.page},
})
Do it with this example
https://codesandbox.io/s/withered-darkness-9ezn9?file=/pages/index/_id.vue
Now I can change the filters, categories, and the url changes, but the page does not reload
As you don't want to change the page if you are already on the correct one, check for differences in current page URL first;
const your_query = '?page=2' // containing url params
const currPath = this.$route.fullPath; // containing current path + query params, e.g. '/catalog/?page=2'
const nextPath = `${this.$route.path}?${your_query)}`;
if (currPath !== nextPath) {
//"Abuse" router to change the current's windows url
this.$router.replace(nextPath, undefined, () => {
//If route navigation fails, e.g. due to a same-route navigation or wrong permissions in navigation-guards, handle here
return;
});
}
Alternative would be to directly pass the new query params to the router, as:
this.$router.replace({ query:
page: 2
})

How can i make my URL seo friendly by removing %?

I am using ejs, expressjs, mongoose and I am rendering templates based on ejs.
One of my landing page has it tile in url. Title is input from user, he may enter with spaces or without spaces. If he entered it with spaces I'm getting an URL like below.
The below URL is complete non SEO friendly so I want to make it plain text with hyphens
http://localhost:8080/photoapp/awesome%20baby%20srija
I want to remove % and replace with - in my URL to make it SEO friendly. how can I do that?
My ejs template:
<td> Campaign Link </td>
My route: This is my post route which is rendering particular page code. How can i achieve this with javascript tags or ejs tricks.
exports.getCampList = (req, res) => {
if (!req.user) {
return res.redirect('/login');
}
Campaign.find({userId:req.user._id}, (err, campaign) => {
if(req.user){
res.render('admin/campaign-list', {
title: 'Campaigns',
camplist : campaign
});
}
});
}
I want remove all unnecessary code and make it url friendly website
You can use slugify or use regex to replace characters and spaces with a hyphen.
function slugify_text(Text){
return Text
.replace(/[^a-zA-Z0-9]+/g, "-")
.replace(/(^\s*-)|(-\s*$)/g, '');}
You can use this to slugify the page name to an SEO friendly URL.

fetch query string parameters and display on pug generated page after form submission

I'm working with express right now. I've built just a simple form that goes to a pug page generated via express after submitting:
form.create-list(action='/test', method='get')
fieldset
legend Add your item
label(for='item-name') Item:
input#name(type='text', name='name', required='')
br
label(for='item-name') Quantity:
input#quantity(type='text', name='quantity', required='')
br
br
input(type='submit')
With the get method, I can see the name properties behind pulled into my URL: http://localhost:4000/test?name=hello&quantity=there
I would like to display specifically the name/quantity parameters on my pug page, but have been unsuccessful. In my routing file I used:
router.get('/test/:name', function(req, res, next) {
res.render('layout', {'title': req.param("name")});
});
And in my pug template just added the below line:
p #{title}
Shouldn't that work? I'm not sure what I'm missing here. Anybody have any suggestions?
The value you should be looking for is req.query.name instead of req.params.name

vars in express routes are blocking any following routes

I'm trying to use vars in my Express routes. They work fine but after i use a variable in a route, any routes after that one will not work. Here's really simple example.
/////////////////////////////////////////////planets
router.get('/:planetID', function(req, res, next) {
if(req.params.planetID == "hoth"){
res.render('index', {
title: 'Hoth',
subtitle:"Damn its cold"
});
}
});
////////////////////////////////////////////////jedi
router.get('/jedi', function(req, res, next) {
res.render('characters', {
title: 'Jedi',
subtitle:"why the f is this happening?",
});
});
In this example, the jedi route doesnt render anything. But if i put the jedi route before the planet route, everything works fine. Has anyone encountered this before?
Many thanks in advance for any help.
Express routes work in a pipe, that means that it will first check the first route and it will see that it accepts a parameter and it cannot see any difference between "/23423423" and '/jedi'. It assumes that jedi is an ID aswell. you should prefix it with
/planet/:planetID
for them not to conflict each other.
Express uses path-to-regexp for matching the route paths; see its documentation for all the possibilities in defining route paths. Apart from that, when you are working in express middle wares, do take care of the order of middle wares defined.
Note : Router is also a middleware in Express.
So you are working with two routes :
/:planetId
/jedi
If you define route /:planetId at the top then it actually treats /jedi as the same route with value of param planetId = jedi, whereas if you place your second route i.e.; /jedi at the top then it goes for exact match condition and if it find /jedi then only it executes the corresponding action else it will try with other routes defined.
ahh ok scopsy, now I see how your /23423423 example applies. Im sorry guys, I didnt post enough info I'm realizing. I had to use an if() statement to tell the route to move on if it didnt find a match. I did this using the next() function and a counter var.
router.get('/:planetID', function(req, res, next) {
var counter = 0;
planetJSON.planets.forEach(function(item){
counter++;
if(item.link == req.params.planetID){
planetDisplay.name = item.name;
planetDisplay.text = item.text;
planetDisplay.image = item.image;
res.render('index', {
planetGrab:planetDisplay,
planetList:planetJSON
});
}//end if()
else if(counter + 1 > planetJSON.planets.length){
next();
}
});//end for each()
});//end router.get
thanks again for your help

Rails3: how to reload a page with a parameter taken from a collection_select within the page?

I have a page with a route in the form : :client_id/tarif/:tarif_name
in the corresponding HTML page, I have a <%= collection_select(.....:tarif_name...) which enables to select the name of the tarif to be shown. That works.
How do I instruct to reload the page with the new :tarif_name parameter in the url ?
I thought of using the :onchange option helper with collection_select, but although I managed to execute javascript this way, I find no example of composing and triggering the loading of a url through that option.
Thank you very much for your help
If you are able to run javascript code in the :onchange, then window.location.href = "your_url" will make the redirect.
You will also need the selected value. Your onchange will be something like
function() {
window.location.href = "your_url" + this.value
}