How to trigger onclick function in router for PugJS? - javascript

I'm currently using a expressJs template that uses pug in order to make a simple website. On the site is a button. I want on the click of the button to call a function in the index.js file.
Originally I had the code like this. In the index.pug file:
extends layout
block content
h1= title
p Welcome to #{title}
button#BubbleButton.button.hypeButton.button-3d.button-caution.button-circle.button-jumbo(onclick = 'buttonClick()') Click
In my index.js file, it would look like so:
var express = require('express');
var router = express.Router();
var PubNub = require('pubnub');
module.exports = router;
function buttonClick(){
alert('test');
}
However, I would get a response along these lines:
buttonClick function not found.
I'm frankly more familiar with angular than pug. What does it take to link up the view side to the router file? I understand in Pug, you can add an endpoint REST API style, but this isn't necessarily going to be an API. I may just want to show something simple and not expose it. However, I may be misunderstanding something fundamental.
Thanks!

The JavaScript code contained in the script. tags in your pug file will only run in the browser, and the code in index.js will only run on the server. Therefore they can never speak directly.
You need an ajax call on the client (i.e. in your pug file). Here's an example using jquery but you can use one of the many ajax client packages out there to do the same thing:
script.
function onButtonClick(){
$.ajax({
"url": "/service",
"method": "POST"
});
}
Then you need a route handler in index.js:
router.post('/service', function(req, res){
console.log('test');
});
Note that this will output to the console on the server, not the client. I believe that's what you want to do.
To add jquery to your page you can use a cdn (Content Delivery Network) to quickly bring it into your code. Here is the pug syntax for that:
script(src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous")
Alternatively you could you axios as a lightweight alternative to jquery, all it does is ajax:
script(src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js" integrity="sha256-mpnrJ5DpEZZkwkE1ZgkEQQJW/46CSEh/STrZKOB/qoM=" crossorigin="anonymous")

Related

How to pass data from nodejs to inside html script tags

I'm using expressjs as a server on 8000 port. I want to send a string value from expressjs file to html script tags and use this string value in script tags.
name variable is coming as a empty string now.
How can i console.log name variable's value?
static-pages-server.js:
app.get('/index', function(req, res) {
var name = "hello";
res.render(__dirname + "/static-pages/journey-analize-report/index.html", {name:name});
});
index.html:
<script type="text/javascript">
console.log(name);
</script>
Edit : I used ejs and now problem is how should i describe name attribute in script tags? Below code is giving syntax error.
<script type="text/javascript">
console.log(<%=name%>);
</script>
Express.js itself is a backend server. If you would like to have dynamic HTML files you need to use templates engines.
Please follow this document -> https://expressjs.com/en/guide/using-template-engines.html
Eventually, you will realize you will need a frontend framework to write your code faster with good quality. So also recommend you to take a look at some of the frameworks like React, Vue.js. If you need Single Page Applications you only use express.js to provide data not to render HTML. If you need Server-side rendering it is good to investigate Next.js, Nuxt.js.
You cant directly inject variables into a html file in nodejs . That is why you have templating engines in express. Check out ejs.
It would allow you to pass data directly from your routes into the page you are rendering.
Local variables sent to a view via the locals parameter using the res.render() method aren't directly accessible. Instead you need to refer to those using it's variable name wrapped inside double curly brackets. So if you want to use it inside a JavaScript function, you need declare a local variable and give it the content of your name local.
Simply modify your index.html like this:
<script type="text/javascript">
let name = "{{name}}";
console.log(name);
</script>
here is the answer How do I use HTML as the view engine in Express?
what you will need is a view engine package in your app. there are many view engines currently available.
then set that view engine in express app. Trigger the view render via a call from your route’s response like you have done above.
Then in your view render the html output using the view variables and if these variables are outputted into html you can use them in your in browser JavaScript. You can also call a service in your html sending the dynamic data as well.
check out esj or pug (ps pug is my personal favourite )

Basic html engine in Node

I want to write my HTML in HTML. Not some fancy way. The only thing that would be cool is to be able to use some sort of include statement to include header/navigation/footer for each page.
I've looked at pug, ejs, mustache, nunchuck, etc etc. I hate all of these things. I just want to write HTML..
What is a simple node module to do this? And how do I set up the render engine in my main app.js? I am using express
You can just set up your express routes to connect with html pages. Here's a simple example:
var express = require('express');
// Create express app
var app = express();
// Route index page to an index html page
app.get('/', function(req, res){
res.sendFile(__dirname + '/path/to/views/index.html');
});
// Create server
app.listen(8080, function(){
console.log('Ready on port 8080...');
});
As a side note, ejs is basically html but with some bonus functionality. You can totally get away with writing only html in ejs pages and then start using the ejs features when you get comfortable with it.
Looks like you want to server only static html files using node not some jsp equivalent dynamically generated html.
Express has support for serving static files and you do not need to define any routes for that!
http://expressjs.com/en/starter/static-files.html
Second thing I understood from your post is you want to include some common html to your html page. One way of doing that is to use a browser/client side java script framework. Take a look at angular.js. It has ng-include. Basically you can include one html file to another using that.

Jade: load external javascript and call function

I was learning Express/Node/Jade and now in the Jade file I want to include a javascript file from the public folder just for the page.
For example, in jade file I type this:
script(src='/javascripts/test.js')
and inside test.js I have a function
function check_test(){
return "It's working!"
}
then I try to call the function in Jade by
- var test_response = check_test()
than I got the error saying that "undefined is not a function" and test.js isn't load at all.
Apparently Jade doesn't load the file, they only transform into HTML code.
I look someone else's question and this is the closest one I can found but it doesn't provide a clear answer of what to do.
In Jade, how can you call a function in an external Javascript
So my question is: In this case what should I do to make it work?
I don't want to load the file in layout.js since I only want test.js only be use by this page.
Well... In the first instance, it is different what happens in the browser of what happens on the server. So Jade is a rendering of HTML, therefore if you are in the browser. It's what ExpressJS shipping, ie rendering Jade. If you want to call, your HTML Javascript (Rendering of Jade), should show you where the Javascript. For exmaple
in Server.js
// Get the Javascript in the browser
app.use("/javascripts", express.static("./outJavascripts"));
// Get the URL
app.all("/", function(req, res){
// Render the Jade and Send for the client (Browser)
req.render("myTemplate.jade");
});
In myTemplate.jade
script(src='/javascripts/test.js')
In "./outJavascripts/test.js"
function check_test(){
console.log("It's working! :D");
return "It's working!";
}
If you do this, you will realize that it is run, the file "./outJavascripts/test.js" in the browser. And the function "check_test" never run in the server.
Or put all folders in a common folder, for example public
public
-javascripts
-stylesheets
-images
and then expose that public folder
app.use(express.static(path.join(__dirname, 'public')));
which means you can
script(src='/javascripts/script.js')
link(rel='stylesheet', href='/stylesheets/style.css')
Save your JS file and link it in your Jade file as:
script(src="filepath/yourJSfile.js")
Then call the function, I'm using a button here for example:
button(class="btn", onclick='functionName()')

bootstrappedUser - Jade or EJS to HTML

I've been doing some guide on Mean stack and I came to a point where I'm currently stuck.
Following this guide, I have created a simple authentication where I'm able to log in using Passport JS. Whatsoever, each time when page refreshes, the authentication gets restarted (client doesn't recognise it anymore).
Since this is suppose to happen in the guide and we are about to fix it, guide said the following.
1. Create a Jade file and insert this:
if !!bootstrappedUser
script.
window.bootstrappedUserObject = !{JSON.stringify(bootstrappedUser)}
I've tried this in my html file but it doesn't work:
<script type='text/javascript'>
if (bootstrappedUser != "undefined" ){
window.bootstrappedUserObject = JSON.stringify(bootstrappedUser);
}
</script>
Getting the error: Uncaught ReferenceError: bootstrappedUser is not defined
even though I have created the variable in my backend js file and assigned req.user to it.
I'm suppose to have this file included in my main layout (index.html). The problem is that I'm not using Jade as template engine but plain HTML and I don't know how to transform this code up there to work as simple HTML in my index.html.
It seams that this statement up here only initialise when user hits the login button. Does anyone have any idea or solution how to write the above code in plain HTML.
I browsed StackOverflow and found almost similar problems but not similar enough.
Thanks in advance,
Aleksandar
bootstrappedUser is a variable passed by server-side code to Jade compiler which injects it into the HTML while compiling. If you plan on writing the HTML yourself you can not inject variables from server-side code, obviously because HTML is just a static markup. You'll probably have to get that variable at the client-side from the server yourself via ajax or something.
Via Angular controller let's say ?
You can first define a route on server that serves the variable you want
app.get('/bootstrappedUser', function(req, res){
if(req.user)
res.json(req.user);
else
res.status(401).end();
});
Then on client-side angular you can perform an http request and get that variable
$http.get('/bootstrappedUser')
.success(function(data, status, headers, config) {
$scope.bootstrappedUser = data;
});

Load an Ember.js app from another website

I'm working on a project where I'd like to load an Ember.js application from another website, hosted on a different server and using a different domain name. In other terms, I'd like to include an Ember app in other website like I would do with an iFrame, but without an iFrame.
I built my Ember.js application using Yeoman and the Ember generator.
In the origin website, I just have a simple markup like this:
<body>
<h1>My website</h1>
<p>Lorem ipsum...</p>
<div id="myEmberApp"></div>
<p>Lorem ipsum...</p>
</body>
I know how to call an external JS file, but don't know from here how to execute or to load my Ember.js app. I tried also with CORS, but I don't think it will suit my needs.
For the records, I can't use an iFrame. On the origin website, I don't want to have any dependencies against jQuery or whatever. In the future, I'd like to be able to offer a step by step how-to to integrate this app on any websites.
Is there any solution? Or should I have to plan to do my app in full JS without Ember.js?
Let me know if you need more information.
Thanks in advance
--- Edit ---
Here's how I call my JS file from the origin website:
<!-- The JS script to be included by the client -->
<script>
(function () {
var eh = document.createElement('script');
eh.type = 'text/javascript';
eh.async = true;
eh.src = '//localhost:9000/scripts/edenhome.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(eh, s)
})();
</script>
I hope this helps.
Perhaps I am missing something, but why not just include your application in a script tag? I'm not familiar with the yeoman generator, but most of these build tools kick out an ember application with templates precompiled into JavaScript functions and then all your files concatenated together in a single file.
For example:
// this would be the precompiler output generated by yeoman, not exactly like
// this, but same idea, the template is part of the JS file
Ember.TEMPLATES['application'] = Ember.Handlebars.compile('<h1>I am an ember app</h1>');
// make an app and set the rootElement
var App = Ember.Application.create({
rootElement: '#myEmberApp'
});
You can see here I'm loading in the ember app from a different domain:
http://emberjs.jsbin.com/mawuv/1/edit
edit follow up
Injecting the script works just as well as a script with a src attribute:
http://emberjs.jsbin.com/mawuv/2/
I would suggest the following,
disclaimer: i have not actually tried what you are asking, but i do usually load everything from separate files but within the context of the same domain.
create a function that loads all templates and appends them to the document.
create a function that runs the complete ember.js app.
create the file that will be referenced by the remote site and will search for a specific element (this could also be parametrized / be a jquery plugin etc) and once found loads all templates calling function from (1) and start the application calling function from (2) with rootElement the specific element mentioned earlier. (Prior to any of the previous loadings, all dependencies of the ember.js app should be loaded e.g. jquery, handlebars.js, ember.js etc. probably in a no conflict state)
All ajax requests to the server from the ember app should be carried out using jsonp.
simplified example,
http://emberjs.jsbin.com/nelosese/1/edit
js
/*it is possible to load templates from independent files, using promises, however here it is just demonstrated the loading of templates*/
/*a callback is added since they are loaded async and only when this is done should the app complete initialization */
function initTemplates(callback){
var templates ='<script type="text/x-handlebars"><h2> Welcome to Ember.js</h2>{{outlet}}</script><script type="text/x-handlebars" data-template-name="index"><ul>{{#each item in model}}<li>{{item}}</li>{{/each}}</ul></script>';
$('body').append(templates);
callback();
}
function initApp(){
App = Ember.Application.create({
rootElement: '#myEmberApp'
});
App.Router.map(function() {});
App.IndexRoute = Ember.Route.extend({model: function() {
return ['red', 'yellow', 'blue'];
}
});
}
/*a reference to your bootstrap script, that executes the following*/
$(document).ready(function(){
if($('#myEmberApp').length>0){
$.get("/",function(){initTemplates(function(){
initApp();
});});
}
});
html
<body>
<div id="myEmberApp"></div>
</body>

Categories

Resources