processing data for templates in express/node - javascript

I'm developing extension to an existing app using expressjs. By requirements I need to do server side rendering. Our API server is running on JAVA.
In my express app, I'm going to have to render page while making serverside calls to JAVA server. For example, I'm going to call getCategories, getVendors, getReviews etc APIs in order get data that I need to pass to rendering template.
What is a good way to accomplish this? I mean pack all of that into a single object and pass to res.render() method. Could you please provide me with some basic examples? I imagine that I would need to create a module that does all of this and returns some nice object...
All of the examples on the internet show something like res.render('index', { data: 'someData'}), however in this case data is bootstrapped. I would need a data to be compiled with several API calls and then passed to the rendering method.
Thanks!

It really depends on whether you want to call your Java API server side or client side.
If server side, your express route containing res.render() will need to collect all the information it needs from Java before rendering the page. If your API is slow, the page load will be slow. If possible, use something like async.parallel to avoid blocking.
Your code sample is correct. res.render('index', { foo: 'bar'})
This would add the foo variable to the root scope of your view. How you build up the data structure is entirely up to you. I would recommend using async.parallel and/or async.series to collate all of the data. If they are all completely independent, run them in parallel.
// an example of how to run each in parallel and then render the view.
var getCategories = function(done) {
// get something
done();
};
var data = {};
async.parallel([
getCategories, // <-- adds to the data structure
getVendors,
getReviews
], function(err) {
res.render('index', { data: data });
});
Your other option is using express to render the base page and using something like jQuery to hit the Java API and update the relevant page fragments.

Related

The relationship between front end and middleware

I have a front end application, which I would like to return results with from an Express backend. Let's just call those results country and city for this reference.
I have done a bunch of searching, but I cannot find any solid resources on the relationship between the front end and middleware. Yes, I know what these things are, and the order in which they should flow, but the confusion sits with :
Do I need to connect my front end and middleware? How so?
If I am already connected to my backend from the front end, would I also have to connect to middleware?
How would I return the country and city from the middleware and/or express backend?
Any other info you think would be helpful for the greater dev community who is still learning would be beneficial.
While you could return data from a middleware, it's probably not what you are trying to do. A middleware is a piece of code that is executed between the time the request is receive by your backend, and the resource is fetch. In a middleware you could do things such as check if a user has access to a certain resource or authenticate a user by some sort of credential passed with the request.
Either way, the way you would, typically, do request from your front-end to your backend is via an XmlHttpRequest. Those request are usually Asynchronous, so they usage will not block the whole page while being executed. There are many ways you could create XmlHttpRequest. The native Javascript way is kinda ugly so I would suggest using the fetch api instead. You could also go with third party library if you need to do more complex stuff. I personnally like axios but this is up to you.
To give you a better understanding of what Express is doing, it's basically an infinite loop that waits for http request. You need to defined routes, that execute function that returns data.
Here is a basic example. Note that this script is executed via NodeJS :
// myserver.js
const express = require('express')
const app = express()
app.get('/cities', (req, res) => {
const cities = /** somehow get all the cities **/
res.json(cities);
})
/** the rest of the server... **/
/** For example, the route for Countries **/
In the previous example, we've built a basic server that listen to the url localhost:3000/cities and execute a function when this url is fetched. The said function will fetch all the cities and return them as JSON.
In your frontend, You would need to do a XmlHttpRequest that would call this url, to get the server to execute the function, which will return the data. Phew... I hope I did not lost you there.
A typical example would be a simple call using the fetch api.
Please note that this script is executed in the browser.
// myclient.js
async fetchAllCities() {
const cities = await fetch('http://localhost:3000/cities');
console.log(cities);
}
// just for fun, we add a click listener on a button and call the function defined above.
document.getElementById('myButton').addEventListener('click', async function() {
// we fetch the cities when we click on the button !
await fetchAllCities();
});
In the previous example, I am using the fetch function to call the url we declared in our Express server.
I'm also using Async / Await, which can be a little tricky, but it just mean Wait for the data to be there before going forward.
I highly suggest reading on the subject. Here are some references.
How do I return the response from an asynchronous call?
Understanding async/await on NodeJS.
Await from MDN
I hope this brief overview of XmlHttpRequest helped you get the base of how an API works.
Middleware is used to help the back-end do its job in processing incoming requests. It does not exist separate from the back-end. It's part of the back-end. For example, you might have middleware that checks to see if an incoming request is properly authorized/authenticated before the route can be handled by it's regular route handler.
Do I need to connect my front end and middleware? How so?
No. Your front-end sends requests to the back-end. The back-end may or may not use middleware to service the request. That's entirely up to the implementation in the back-end and what it needs to do for any given request.
If I am already connected to my backend from the front end, would I also have to connect to middleware?
No. You don't separately connect to middleware. You connect to your back-end and the back-end may or may not use middleware to do its job (something the front-end will have no knowledge of).
How would I return the country and city from the middleware and/or express backend?
You would have to show more details about what you're actually trying to return back from a request, but a common data format is JSON so you could construct a Javascript object with your desired response and then send it back to the client as the response from the incoming request using either res.json(someObj) or res.send(someObj) (both do the same thing if someObj is a Javascript object).
For example:
app.get("/getsomething", (req res) => {
// do some processing here to get cityResult and countryResult
// construct object to send back to client
const obj = { city: cityResult, country: countryResult};
// send this object as JSON back the the client as the response to this
// incoming request
res.json(obj);
});

Persistent object in node.js

I am fairly new to node and backend work in general. We are using express at work for a pretty large monolith application that houses all of our endpoints and services. My task is to grab a property that comes in on the request object (i.e. request.someObject), and use it in several services. In a DOM environment I would use something like localStorage or sessionStorage to store that data, and then reuse it where needed across the application. Im going to try and explain a little further with code:
Endpoint
router.route('/:cartId/generatePaymentLink')
.post(jsonParser, urlParser, function(request, response, next) {
var theObject = request.someObject;
// need to pass theObject to several services
});
Services are stored within separate files, here is an example of one
var paypalInfo = new Paypal({
userId: theObject.user_id,
password: theObject.password
});
I can pass it through parameters to the services that use data, but its used in several different places and would have to be defined in those individual services. Is there a way to create a persistent object/config file that I can just import and have that data, or something like sessionStorage in the DOM?
EDIT: Not a database, looking for another solution. For performance reasons we are avoiding this

Sharing variables between client and server in node

Let me preface by saying that I have spent a considerable amount of time trying to figure out the solution to this problem but I have not discovered something that works. I am using node and want to share a variable between my app.js server file and a client side javascript file (demo.js).
I run node app.js to launch the server and demo.js runs in the client. I have tried using module.exports and export but when I try importing in the demo.js file or referring to the module.exports var I get errors. Maybe I'm approaching this is in the wrong way.
For example, I am trying to use the node wikipedia package to scrape data. I have the following in my app.js file:
var wikipedia = require('node-wikipedia');
wikipedia.page.data('Clifford_Brown', { content: true }, function(response) {
console.log(response);
export const response = response;
module.exports.data = response
});
In my demo.js file I have tried importing this response var and using the module.exports var but I have been unsuccessful.
Anyone have any solutions to this issue or different approaches I should take?
Browser javascript files run in the browser. node.js javascript files run on the server. You cannot directly export things from one to the other. They are on completely different computers in different locations.
It is very important for developers to understand the notion that server-side code runs on the server and client-side code runs on the browser. The two cannot directly call each other or reach the other's variables. Imagine your server is in a data center in Seattle and the browser is running on a computer in Venice.
See How to access session variables in the browser for your various choices described for a previous answer.
In a nutshell, you can have the server insert a javascript variable into the generated web page so that when the javascript runs in the web page on the browser, it can then access that variable in its own page. Or, you can create an Ajax call so the client can request data directly from the server. Or you can have the server put some data in a cookie which the Javascript in the browser can then access.
If the data is easily known by the server at the time the page is generated and you are using some sort of page template system, then it is very easy to just add a <script> tag to the generated page that defines one or more Javascript variables that contain the desired information. Then, the client-side Javascript can just refer to those variables to have access to the data.
To pass data in http there is a request message and response message and the data needs to be inside that message.
In the request you can either pass variables in the request URL
http://host_name/path?key=value
Or inside the request body or headers.
In the response you pass back variables in the response header or response body
First Example:
One way of processing a URL request from the browser explicitly while passing variables is to set up your server to render a html page with those variables embedded.
If you use a templating engine like jade, you can consume the sent variables directly into the template using res.render({ key: 'value' }) rather than using a promise based api call which would run when the user performs some action on the client.
For instance.
// SERVER setup rendering engine
app.get('/', function(req, res) {
res.render( 'index', { key: 'value' })
}
Which will render index.html to the client with the key-value pair passed to the template file used to serve up the index.html (for example jade or ejs).
Second Example:
Using axios you can set up an action to call a server api (you can also pass variables in the URL, headers or body). Using the promise pattern you can then use these variables after the server api has responded.
// CLIENT setup axios
axios.get(URL + '/getkeyvalue')
.then(function(response) {
const value = response.data.key
})
On you server using express you (this is where you would get the optional request variables mentioned above) send back response variables in the body like this.
// SERVER setup express
app.get('/getkeyvalue', function(req, res) {
res.send({ key: 'value' })
}
Note that these are simple examples.
They are too completely different systems. The best way to accomplish what you're trying to do is the create a variable in your html on the server side by stringifying your data
<script> var my_data = <%= JSON.stringify(data) %> </script>
Thats an example using ejs, a common templating language in expressjs

Communication between an express node server and its displaying html

Really fast, this question may have already been asked, but I am not totally clear on the terminology and have had no success when searching for a solution.
I am attempting to create a simple web application that can receive get and post requests. Then, I would like to take the information I receive from these requests and use them in a javascript file embedded in html that is displayed. I think it may be more clear with code. This is my app.js:
var express = require('express');
var app = express();
var assert = require('assert');
app.use(express.static('javascript'));
app.get('/', function(req, res) {
res.render('index.jade');
});
app.listen(3000);
I would then like to be able to take information received from a get or post request, specifically in JSON format, and then be able to use it in javascript that I have linked to index.jade. To make matters slightly more confusing in index.jade the only line is:
include map.html
So ideally I would be able to get the information to javascript in that html file.
I want to be able to pretty continuously update map.html using javascript based on frequent get and post commands.
This could be a very simple solution, I am pretty new with web application programming in general, and I have been struggling with this problem. Thanks in advance, and ask if you need any clarification.
I think you need to understand what you are doing. You are creating a web server using node.js. Express framework simplifies that for you. The official documentation of express is pretty great. You should refer that especially this link.
Now, in your application, you need to create endpoints for GET and POST requests. You have already created one endpoint "/" (root location) that loads your home page which is the contents of the file index.jade. A small example is :
app.get('/json', function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ a: 1 }));
});
Jade is a templating engine which resolves to HTML. You should refer its documentation as well. Since as you said, you are not very familiar with these, you could simply use HTML as well.
After this tasks are quite simple. In your javascript, using ajax calls you can access the GET or POST endpoints of your server and do the desired actions.
Hope it helps!
The way I get it you want to be able to call an endpoint (lets assume /awesome) pass some info and then write to a Javascript file that you can then reference in your html.
Something like the below would write a main.js file in your public folder. You can make it write whatever you want.
var fs = require('fs');
fs.writeFile("/public/main.js", "console.log('Hello!')", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
You can then reference /public/main.js in your html.
Check that: Writing files in Node.js
If I misunderstood your intentions, apologies. :)
So you want to reviece continuously data from the server maybe web sockts are an option for you http://socket.io/docs/
This way u will open a stable connection from the client to the server. This is a great way if u want to get updates done by other clients.
If you want to trigger the changes by the client then ajaxs calls(http://www.w3schools.com/ajax/) as hkasera mentioned are the way to go.

How to set Backbone.js to include model name in JSON post?

I've been working on a Backbone.js project that syncs to a Google App Engine REST server I've also put together. I'm using the Appengine-Rest-Server project code to enable the REST interface. IT works really well, but there is one problem. When I post a new model to it, it expects a JSON post in the form of:
{ 'modelname' : {'attribute1':'attribute','attribute2':'attribute'}}
When I use python and the requests library to POST this data to my REST server... it works fine.
Backbone.js appears to be sending POST requests without the model name a la
{'attribute1':'attribute','attribute2':'attribute'}
Now, not being an expert on what formats are 100% RESTful, I'm not sure whether my REST server is improperly configured (in which case I don't expect you guys to be able to help with the code), whether Backbone.js is improperly configured, or whether both formats are potentially RESTful and I just need to figure out how to get backbone to add in the model name.
So, to close, is one or both of these formats compatible with a truly RESTful API? If requiring the model name in the JSON is not a gross violation of making a RESTful API, does anyone know how I can make Backbone send out post requests in the proper format?
Thanks!
Most elegant way:
YourModel = Backbone.Model.extend({
name: 'modelName',
toJSON: function () {
var data = {};
data[this.name] = _.clone(this.attributes); // or Backbone.Model.prototype.toJSON.apply(this)
return data;
}
});
Or you can directly pass data to the options
model.save(null, {
data: {
// custom format
}
});

Categories

Resources