Use dynamic express routes within another Express route - node.js

For a school project, I created a plugin system for an Express.js-Application in Node.js. The main page of the application should display a dashboard, where every root page of each plugin should be displayed in a div. Every root page is accessible over the pluginName/-route.
What I would like to do is the following: I wanna include the HTML-string of every home-route in the dashboard. But for this, I need to call the routes inside Node.js (like partials) and for some plugins I even have to provide some properties.
Does someone have an idea, how this could be implemented?
e.g. I have following route:
router.get('/pluginName', function(req, res) {
res.render(__dirname + '/views/home.handlebars', {
layout: __dirname + '/views/layouts/main.handlebars',
markup: markup // Pass rendered react markup
});
});
Now I want to pass the resulting HTML from this route into another route.
So far I had the following ideas:
Simply add the URLs of the plugins to a "data-ajax-url" attribute of the divs and load the stuff via AJAX.
Make an HTTP-Call to every route and append the result on server side (pretty nasty...).
Create a renderDashboard-function for every plugin, where I get the HTML using app.render(...) and then I append the result.
But I'm not really sure, which approach (if any) would be the nicest.

Related

Is it possible to render handlebars templates from a database on node.js?

I'm looking to create a single node.js application that will render multiple different client websites.
We currently run one node.js application per client website, but I think this might be overkill as the serverside logic is exactly the same for all of them, the only difference being the handlebars template.
I'm looking to re-architecture to have a single node.js application which will then render the different client's websites based on some incoming information, will use nginx to add a header or something to the request so the app knows which website to render.
Is it possible to store the handlebars template within a database and then request the template at render time? Rendering a simple single page should be easy enough, but I'm struggling to understand how partials would be rendered?
Looking to achieve something similar to Shopify's Storefront Renderer, not sure if it's possible to do with handlebars or if it's better to use of of the LiquidJs ports for Node to achieve this?
https://shopify.engineering/how-shopify-reduced-storefront-response-times-rewrite
I do this with different countries, same concept as you with different Clients.
You just create the Handlebars layout and put it in your partials folder. No need to put template in your database.
Then your server logic will have eg clientName, and your Handlebars will have IfEqual tags (you'll need an IfEqual helper)
Example:
Server route will give a variable clientName.
Handlebars you have the main view page with only the IfEqual helpers.
{{#ifEqual clientName 'Client Name 1'}}
{{> client/clientName1}}
{{/ifEqual}}
{{#ifEqual clientName 'Client Name 2'}}
{{> client/clientName2}}
{{/ifEqual}}
Your helper function will be
, helpers: {
ifEqual: function(x, y, options) {
return(x == y) ? options.fn(this) : options.inverse(this)
} // {{#ifEqual statusLogin 'unconfirmed'}} {{/ifEqual}}
Search nodejs handlebar helper if you dont know how to set it.
So my partial folder, you can create a folder in it called client, and put all your Handlebars template in there. Search for nodejs handlebars partial folder setup if you dont know how to do it.
The handlebar helper function I found it I think in stack overflow, so you can search for others if you want, but for me it works.
Your partial template files just do as normal Handlebar files.
So the main idea is User loads the page, depending on what Client flag you put it, it loads up that template.

How to use the same view in FrontEnd and express server-side rendering?

I have a partial view that is used on server-side rendering to build a HTML page and also in FrontEnd to make a partial update on the UI. BecauseI want to use the same partial view file on both server-side and FrontEnd, I was looking for the best approach to share this file between the two sides.
For now, TBMK I used the following approach:
Placed the partial view file in /public folder which is served by express static middleware.
The server application loads the partial view from the file system.
The FrontEnd loads the partial via an AJAX HTTP request.
Is there any better approach?
I've had a similar problem. My solution was to have a particular route (maybe even in a special controller, for separation of concerns sake) serving the ajax requests.
The controller is serving files from the views directory.
If you'd like to deliver e.g. a file from the app/viewsDir/partialsDir directory you'd use a URL like:
http://myhost.com/partials/my-partial
then controller the could respond like:
router.get('/partials/:partialName', function(req, res, next) {
res.sendfile(`viewsDir/partialsDir/${req.params.partialName}`,
{root: __dirname });
});
This way, you could even have the file preprocessed by handlebars or any other serverside templating engine.
I did it this way, because I didn't want to have any templates located in the public directory.

Looking for passportjs-local simple example using MEAN only

I am looking for a very simple example for using Passportjs (Local api) in my MEAN application. I took a reference from one example on github. There they have used jade to render the page after authentication. But I just want to use my home.html to show home page after authentication.
I have searched many example but in all they are using either jade or ejs. I don't want to use any engine to render the home page.
If anyone can provide a very simple example just using MEAN that would be a great help.
I don't want to use jade or ejs. Just simple html to render page.
Just setup a route similar to this:
app.route("/login")
.post(passport.authenticate("local"), function (req, res) {
res.json(req.user);
});
Then call that as an post call from the function you bind the form to in angular, you don't need to use jade/pug/ejs or any of it. You can simply use express as an API server. Just have angular redirect to the route you want after the successful return of the authentication (you should get a user object back)

Don't redirect on POST express.js

I'm making a basic web app with Node.js and Express 4 and I'm trying to implement a "follow" function. I did some inspecting on the Github website and noticed it used a form with a follow button that would post to the server to follow a user. I think this sounds like a good approach but when I post I don't want to have to reload the page just like the github website.
How does one this inside of Express 4? Everything I put inside the .post route always end up in a page load. I'm pretty sure in jQuery's ajax method you can just return false and nothing will happen to the page, just the request will be sent which is what I want to happen because I'm using a RESTful api and I want to add the user to the current user's following but I don't want to have to use jQuery just for this function. I would prefer it be done in Express if possible, though any help would be appreciated.
views/user.handlebars
<h1>{{user.displayName}}</h1>
<p>#{{user.username}}</p>
<form action="" data-userid="{{user._id}}" method="post">
<button name="follow" type="submit">Follow</button>
</form>
routes/users.js
app.route('/:username')
.get(function(req, res) {
// get :username user from api and load info
...
})
.post(function(req, res) {
// don't reload page
???
// send PUT :username user to current users following array
...
});
So you're on the right track, but instead of putting your actions in the HTML (in your jade file) you're gonna have to add a script section to your jade and use javascript to attach an onClick event to the button so that when you press the button you invoke your ajax method.
Let me know if that doesn't make sense.

How to dynamically render/load pages in express?

I need to dynamically load/render part of a page in nodejs (v1.8.15) with express (>3.0) framework. Generally, I want to create a single-page app.
I have a menu at the top of the page with links. Clicking on the links will change the content below, as in AJAX page loading.
For example:
>home|login|signup|chat
..content for home..
If I press the 'signup' link:
home|login|>signup|chat
..content for signup..
In express I have routes on the server:
var express = require('express');
var app = express();
app.get('/signup', function(req, res) {
// render signup.jade
res.render('signup');
}
app.post('/signup', function(req, res) {
// .. work with information
if (ok) res.send('ok', 200); else res.send(error, 200);
}
After reading this, I figured out that I should use socket.io. I know sockets well, so it will be easy to send data about 'clicking on link' from the client to the server.
Q1: How do I render/load pages dynamically like I wrote in express?
Yes, I could use AJAX for page loading, but will it work for .post methods in express?
How should I organize my thoughts to create such a site?
By the way, I've read about Derby and SocketStream, but I didn't understand.
Q2: Can I use Derby or SocketStream in my aims (site functions: login, signup, chat)? How?
If SocketStream is what I need, that would be very bad, because Heroku doesn't work with it.
Q1) This is in fact very simple, no need for Socket.io, Derby or whatever. You can call any expess route with any method through ajax, using jQuery makes ajax very easy. In your example, let's suppose your container HTML file has a div with id 'container', which is where you want the ajax-loaded content to go:
$.ajax({ url: 'http://yoursite.com/signup'
, type: 'GET'
, dataType: 'html'
})
.done(function(data) {
$('#container').html(data);
})
.fail(function() {
console.log("Something went wrong!");
});
Express supports all HTTP verbs (GET, POST, PUT etc.). For loading pages dynamically, use GET, then when a user enters some login information you can POST it to an Express route that will tell you if it is valid or not, and you use jQuery to modify the DOM accordingly.
Q2) As said in Q1, no need to use Derby or SocketStream. Plain old jQuery + basic Express will get you where you want!

Resources