NODE.JS accessing functions within an EJS template - javascript

I have a scripts.js file that includes a function inside that i want to access within an EJS templates.
in the templates i included a header, in the header I added a script rel to scripts.js
<script src="/scripts/scripts.js" type="text/javascript"></script>
I tested it though console.log("test") and when the template is being called I see "test" appears in the console.
when I try to call an actual function (verify_data) within the EJS template i get an error verify_data is not defined.
the error code within the EJS looks like this:
<p><em>Submited By <%= verify_data(results.user.username) %></em></p>
the function check if the argument passed is null/undefined, if yes the data returns if not "n/a" string returns instead.
How do i access JS functions directly within EJS template ?
Thanks,

Assuming you're not using a SPA framework, you need to add a tag which will be either replaced by the function or to contain the data you want to store.
Look at this code snippet
<p><em>Submited By <span id='userData'></span></em></p>
<script>
//This is the script.js
function verify_data(userName) {
return `My data with '${userName}'`;
}
</script>
<script>
let data = verify_data("EleFromStack"); // assuming <%=results.user.username%> = "EleFromStack"
document.querySelector("#userData").textContent = data;
</script>

Related

How to pass a variable from my controller, to the HTML, then to a JS function?

My controller ultimately renders this:
res.render('my-html', { title: `${title}`, myVar1, myVar2 });
In the HTML, I can access the variables in order to display data directly into the HTML. But what I'm trying to do is then pass those variables into a client-side JS function:
function myClientSideFunction(myVar1) {
console.log(myVar1)
};
My webpack entry point file says:
'Uncaught ReferenceError: myVar1 is not defined'
I'm using Pug/Jade if that info helps.
You would need to define those variables on the rendered HTML page in a script tag via Pug:
script.
var myVar1 = #{myVar1};
Then you could access them like any other javascript variable client-side.

access an object previously filled by another html file

I have 2 files html (index.html and event.html).
in my index.html in my file I import a JS:
<script type="text/javascript" src="../js/events/createEventOBJ.js"></script>
and this is my js example with filled object (infact, with console.log I can see my newObj):
var newObj = [];
function getOBJ(eventObj){
newObj = eventObj;
console.log(newObj);
}
function createObj(){
return newObj;
}
now, in another html file (event.html, in which I entered with a button in the index.html file) I use this:
<script type="text/javascript" src="../js/events/createEventOBJ.js"></script>
<script>
console.log(createObj());
</script>
but it is empty, why?
And, another question is:
if in event.html I have something like this:
<div id="idevent" class="classGraph"></div>
and in createEventObj.js I use this:
var event1 = document.getElementById('idevent');
event1 is undefined, why?
Js variables (e.g. your created objects) between to html pages are independent. It means that they have different instances and you cant share object like that. If you are on index.html and you are going to another page every js variable from index.html are destroyed.
If you want to share between two pages some variables you need to use cookies or local storage or have backend to store the values.
Or you need SPA

Render HTML file content and assign it to an Object

This is what my initial js looks like
// template.js
file: {
template : '<div><h2>Template</h2><p>My paragraph</p></div>';
}
But I need to create this as a separate html file.
<!-- template.html -->
<div>
<h2>Template</h2>
<p>My paragraph</p>
</div>
Now I need to import and assign it to an object (template) of a script. Any ideas how to do this?
// template.js
file: {
template : 'Content Here';
}
You will have to get it via AJAX. This will be a pseudo-promise (see: Promise and $.get()) that is resolved with the contents of the file:
$.get(templateUrl).then(...)
So a good example would be:
// assuming `file` is inside `options`
if (options.file.template == null && options.file.templateUrl != null) {
$.get(options.file.templateUrl).then(function(html) {
options.file.template = html
// continue doing stuff with the newly received html...
});
}
Notice how I separated them into template and templateUrl, but you don't have to do that.
Note: if you try to use to use the result outside the promise's callback, you will probably get undefined when you try to access it (unless some time has passed) so you might need to organize your code to accommodate to that.

Flask -- instantiating an object from external doesn't seem to do anything

I'm just starting with Flask, so I may be overlooking something very obvious. I have loaded my javscript file with this:
<script src="{{ url_for('static', filename='Page.js') }}"></script>
then I try to instantiate an object from that js file:
<script>
var page = new Page("index");
</script>
In Page.js, I have this:
var Page = function(page) {
alert("init");
<some other things>
}
<and then some object methods Page.prototype.init_standard = function() {} etc>
The alert isn't alerting, though I am expecting it to. Also, if I put an alert before the instantiation in the HTML page, I get the alert, if I put an alert on the line after the instantiation on the HTML page, I don't get the alert. I'm not sure if this is a Flask issue or javascript -- I'm quite new at both.
EDIT: To nip this possibility in the bud, the javascript file is getting loaded according to the development server, status 304
Page.js needs to just define a function that creates the object you want. So Page() should just be a function that ends with 'return this;'. Correction returning this is not strictly required for object creation.
function Page(page) {
alert("init");
... Your code and methods...
// Example Method:
this.foo = function(param) {
... function body ...
};
return this;
}
And then you can create an object with:
var page_object = new Page("index");
page_object.foo(some_data);
I figured it out after looking at the browser debugger. It said Page was not defined. After some trial and error, I realized I can't use {{ flask templating notation inside the javascript file, probably because it isn't loaded as a template so no parsing of it in that way occurs. Anyway, I ended up just moving the {{ }} link to the html template and passing it in as an argument to the javascript.

How to cache mustache templates?

I would like to cache mustache templates.
I know that I could include mustache templates directly, like this:
<script id="mustache-template" type="text/html">
<h1>{{title}}</h1>
</script>
And call those with javascript, like this:
var html, template, data;
data = {
title : "Some title"
};
template = document.getElementById('mustache-template').innerHTML;
html = Mustache.to_html(template, data);
This won't cache templates. Only way I could figure out is usage of link -tags, but how do I call template content via javascript without an ajax request?
This won't work (of course)...
HTML
<link type="text/html" href="/mustache/template.tpl" id="mustache-template" />
Javascript
document.getElementById('mustache-template').innerHTML;
This question is very interesting! I had the same problem several months ago when I started to use mustache for 'huge' front-end templating within a rails project.
I ended up with the following solution...
Mustache templates are inside a public folder :
/public/templates/_template_name.tpl
Whenever I need a template I have this helper getTemplate that does some stuff (there's some mootools, but there are comments too):
// namespace.templatesCache is an object ( {} ) defined inside the main app js file
var
needXHR = false, // for callback function
templateHTML = ""; //template html
if(!(templateHTML = namespace.templatesCache[template_name])){ //if template is not cached
templateHTML = (this.helpers.supportLocalStorage) ? localStorage.getItem(template_name) : ""; //if browser supports local storage, check if I can retrieve it
if(templateHTML === "" || templateHTML === null){ // if I don't have a template (usually, first time), retrieve it by ajax
needXHR = true;
new Request.HTML({ //or jQuery's $.get( url /*, etc */ )
url: namespace.URLS.BASE+"templates/_"+template_name+".tpl", // url of the template file
onSuccess : function(t, e, html, js){
namespace.templatesCache[template_name] = html; //cache it
if(_this.helpers.supportLocalStorage){ //and store it inside local storage, if available
localStorage.setItem(template_name,html);
}
//call callback
}
}).get();
}else{ //retrieved by localStorage, let's cache it
namespace.templatesCache[template_name] = templateHTML;
}
}
if(!needXHR){ // I retrieved template by cache/localstorage, not by Ajax
//call callback
}
and I call this helper in this way :
namespace.helpers.getTemplate('template_name', function( templateHTML ){
// the callback function
});
You can notice that first time user needs the template, there's an asynch request (you could make a sync request if u don't want to wrap some other code inside the callback)
I hope it could help and I'd love to receive feedbacks/suggestions concerning this stuff :)
You could try to load your template in an iframe that contains an HTML page(that will be cached) with all your script tags inside.
Then you can read them from the main page, or push them from the iframe to the parent window.
That is what I do when using pure.js templates
What you say it will not work, of course, because the innerHTML attribute of the liknek element will not give you the contents of the link.
You can use Chevron to load external templates from links like so:
You add in you template a link to your template file:
<link href="path/to/template.mustache" rel="template" id="templateName"/>
Then, in you JS you can render your template like so:
$("#templateName").Chevron("render", {name: "Slim Shady"}, function(result){
// do something with 'result'
// 'result' will contain the result of rendering the template
// (in this case 'result' will contain: My name is Slim Shady)
});
The docs of Chevron will give more examples

Categories