How to call a function inside a Template literal in node js - javascript

I am using node js , express. I am trying to call a function in template literal.
I made a module and import in main file and then add the function to app.locals and accessing in my views that works fine. But when i try to use it in template literals and also in my public file it give me error "currencyToWords is not defined".
I think in public file it makes sense because i make public folder static.
but in my views it is weird because when i use it in html it works but when i use it in template literal it gives error.
I want to use the currencyToWords function in template literals to change the response.
I have one solution that i can make the file in public folder and add the function in script in that file and import in footer but i dont want to do that.
Can anybody help me in solving the issue.
My app stucture
module.exports = { currencyConverter }
In app.js
app.js is my main file where i create server
var { currencyToWords } = require('./config/functions');
app.locals.currencyToWords = currencyToWords;
by adding in locals i can access it in my application any where
This code is working:
<div class="fix pull_right">
<h3><%= currencyToWords(property.propertyDetails.price)%></h3>
</div>
This is not working
var a =`
<p>${currencyToWords(property.propertyDetails.price)}</p>
`;
the above code is same but only difference is first one is use in ejs tags and second in ejs and template literals.
Here is the documentation from express about app.locals
app.locals
The app.locals object has properties that are local variables within the application.
console.dir(app.locals.title)
// => 'My App'
console.dir(app.locals.email)
// => 'me#myapp.com'
Once set, the value of app.locals properties persist throughout the life of the application, in contrast with res.locals properties that are valid only for the lifetime of the request.
You can access local variables in templates rendered within the application. This is useful for providing helper functions to templates, as well as application-level data. Local variables are available in middleware via req.app.locals (see req.app)
app.locals.title = 'My App'
app.locals.strftime = require('strftime')
app.locals.email = 'me#myapp.com'

Related

Http initial load data from local json file, then refreshing data via another call to a different file angular 4

I am working on an angular application with the angular cli. Right now I am using http.get to call a local json file and render the data on initial load. My task is after a certain amount of time of initial load, I am supposed to call data from a different local json file and update the UI to reflect the new data. I am unsure of the best way to approach this. Can someone provide some examples of a data refresh?
You can use the setTimeout function.
e.g.
setTimeout(() => {
// Load from the other json file
}, 1000);
Let's say, you want to use a json file that contains a list of cities and you want to reference the city names in a dropdown list, this is how you will go about it.
Since you are using the Angular Cli, that means you are using Webpack so first of all, go to typings.d.ts and insert an object like this.
declare module "*.json" {
const value: any;
export default value;
}
The above code will allow you to import your json file in your component.
Now go to your component and import your json file. For example:
import * as cities from "./cities.json"
Next, you can use this little hack to get the contents of the json file.
cities: any = cities
Now in your view, you can reference it in let's say an ngFor
<select>
<option *ngFor='let city of cities'>{{city.name}}</option>
</select>
Try something like this:
file1$ = this.http.get('file1.json');
file2$ = this.http.get('file2.json').delay(1000);
Observable.combineLatest(file1$, file2$)
.subscribe(([file1, file2]) => { ... })
If your json files are only local you can also import them directly. Add typings.d.ts file in your project root with:
declare module '*.json' {
const value: any;
export default value;
}
Then you can use it in your code:
import * as file1 from './file1.json';

Isomorphic JS - variable is not available on client

I'm currently working on a project which uses some shared JS between client and server. The tech stack includes Node v6, Webpack, React etc.
There's a directory "shared" from which server and client require a file called rules.js. On the first render which happens on the server side, the rules variable declared in rules.js is set with a value from DB (I've done console.log to verify it's really filled with data).
Then on client side some component might require this rules.js file and get the rules variable. However, when I console.log the variable, it's empty.
The rules file looks similar to this:
// shared/rules.js
let rules;
// This is called on server to set the value
exports.setData = function(data) {
rules = data;
}
exports.rules = rules;
Do you have any idea what could be wrong? Should I choose different approach?
While the file may be shared by both the client and server, the instance of the class is not. So, anything you do to it on the server will not persist on the client, and vice versa.
One idea available is that of "dehydrating" and "rehydrating" your state.
server.js
// implemented in server to dehydrate your state
import rules from '../shared/rules';
let dehydratedRules = JSON.stringify(rules.rules);
let html = renderToString(<App/>);
// now in your render call
res.render('yourTemplateFile', {html, dehydratedRules});
yourTemplateFile
...
<script type="text/javascript">var __RULES__ = {{dehydratedRules}};
...
client.js
// implemented in client to rehydrate your state
import rules from '../shared/rules';
let parsedRules = JSON.parse(__RULES__);
delete window.__RULES__;
// set the rehydrated data back in the class
rules.setData(parsedRules);
Checkout this SO answer utilizing an analogy from Back to the Future to explain dehydrating/rehydrating.

Merge two json objects on the server side

I have inherited an express application. In the application we pass to res.render a massive list of local variables. For every page we pass about 30 variables that do not change. If one does change it needs to be changed in a dozen places. This is obviously bad.
So what I want to do store the values locals that do not change separate from the truly local. So I placed these non-changing values in their own file and load the file at the start of each route, like so:
'use strict';
var locals =
{
indexName: 'Home',
...lots more of these...
};
module.exports = { locals : locals };
// in each route files
var local = require('../locals.js');
And I can use it via res.render('sensor', local.locals);
However I also need to add page specific values. So I tried local.locals + { ... }; which doesn't while it doesn't give an error doesn't even show the original values.
I then tried local.locals.concat({...}) but that does give an error (TypeError: Object #<Object> has no method 'concat'), likewise for extend and push.
Is there no methods to extend or merge two objects? Do I need to roll my own?
Also, is this the best way of making the an array global? I would prefer just to call it locals, and not local.locals as that is just cumbersome.
In addition to Object.assign from #mostruash, there are two JS libraries that are very similar, which both provide an object merge function (along with a lot of nice helper utilities). Pick one:
underscore
lodash
Edit: and as to your second question about local.locals...of course, just export the object itself, rather than an object that wraps it:
module.exports = locals;
...and in your routes:
var locals = require('../locals');
console.log(locals.indexName);

Accessing handlebars variable inside client js file

I'm generating a handlebars view with hbs for express js framework, and I need to access the variables I pass to the view from inside a separate JavaScript file.
For example:
var foo = {{user.name}}
Obviously this code throws an error, but what is the preferred way of getting hbs variables inside JavaScript?
Currently I'm running another ajax request to get the same data. but I think it is not wise to make another request for the same data...
Found the solution, seems like i just had to put the handlebars variable inside a string for it to work.
In order to pass and Object to a variable I created hbs helper:
hbs.registerHelper('json', function(context) {
return JSON.stringify(context);
});
and the in my view:
var currentUser = JSON.parse('{{{json user}}}');
and now i can access the data on the client side js.

Getting access to data in jade template (to make static html)

I am trying to pass some data to jade template to generate static content. I do not know much about node.js and express, I don't use them as backend. I use jade as a template engine and to generate static html.
There are lot of request in jade issue list about having multi line code, and the owner comments
I'd like to promote keeping too much js out of the templates, maps etc
can be exposed via locals
if there's a lot of logic or objects etc within a template you should
be using app.helpers() etc, they can still be view-only helpers but at
least it keeps the templates cleaner
I am not quite sure how to do this in a grunt based environment. Basically, if I can get access to javascript variables (which may be a text, js or json file) in my jade template, so I can use the data in my template and generate static html files. What is the best way to do this?
Edit
To clarify further, I may have data like (say in a json file)
user1 = {link: '', lbl: 'User', txt: '.... lot 0f text ....'}
user2 = {link: '', lbl: 'User', txt: '.... lot 0f text ....'}
in my mixin, somehow I need to access user1, user2 etc in my jade template
.content
+colum(user1 )
+colum(user2 )
mixin colum(d)
.span4
h4
| #{d.lbl}
p
| #{d.txt}
Thanks a ton.
If you want to do it with grunt-contrib-jade try the data option:
jade: {
compile: {
options: {
data: function(dest, src) {
// Return an object of data to pass to templates
return require('./userData.json');
},
},
files: {
"dest.html": ["templates/*.jade"]
},
},
}
Here are the docs on it: https://github.com/gruntjs/grunt-contrib-jade#data
You can render your data in jade with: #{your_variable}
Hope this helps: The jade public API https://github.com/visionmedia/jade#readme
Update: after play around for awhile, I got this:
var jade = require('jade');
// Compile a function
var fn = jade.compile('p= data');
console.log(fn({'data':'test'}));
When I ran this code, I got: <p>test</p>. So here is how jade can work:
jade.complie(jadeString) is a function to determine what string that jade have to complie - the jadeString parameter, you can use fs module to load the content of your jade template and place it here. fn(jsonData) is the function that actually complie the jade template to html, jsonData is the data you want to use in the template.

Categories

Resources