How to use javascript methd from external files in hbs file - javascript

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.

Related

Cant find embedded script in HTML in nodemon

I am a newbie, experimenting with JS. I was trying to build a small Node.js app, with a JS script embedded in the index.html, but when I run nodemon, it returns 404 for the script and cant find it. The same html page with embedded script works fine with parcel. What am I doing wrong?
My app.js :
const express = require('express')
app = express()
app.get('/', (req, res, next)=>{
res.sendFile('D:/Node.js Folder/My first project/views/index.html')
})
app.get('/add-user', (req, res, next)=>{
res.sendFile('D:/Node.js Folder/My first project/views/add-user.html')
})
app.get('/show-user', (req, res, next)=>{
res.sendFile('D:/Node.js Folder/My first project/views/show-users.html')
})
app.listen(3000)
HTML File :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body class = "text-gray-400">
<div>
<div class = "text-3xl">
<nav>
<h1>
Hello! Welcome to the first page!
</h1>
<h1 class = "chat-notification-title">
Hello! Welcome to the first page!
</h1>
<form>
<label for="cname">Company Name</label><br>
<input type="text" id="cname" name="cname"><br>
<label for="ccode">Company Code</label><br>
<input type="text" id="ccode" name="ccode">
</form>
<button class ='btn-submit' type = "submit">Add Record</button>
</nav>
</div>
</div><script src="../controller/controller-1.js"></script>
</body>
</html>
Embedded Script :
'use strict'
console.log(document)
const button = document.querySelector('.btn-submit')
console.log(button)
button.addEventListener('click', function () {
console.log('BUTTON PRESSED')
alert("Pressed")
})
One thing you need to do is stop using absolute paths
for eg. 'D:/Node.js Folder/My first project/views/index.html'
should be ./views/index.html
assuming that the app.js file is in the same folder as the views folder.
The server on which you might deploy this code is not going to have the same path as your pc.
You also might wanna make a static folder and move your html, script (controller) folder inside that
and add the following line to the app.js
app.use('/', express.static('static'))
// or
app.use('/', express.static('./static'))
this way you won't have to serve the individual files like you are doing right now.
if you have the src for the embedded file set to ./controller/controller-1.js it will work fine.
I solved it by adding this to my app.js :
app.get('/controller/controller-1.js', (req, res, next)=>{
res.sendFile('D:/Node.js Folder/My first project/controller/controller-1.js')
})
Help from this thread : How to include javascript on client side of node.js?
Is there a better way to do this?
Nodemon are supposed to be used on the server side, often running an express or similar server.
parcel serve is what you are supposed to use on the client side (without server), to serve the html files directly.
You should also not use paths to your own disk. Luckily when the project is running it creates a dist folder with the same files. You are meant to link those to paths in code. Ie on res.sendFile you should write res.sendFile(path.resolve("../client/dist/index.html")) or res.sendFile(path.resolve("../dist/views/index.html))
You import path as import * as path from "path"
If you want to use it with a server, then you should do this:
Client json "dev" should parcel watch index.html, and server "dev" should nodemon server.js.
Both these scripts are supposed to be run in the root package.json file, with concurrently, allowing them to run simultaneously
"dev": "concurrently npm:server:dev npm:client:dev",
"server:dev": "cd server && npm run dev",
"client:dev": "cd client && npm run dev",
In the server file, you should then do something like this:
import express from "express"; //import express
const app = express(); // use express
app.use(express.static("../client/dist/")); // allows express to server static files
app.use((req, res, next) => {
if (req.method === "GET" && !req.path.startsWith("/api")) {
return res.sendFile(path.resolve("../client/dist/index.html"));
} else {
next();
}
}); // checks if url is trying to reach an api, if not it returns the file you are looking for
const server = app.listen(process.env.PORT || 3000, () => {
console.log("Server started on http://localhost:" + server.address().port);
}); // starts server and logs the localhost url
You are then meant to access your site from the server side, and every time you change the server, nodemon will restart the server for you, and every time you change the client, parcel will do the same

Rendering HTML file with res.sendFile() in Express.js

I'm trying to render my HTML file with some a local CSS file, local JS file and two remote files as links
but all I got is a plain HTML in the browser
here is the top of my HTML file (index.html):
<script src="src/drawflow.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="src/index.css" />
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
/>
This is my server code (app.js):
"use strict";
const express = require("express");
const path = require("path");
const app = express();
app.use(express.static(__dirname + "/src"));
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname + "/index.html"));
});
app.listen(process.env.port || 4000, () => {
console.log("listening to port 4000...");
});
and here is my file structure:
file structure
The index.html file is working just fine when opened in the browser but it can't be fetched properly from the server.
Any ideas ?
Thanks to the comment by Chris Short
I replaced
app.use(express.static(__dirname + "/src"));
to
app.use('/src', express.static(path.join(__dirname + '/src')));
and it worked perfectly.
Thanks a lot.
If I'm understanding correctly. The assets for your HTML file are not being fetched properly, so your HTML is showing as bare when you access through the browser. With this understanding, the reason your assets are not loading properly is due to the way your app.js is set up.
Currently you are trying to access href="src/index.css" in your header, however all of your assets are going to be found from your website root. Expressjs handles all app.use statements as middleware and by default are attached to the root of your website. If you would like to have this accessible from "src" then you will need to set up your express.static a bit differently like so.
app.use("/src", express.static(path.join(__dirname, "/src"));
See the below for more info
https://expressjs.com/en/starter/static-files.html
https://expressjs.com/en/guide/using-middleware.html

How to serve html in express.js that references js file from server and run it on client side?

I'm trying to write simplest possible server that serves html page with client side scripts.
Already tried based on http://expressjs.com/en/starter/static-files.html,
Using express.js to serve html file along with scripts, css, and images and
How to load JS file in html using express server, but still I don't get it.
File structure I'm using:
node_modules
resources
resources/page.html
resources/script.js
index.js
package.json
index.js:
const express = require('express');
const app = express();
const port = 3000;
const path = require('path');
app.use(express.static(__dirname + '/resources'));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname , 'resources', 'page.html'));
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
page.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body>
Content
</body>
<script scr="script.js"></script>
</html>
script.js:
var i = 0;
setInterval(() => {
if (i < 10) {
console.log(i);
i++;
}
}, 100);
I type in google chrome browser address localhost:3000/ and page is successfully loader ("Content" string is displayed), but script script.js is not running (empty console). I expect browser to retrieve script.js file and print numbers to console when page.html is loaded.
In the page.html file, change the property scr to src in the script tag and it will work.

Why am i getting a 404 js file, while including a script tag?

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

javascript not loading in HTML file - nodejs + expressjs

I am new to nodejs and expressjs so Im trying to build simple web app to grasp both frameworks.
Here I have built a project with the following architecture:
js
test.js
views
index.html
server.js
my server file looks like this:
var fs = require("fs");
var host = "127.0.0.1";
var port = 1337;
var express = require("express");
var ejs = require("ejs");
var server = express();
server.use(server.router);
server.use(express(__dirname));
server.set('view engine','html');
server.engine('html', require('ejs').renderFile);
server.get("*", function(request, response){
response.render('index.html');
});
server.listen(port, host);
and my index file like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Starter Template for Bootstrap</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script language="javascript" src="/js/test.js" type="text/javascript"></script>
</head>
<body ng-app>
<div class="container">
<div class="starter-template">
some code
</div>
</div><!-- /.container -->
</body>
</html>
My index.html file loads properly but I cannot get the test.js file to load. How can I fix this?
Use express.static built-in middleware function in Express.
Add this line after server.engine. This mechanism should allow static files to be served e.g. images, javascripts, css
app.use(express.static(__dirname + '/js'));
Now you can load:
http://localhost:1337/js/test.js
change render into sendfile and move your js folder to public folder then add this middleware
server.use(express(__dirname+'/public'));
JS files are rendered as static files.
Ref: https://expressjs.com/en/starter/static-files.html
First create a folder "static" and keep .js files in it.
Now, correct the script tags of these .js files in .ejs file.
in the nodejs side :
var path = require("path");
app.use(express.static(path.join(__dirname + '/js')));//middleware
in the HTML page :
<script src="./my_script.js"></script>
As this files is static, you should add the entire root directory to 'app'.
Like this:
app.use(express.static(path.join(__dirname, '/')));
So that you can quote all of your files by relative path.

Categories