So I'm trying to create a client-side JavaScript file for one of my .hbs templates. But it doesn't seem to even load the .js file when i add a tag in the html code. I have looked around for a solution but I can't find any clear answer for handlebars, at least not one I can understand.
I have tried:
specifying type="text/javascript"
adding the tag in main.hbs right below {{{body}}} just to see if it works but nothing happend.
Playing around with the .js file but it clearly doesn't get executed.
booking-functions.hbs
console.log("test")
document.addEventListener("DOMContentLoaded", function(){
console.log("In bookingfunctions")
// bunch of code
})
booking.hbs
<div>
<script src="../functions/booking-functions.js"></script>
// Bunch of html that works fine with handlebars
</div>
```
main.hbs
======
```
<!DOCTYPE html>
<html lang="en">
<head>
// Nothing javascript or handlebars related here
</head>
<body>
// Navbarcode and such
//Login check with #if handlebars
{{{body}}}
</body>
</html>
app.js
const path = require('path')
const express = require('express')
const expressHandlebars = require('express-handlebars')
const variousRouter = require('./routers/various-router')
const accountRouter = require('./routers/account-router')
const bookingRouter = require('./routers/booking-router')
const app = express()
//Session code here
// Setup express-handlebars.
app.set('views', path.join(__dirname, 'views'))
app.engine('hbs', expressHandlebars({
extname: 'hbs',
defaultLayout: 'main',
layoutsDir: path.join(__dirname, 'layouts')
}))
// Handle static files in the public folder.
app.use(express.static(path.join(__dirname, 'public')))
//body parser middleware
app.use(express.json());
app.use(express.urlencoded({extended:false}));
// Attach all routers.
app.use('/', variousRouter)
app.use('/accounts', accountRouter)
app.use('/booking', bookingRouter)
Related
Let's say i have a simple project, index.html and one .js file with a method:
<!DOCTYPE html>
<html lang="pl">
<HEAD>
<script src="controller.js"></script>
<meta charset="utf-8"/>
<title>Project</title>
</HEAD>
<body>
<textarea id ="someID" name = "textFieldName"></textarea>
<button onclick="showNewData()">Button</button>
<p id="score"></p>
</body>
</html>
function getText(){
value = document.getElementById('someID').value;
}
function showNewData(){
getText();
document.getElementById('score').innerHTML = "Current data: "+value;
}
I tried to do the same on localhost:3000. So i've done npm project with express and hbs dependencies. It start from server.js file:
const express = require('express');
const port = 3000;
const app = express();
app.set('view engine', 'hbs');
app.get('/', (req, res) => {
res.render('index')
})
app.listen(port);
In "views" folder i have hbs file looked the same like former index.html file but it can't use javascript method from external file. Does anyone know how to do that?
in hbs file
As far as the browser knows, it is HTML. Clients do not care, and cannot know, if an HTTP response is generated by reading a static file or dynamically with some form of server side processing.
src="controller.js"
The value of the src attribute has to resolve to a URL containing the JavaScript
app.get('/', (req, res) => {
res.render('index')
})
The only URL your web server knows about (and so will provide anything other than a 404 error for) is /.
If you want /controller.js to provide a JS file then you need to write code to make that happen.
How to handle static files is covered in the Express Getting Started Guide.
index.html
<head>
<script src="/main.js"></script>
</head>
Error:
GET http://localhost:3000/main.js
Structure
Project
app.js
view
index.html
main.js
I've tried src="main.js". /view/main.js
Very basic, but dont want to get stuck on this any longer... sigh.
if it helps my app.js file has this:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/view/home.html');
});
So, according to your comments - you are serving only the 'index.html' file instead of whole directory.
Try this code:
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'view')));
//... other settings and server launching further
If you want to set serving static files to particular route - extend 'app.use' line with '/your-route', like this:
app.use('/your-route', express.static(path.join(__dirname, 'view')));
After that you can use <script src="main.js"></script> in your index.html
I'm using back4app BaaS service that uses Parse-Server. For the ClientSide I'm running AngularJS with html5Mode(true);
My problem is that this is NOT working: http://app.rizop.tv/dashboard
While this is working right: http://app.rizop.tv
Any idea how to fix expressJS to handle my routes in the right way?
I have this config:
cloud\app.js
// Helper modules that will be used
var path = require('path');
var bodyParser = require('body-parser')
// This imports the Router that uses the template engine
var index = require('./routers/index');
// Sets the template engine as EJS
app.set('view engine', 'ejs');
// This defines that the 'views' folder contains the templates
app.set('views', path.join(__dirname, '/views'));
// These options are necessary to
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// This bind the Router to the / route
app.use('/', index)
// Starts listening in the routes
app.listen();
cloud\routers\index.js
// Importing express
var express = require('express');
// Creating a Router
var route = express.Router();
// Defining a route that binds the GET method
route.get('/', function(req, res) {
// This is the code that renders the template
res.render('index', {testParam: 'Back4Apper'});
});
module.exports = route;
cloud\views\index.ejs
<!doctype html>
<html>
<head>
<meta charset="utf-8">
...
</body>
...
</body>
</html>
Here is my app structure:
You can make it work by making little changes in app.js and root html file
I assume you already defined $locationProvider.html5Mode(true); where you defined your routes. Then define base href in your index html
<head>
<base href="/">
...
</head>
This answer might be helpful to configure your server
The file at cloud/app.js should not have app.listen() on its final line, due to the fact that you are using Cloud Code. Can you please try that?
I have ran into the same problem and did the following
I've put this route as the last option, so when the express router ran out of options it will render the index file where is the angular app. Angular internal router will resolve that route and draw the view.
router.get('*', function (req, res) {
res.render('index', {testParam: 'Back4Apper'});
});
Obviously you can write a smarter regex instead of * according to your needs but you get the idea.
This is not a question about express.static()
I have a application where I need to serve multiple pages which have same js and css dependencies. Hence, writing css and js includes using <script> or <link> tags on every single page is bad practice.
I am looking for a look alike php include way to do it. As php would process all php code and send compiled html, I think same could be done with js on node server.
So a server would do kinda like below:
get html from a resources.html
push above html to index.html
send index.html
Or perhaps there could be other way around. Any idea?
You can use layouts with your chosen template engine and each view can extend that layout. For example, if you're using Jade as your template engine.
index.js
var express = require("express");
var app = express();
var port = process.env.PORT || 7080;
app.set('view engine', 'jade');
app.get('/', function (req, res) {
res.render('home');
});
app.listen(3000);
views/layout.jade
doctype html
html
head
script(src='/javascripts/home.js')
link(rel='stylesheet', href='/stylesheets/style.css')
block title
title= "My Website"
body
.container
block content
views/home.jade
extends ./layout.jade
block content
h1 Hello World!
The home.jade view extends the layout and overrides the content block. Visiting http://localhost:3000/ returns the following:
<!DOCTYPE html>
<html>
<head>
<script src="/javascripts/home.js"></script>
<link rel="stylesheet" href="/stylesheets/style.css">
<title>My Website</title>
</head>
<body>
<div class="container"><h1>Hello World!</h1></div>
</body>
</html>
Make a public folder in your root directory
then in main app.js/server.js
add the following line :-
`var express = require('express'),
bodyParser = require('body-parser'),
userRoutes = require('./routes/user'),
mongoose = require('mongoose');
var app = express();
mongoose.connect('mongodb://localhost/meanDemo');
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.use(express.static('public'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use('/', userRoutes);
app.get('/',function(req, res){
res.render('userlist');
});
app.listen(3000);
console.log("sever started at 3000");
`
Then in views use /*filename to / will be your public directory
I'm taking a course (on MEAN) and it starts by trying to get something running end-to-end. The point now is to add in the Javascript necessary to make Angular work. I'm having some kind of simple problem including the scripts.
The error I'm getting is (firebug), which appears to complain about the entire index.html file, is:
The Jade code is short. It is an index.jade file which extends a layout.jade file which includes in all the js files:
extends ../includes/layout
block main-content
section.content
div(ng-view)
h2 some regular text 5
This produces the following index.html file:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/bootstrap.css">
<link rel="stylesheet" href="/vendor/toastr/toastr.css">
<link rel="stylesheet" href="/css/site.css">
</head>
<body ng-app="app">
<script type="text/javascript" src="/vendor/jquery/jquery.js"></script>
<script type="text/javascript" src="/vendor/angular/angular.js"></script>
<script type="text/javascript" src="/vendor/angular-resource/angular-resource.js"></script>
<script type="text/javascript" src="/vendor/angular-route/angular-route.js"></script>
<script type="text/javascript" src="/app/app.js"></script>
<section class="content">
<div ng-view></div>
<h2>some regular text 5</h2>
</section>
</body>
</html>
================ UPDATE ========
It appears Node is substituting the index.html file for the assets. The project directory structure is:
The server.js file which node runs is:
var express = require('express');
var stylus = require('stylus');
// set env variable to determine if in production or development mode; this contains environment if set my MODE
var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
// create express application
var app = express();
function compile(str, path) {
return sytle(str).set('filename', path);
}
// configure express
//app.set('views', __dirname + '/server/views');
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(stylus.middleware({
src: __dirname + '/public',
compile: compile
}));
console.log("dirname:" + __dirname);
app.use(express.static(__dirname + '/public'));
//app.use(express.static(path.join(__dirname, '/public')));
app.get('/partials/:partialPath', function(req, res) {
res.render('partials/' + req.params.partialPath);
});
app.use(express.logger('dev')); //- logger no longer bundled with Express
app.use(express.bodyParser());
// add routes:
// We won't tell the server specifically what routes to handle. We'll have the client-side be
// responsible to server up and 404 notices. Client-side will have to specify all routes.
// Other solution is to coordinate your routes, so that every client route is also listed on the server.
// Far more customary to have a server side have a catch all that lists up a 404 page.
app.get('*', function(req, res) {
res.render('index');
})
var port = 3030;
app.listen(port);
console.log("listening on port: " + port + " ...");
This looks like a path issue as the page is not able to access your assets directory. Make sure your public folder is set right in your node server code. It should be along the lines of app.use(express.static(path.join(__dirname, 'public_folder_name')));. Looking at your folder structure, your server.js is nested in server folder and not at the same level as your public folder. Try app.use(express.static(__dirname + '/../public'));