ExpressJS pass data to public js file - node.js

I am new in ExpressJS, I know how to pass data from backend to the an ejs page, but I wanted to know how to pass data to a js file in the public folder?
So to pass data to a js file ( which js file is in the same folder as ejs ) while rendering the ejs page in the same time .
From ExpressJS I pass data to ejs by rendering ejs page like this
exports.user_signup = (req, res, next) => {
res.render('login', { page:'Login', email: req.body.email, idd: user[0]._id,} );
}
The ejs file :
<script src="file1.js"></script>
<%= email %>
So what I want, is to pass some data from ExpressJS to file1.js (which is in public folder)..

You cant access ejs data in a Javascript file or pass in data to a js file.
One possible way, Is that you can make use of variable passed to an ejs file.
Copy in your JS code to your ejs file and enclose them in a <script> tag.
pass in your required data to the ejs file ( in our case index.ejs ).
res.render('index', {data: 'some data'});
Inside the <script> tag in ejs file you can access the data like.
<script>
var x= <%- data %>;
console.log(x);
</script>

Related

Node Express i18next - How to send locale text to client side js file?

I have i18next setup in Node.js server side. What is the best practice to use i18next.t() in client side javascript files? I've already set up Express to render server side variables to be used in .ejs files. However, I can't transfer them to the js files that are imported in ejs.
Some possible ways I've thought of:
Export and load i18next that was initialized in the server to the client.
I know the <%= %> variables for ejs work in inline scripts. However, I'm avoiding to have them for content security policy. Perhaps there is a way to send this over to the js file?
Load and initialize i18next on the client-side again. I've tried this and it works, but then there are duplicated locale files for both server and client.
Export the locale files by specifying path. EX
app.use('/locale', express.static(path.join(__dirname, 'locale', {{lng}}.json)));
// app.js
const i18next = require('i18next');
const Backend = require('i18next-fs-backend');
const middleware = require('i18next-http-middleware');
i18next.use(Backend)
.use(middleware.LanguageDetector)
.init({
detection: detection_options,
fallbackLng: 'en',
backend: {
loadPath(lng, ns) {
if (lng === 'zh' || lng === 'zh-HK' || lng === 'zh-TW') {
return path.join(__dirname, 'locales/zh-hant.json');
} else if (lng === 'en-US') {
return path.join(__dirname, 'locales/en.json');
}
return path.join(__dirname, 'locales/{{lng}}.json');
}
}
})
app.use(middleware.handle(i18next));
// index.ejs
<%- include('../includes/head.ejs') %>
<link rel="stylesheet" href="/css/index.css">
</head>
<body>
<h1>
<%= t('locale-text-from-en.json-goes-here') %> // this works well
</h1>
<script src="/js/index.js"></script>
</body>
// index.js
console.log(t('locale-text-from-en.json-goes-here')) // how to use i18next.t() here?
To use i18next on the client you need to install the i18next package via npm or yarn on the client. Or download i18next library via their CDN https://unpkg.com/i18next/dist/umd/i18next.js.
i18next has many extensions for your project, like react-i18next for react project, jquery-i18next for jquery project.

Are there Application scope variables in Node js

I wanted to know are there any application scope variables that can be accessed anywhere in the whole application.
Since I want to add data to my HTML tags using javascript, I need to transfer/get data from the server.js to the index.html
To transfer data from server.js to index.html you don't need to create global variables. You need to use a templating engine: pug, ejs or any other engine.
Just pass the data along with html file in the res.render() function and use templating syntax to display the data at the page.
Router code:
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!'});
});
Pug code:
html
head
title= title //Hey
body
h1= message //Hello there!
ejs code:
<html>
<head> <%= title %> </head>
<body>
<h1> <%= message %> </h1>
</body>
</html>

How can i access a nodeJS variable in ejs views in a sails project?

My LoginController.js looks like this:
module.exports = {
getAuthorizationLink: function (req, res) {
res.send({
authorization_link: sails.config.FACEBOOK_LOGIN_URL
})
}
}
I need to redirect to the authorization_link when a button is clicked
<div class="col-md-4 text-center">
<button id="authenticate" class="btn btn-primary">Authenticate Page</button>
<script type="text/javascript">
document.getElementById("authenticate").onclick = function () {
...
};
</script>
</div>
Here you are looking to mix server-side (EJS) & client-side JS code.
It is possible, makes sense to do sometimes but it is not clean.
Once you understand you are doing this. Variable can be passed and accessed.
Using EJS, write JS code for client side e.g.
var auth_link = '<%= authorization_link %>';
this line will become something like below for client-side JS
var auth_link = 'https://fb.com/login';
Now you can use auth_link in client-side JS as required
Also, check res.view for responding with HTML page

Passing Variable from NodeJS to client-side JS file

Is it possible to pass a server-side JavaScript variable to a <script> tag in an HTML view?
In my routes file I have:
exports.index = function(req, res){
res.sendfile('views/index.html', {
data: {foo: bar}
});
};
If I was using a Jade template, I could do:
script(type='text/javascript').
var local_data =!{JSON.stringify(data)}
To access the data object. However, that doesn't work for an html file. Is there a work-around for this?
Have a route send the data using res.json() and use AJAX in the html to fetch the JSON data.
http://www.w3schools.com/ajax/

How can I bootstrap models from express js into backbone at page load?

I have some data in a mongodb database and want to pass it to a backbone collection when I load the home page. One way of doing this would be to set up a node route like this:
exports.index = function(req, res){
db.users.find(function(err, docs) {
var docs_string = JSON.stringify(docs);
res.send(docs_string);
};
};
But this won't work because it won't render my jade template that pulls in the backbone code, it simply shows the JSON in plain text.
Alternatively, I could render my jade template passing in the data as a variable to jade:
exports.index = function(req, res){
db.users.find(function(err, docs) {
var docs_string = JSON.stringify(docs);
res.render('index', {
title: "Data",
docs_string: docs_string
})
});
};
Then in the jade template, have a script like this to add the users to my user collection:
script
var docs = !{docs_string};
var users = new app.Users();
_.each(docs, function(doc) {
var user = new app.User(doc);
users.add(user);
})
But this seems wrong, since I don't really want to pass the data to the jade template, I want to pass it to a backbone collection. Also, with this solution I don't know how to then include an underscore template (on the backbone side of things) into the page rendered by jade on the server side.
What is the standard way of passing data from a node server to a backbone collection?
Assuming your data is an object, you should convert it to string using JSON.stringify() and then insert in a page inside script tag, so your resulting HTML looks like this (I don't use Jade):
<script>
var data = {...}; // in template instead of {...} here should be the instruction to insert your json string
</script>
Then when the page loads, your script will be executed and the data will be available as a global variable in the browser so you can initialise backbone collection using it. This all is a good idea only to bootstrap your data on the first page load (to avoid extra request) and then use API to request data for this and other pages.
Check out Steamer, a tiny node / express module made for this exact purpose.
https://github.com/rotundasoftware/steamer

Resources