Load routes dynamically in express js - javascript

I am building a blog like app, and posts can be created in the admin dashboard and the public user can visit a published post via the category and permalink.
I have having issues thinking about how to register the routes in my express app.
The solution I have in mind is to fetch all posts and use a for loop to register the routes on app init. The controller is pretty simple, just render the same template.
posts.forEach((post)=> {
app.get(':' + post.category + '/:' + post.slug, renderPostGenericController);
})
Will like to vet this solution and know if there is any other better way to do this.

You can register one route:
app.get('/post/:category/:slug', (req, res) {
// req.params.category
// req.params.slug
...
});
This way, in your route handler you'll have access to both parameters. Now you can fetch the correct post from the DB (or wherever) with the provided category and slug.

Related

How to create a global function which will access DB in express.js

I use express.js, mongodb, ejs. In the navbar, there's an email icon and will display the count of new emails.
<%=newEmailCount%>
Then I need to add this newEmailCount to every route.
Emails.count({userId: userId, new: true})
my question is in express.js, how can I add a global function that can be executed by every route?
If you want to get the count for every GET requests then you can use following approach
router.get('*', function(req, res, next) {
res.locals.newEmailCount = Emails.count({userId: userId, new: true})
next();
})
You need to make sure this is always executed by placing it above all the other routes.
You can then pass res.locals.newEmailCount to your render function which renders HTML file for matched route.
This will work also for application instance level routes handling if that's what you're using.

How to pass request parameters back to Angular

I currently have an app which uses Express with Jade templates.
I'm building a new version of the app using Angular with client-side HTML.
I need access to certain request parameters in order to determine user permissions in my Angular code. My problem is that I don't know how to get ahold of these parameters in my Angular controllers/services.
Below is what currently occurs in Express with the Jade structure:
routes.js:
router.get('/player/:id',
playerRoute.show
);
player.js:
var show = function(req, res) {
res.render('player', {user: req.user});
};
...and now my new version's handler:
var player = function(req, res) {
//res.sendFile(path.join(__dirname, '../v2', 'index.html'));
res.json({user: req.user});
};
The correct user JSON is sent back to my client-side with the code above. When res.json is commented out and res.sendFile uncommented the correct HTML is rendered. My dilemma is how to both render this HTML AND provide my client-side Angular code with the user JSON object?
After all that, your question just boils down to:
MY dilemma is how to both render this HTML AND provide my client-side Angular code with the user JSON object?
You don't. The usual case is to just render the HTML along with the assets needed to render the initial app (hide everything, show a splash screen whatever). Further data (like getting your user) is handled by API calls to your server via Angular's HTTP facilities. That means they are separate. After that API call, your app determines what to render.
Otherwise, you could just render the data in the HTML as some global variable and have Angular pick it up from there. This is messy IMO, but doesn't require a separate API call to get the data.
copied from my own answer to a similar question
To get a variable from server to client javascript try templating a json string into the html and loading it from the javascript. EJS handles quote escaping and I think Jade does too. For reference content!= safeString tells Jade to skip escaping, so does content !{safeString}.
- var user={id:1, displayName:'foo'}
#example
meta(data-userJSON=JSON.stringify(user))
script(src="//code.jquery.com/jquery-1.11.3.min.js")
script.
var user = JSON.parse(
$('#example meta').attr('data-userJSON')
)
console.log(user);
span #{user.id}
span #{user.displayName}
Here's how I ended up handling this situation. I simply created a new API endpoint which I can easily hit with an Angular service. Here's the Node setup:
routes.js:
router.get('/currentUser',
apiController.currentUser.index
);
currentUser.js:
var index = function(req, res) {
res.json({user: req.user});
};
module.exports = {
index: index
};
Still seems odd to me to make an API call to get the request parameters, but it works. Feedback appreciated.

Passing data to view in ExpressJS + Reactjs

I have an app and part of it is to login with twitter.
After successfully logged in, I will usually pass the user data to the template by
app.get('/', function(req, res, next) {
log("The Home page has the user info: ", req.session.user);
res.render('pages/home', {
app: 'home',
user: req.session.user || ''
});
});
And then you can render the template based on the user data.
But in React, how should I pass such data to the component after logged in?
I am thinking of putting the data in the browser directly, but I am not confident about that.
<script type="javascript">
var user = #{user}
</script>
How do you think?? Thanks.
Usually you send the props you pass to the top level component to the client in a script tag.
So, you're doing <MyApp user={user} /> or MyApp({user: user}), you would create a script tag like this:
var code = "<script>var __react_preload_data = "
+ JSON.stringify({user: user})
+ ";</script>";
And on the client side:
React.renderComponent(MyApp(__react_preload_data), document.body);
There is a library that works well with express (and any other view rendering node framework) called react-helper (https://github.com/tswayne/react-helper). It pretty much handles everything you need to do to render react components in your view and pass data to them from the server in any node framework. You just make an entry point (js file) for webpack (the lib has a cli that can generate your webpack config for you) and add a line to your controller and view and your component will render on that page. Passing data into your react components is really simple:
const component = reactHelper.renderComponent('MyComponent', {user:
req.session.user || ''})
res.render('view-to-render', {component})
There is also express middleware for react-helper (https://github.com/tswayne/express-react-helper) that allows you to add context that is available to all views, which is convenient for user session data.
app.use(function(req, res, next) {
req.reactHelperContext.user = req.session.user || '';
});
Then, all of your react components will have the user prop without having to manually add that logic to every controller action.

Sails.js index.ejs controller logic

I'm a little confused on how to add logic to the home page of my Sails.js app. Right now, its just a static page, but I would like to include data on the homepage (index.ejs). I have a MainController and I included a index: function that is pulling in the data. I can't figure out how to configure my route to allow for this.
From What you wrote I am guessing you are using Express js and ejs template.
If you are using the Express render method in your mainController to render your index.ejs you can send the data with response like:
res.render('index', { data: 'my data' }, function(err, html){
// handle callback and error
});
so here you have sent some data
then in your index.ejs file you can get data using ejs tags like:
<div><%= data %></div>
Tell me more about your mainController method if this is not useful
The static-folder is for static-content only (as the name is telling us). If you want your website to show content dynamically you need to create a controller like that:
module.exports = {
index: function(req, res){
res.view(); // sending the view in /views/{controller_name}/index.ejs
return;
}
}
Cheers!

Node.js preresponse with Express

So I'm doing a web page with Node.js and Express framework. I already have registration and login (I'm holding users id in a session). Next step is to render different page whenever a user is authenticated.
Some of those pages require a User object which is just a mapping of a user from my db. So whenever an authenticated request comes I need to retrieve the user from my db. But writing this code every time seems to be a bad way to do this. So here's the question: is it possible (and if it, then how?) to do, say preresponse, so I can automaticaly retrieve User object whenever I know that the user is authenticated and THEN do the main response?
Middleware is what you are referring to. Middleware is just a function that gets called sequentially when the route is triggered. So to have a loadUser function:
function loadUser(req, res, next) {
// You would fetch your user from the db
var user = users[req.params.id];
if (user) {
req.user = user;
next();
} else {
next(new Error('Failed to load user ' + req.params.id));
}
}
app.get('/user/:id', loadUser, function(req, res){
res.send('Viewing user ' + req.user.name);
});
You can define as many middleware functions as your need. Just be sure to call next() at the end to pass the route handling on to the next function.
This EXACT example is covered in the express.js route middleware docs. Go read it and you'll see the pattern of using middleware to factor out common functionality that you need at many route paths in your app.

Categories

Resources