Can't display an image with EJS file in node.js - javascript

i'm new to node.js and my just playing with it to make a website. I want to display a picture on the website and that picture is in the same directory as my ejs file, but it does not show up.. Am i doing something wrong ? Thank you !
Backend code
const express = require('express')
//Init App
const app = express();
//Load view engine
app.set('view engine','ejs');
// Home route
app.get('/', function(req,res){
res.render('index.ejs');
});
app.listen(3000, function(){
console.log('Server started in port 3000...');
});
ejs file content:
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Picture test</h1>
<img src="/Users/aray/Documents/Projects/Node/views/test.jpg">
</body>
</html>
The project strcture is :
- Node
- app.js
- views
- index.ejs
- test.jpg

you have to put your images (and other assets) in separate folder and serve this folder with express.static:
app.use(express.static('public'));
- Node
- app.js
- views
- index.ejs
- public
- test.jpg
<img src="test.jpg">
further information can be found in the express documentation: https://expressjs.com/en/starter/static-files.html

Related

Problem with sending static js files to client browser with express.js

I want to develop a very basic blog app with express.js and I was trying to create a webpage where I could write a post from the browser and store it into a db after submitting it.
By searching on the internet I came upon the ckeditor package, which would allow me to format my blog post before submitting it to the database. I read the documentation and tried to integrate the package in the html code together with the javascript scripts necessary to load the software.
However, when I load the new_post page in my browser I see that the browser is not loading correctly the ckeditor even though I am serving the javascript script necessary to run it as a static resource through the express.static method.
Here you can find the necessary info to check my issue:
Project Structure:
project structure
app.js
const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const app = express();
const PORT = 5000;
const newPostRouter = require(".\\routes\\new_post.js");
app.set("view engine", "ejs");
app.use("/public", express.static(path.join(__dirname, "public")));
app.use(bodyParser.urlencoded({ extended: false }));
//Homepage
app.get("/", (req, res) => {
res.render("homepage", { title: "My Express App", message: "Hello World!" });
});
//Write a new post
app.use("/new-post", newPostRouter);
//Listener
app.listen(5000, () => {
console.log(`Server listening on port ${PORT}...`);
});
routes/new_post.js
const express = require("express");
const router = express.Router();
const path = require("path");
router.get("/", (req, res) => {
res.render("new_post");
});
router.post("/", (req, res) => {
const title = req.body.title;
const content = req.body.content;
res.redirect("/");
});
module.exports = router;
views\new_post.ejs
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.ckeditor.com/ckeditor5/35.4.0/classic/ckeditor.js"></script>
</head>
<body>
<img src="..\public\dog-img.jpg" alt="derp" />
<h1>Classic editor</h1>
<div id="editor">
<p>This is some sample content.</p>
</div>
<script
src="..\public\js_scripts\new_post.js"
type="application\javascript"
></script>
</body>
</html>
public\js_scripts\new_post.js
ClassicEditor.create(document.querySelector("#editor")).catch((error) => {
console.error(error);
});
As you can see I am trying to send the static resources to the client browser by using the express.static method in the app.js file. However when I try to load the page in the browser, this is the result I get:
result 1
The dog-img.jpg, also contained in the public folder, is correctly sent to the client yet the javascript file new_post.js is not.
I've also tried to modify the ejs file by substituting the script tag with
<script>
ClassicEditor.create(document.querySelector("#editor")).catch((error) => {
console.error(error);
});
</script>
When I do this the editor correctly loads in my browser:
result 2
Since I am trying to follow the best practices I'd like to keep my js files separated from the html/ejs files and therefore I'd like to call the scripts from an external source and not internally.
Can anybody help me understand what is wrong with my code?
In app.js you need to write
app.use(express.static(path.join(__dirname, 'public')));
code to access all data inside the asset folder.
then you need to simple add or load this inside your .ejs file.
<img src="/images/img1.jpg" alt="" srcset="">
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src='/javascripts/index.js'></script>
For More Details Please visit this link Serving static files in Express

Unable to load CSS file within nodeJS app

I have an app that I followed from a tutorial for the backend in nodeJS and Express. My connection to MongoDB via Mongoose is working. However, I've been trying to add a front-end- at the moment- just a simple html/ejs/css form. My endpoints are loading in localhost but only the html/ejs is rendering. My css file shows as plain code at http://localhost:3000/styles.css but isn't loading so I'm just getting plain html/ejs. I'm using VS Code. Here's my relevant code:
App.js:
const express = require('express');
const bodyParser = require('body-parser');
const product = require('./routes/product.routes'); // Imports routes for the products
const app = express();
var path = require('path');
const cors = require('cors');
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cors({
origin: '*'
}));
app.use(express.static(path.join(__dirname, '/public')));
app.use(express.static(path.join(__dirname, 'views')));
app.use("/styles", express.static(__dirname + '/styles'));
app.use('/product', product);
let port = 3000;
app.listen(port, () => {
console.log('Server is up and running on port number ' + port);
});
Product.routes.js
const express = require('express');
const router = express.Router();
// Require the controllers WHICH WE DID NOT CREATE YET!!
const product_controller = require('../controllers/product.controller');
// a simple test url to check that all of our files are communicating correctly.
router.get('/', product_controller.start);
router.get('/test', product_controller.test);
router.post('/create', product_controller.product_create);
router.get('/:book', product_controller.product_details);
router.put('/:book/update', product_controller.product_update);
router.delete('/:book/delete', product_controller.product_delete);
module.exports = router;
Product.controller.js
const Product = require('../models/product.model');
//Simple version, without validation or sanitation
exports.start = function (req, res) {
res.sendFile('index.html', { root: './views' })}
exports.test = function (req, res) {
res.render('index.ejs', { root: './views' })}
Index.ejs
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>HTML 5 Boilerplate</title>
<link rel="stylesheet" type="text/css" href='/public/styles.css'/>
<base href="/">
</head>
<body>
<h1>BookBooker</h1>
<h2>A library app for personal use.</h2>
<form action="/create" method="POST">
<input type="text" placeholder="Writer" name="name" />
<input type="text" placeholder="Book" name="book" />
<button type="submit">Submit</button>
</form>
<script src="app.js" type="module" type='text/javascript'></script>
</body>
</html>
My file structure looks like:
CRUD folder
-app.js
-package.json
-package-lock.json
-controller folder
--product.controller.js
-public folder
--styles.css
-routes folder
--product.routes.js
-views folder
--index.html
--index.ejs
Apologies if it's obvious- I'm super new to this. As you can see, I've tried static files, paths, CORS, and lots of combinations of file routing but I'm getting myself in a big muddle. I've considered caching but the css isn't showing in Chrome, Edge or Incognito mode either. Any help would be appreciated.
Instead of
<link rel="stylesheet" type="text/css" href='/public/styles.css'/>
write
<link rel="stylesheet" type="text/css" href='/styles.css'/>
The public folder name is not part of the stylesheet URL, it is just the folder where express.static looks for files.
The CSS showing as plain text may be caused by a wrong Content-type in the header. The browser is interpreting it as a plain text file, instead of handling it as CSS. Before you send the response, you can set response headers in your controller like:
res.header('Content-type', 'text/css');
See Express Docs
Hope this helps.

How to use a function of nodejs to use in a button in html for use joohny five?

I create a server using nodejs with express
server.js
const express = require('express');
const app = express();
const path = require('path');
const router = express.Router();
router.get('/',function(req,res){
res.sendFile(path.join(__dirname+'/index.html'));
//__dirname : It will resolve to your project folder.
});
//----------------------------------------------------------------------
//add the router
app.use(express.static(__dirname + '/View'));
//Store all HTML files in view folder.
app.use(express.static(__dirname + '/Script'));
//Store all JS and CSS in Scripts folder.
app.use('/', router);
app.listen(process.env.port || 3000);
And use html with javascript.
index.html
<html>
<head>
<meta charset="utf-8"/>
</head>
<link rel="stylesheet" href="./index.css">
<script type="text" src="./server.js"></script>
<script src="./index.js"></script>
<body>
<h1>Automatico</h1>
<button onclick="autohabilitar();">Habilitar</button>
<button onclick="autodeshabilitar();">deshabilitar</button>
<br>
<h1>Foco-1</h1>
<button onclick="f1habilitar();" id="f1h">Habilitar</button>
<button onclick="f1deshabilitar();"id="f1d">deshabilitar</button>
</body>
</html>
index.js
document.getElementById("f1h").disabled=true;
document.getElementById("f1d").disabled=true;
}
function autodeshabilitar(){
document.getElementById("f1h").disabled=false;
document.getElementById("f1d").disabled=false;
}
function f1habilitar(){
document.getElementById("f1h").disabled=true;
document.getElementById("f1d").disabled=false;
}
function f1deshabilitar(){
document.getElementById("f1d").disabled=true;
document.getElementById("f1h").disabled=false;
}
I need the function
function apagarf1(){
led1.off();
}
located in server.js for use in onclick of the button...
I tried export the function, import the script in the html, use johnny-five in another script...
I’m not super familiar with Johnny 5. But I do know you can’t access node.js specific stuff from the browser.
Your best bet will be to set up a basic api endpoint in express that you call from your front end code. When that endpoint gets hit you can trigger your nodejs function to turn the led off.
In your server file add this:
app.get('/led-off', (req, res) => {
apagarf1()
return res.send('LED off');
});
On your front end make a fetch() call to that endpoint and that should work.

Setting up the directory management in Express Handlebars

I use NodeJs, Express and Handlebars.
My server file app.js
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
app.engine('handlebars', exphbs({defaultLayout: 'index'}));
app.set('view engine', 'handlebars');
app.get('/start', function (req, res) {
res.render('start'); // render the "start" template
});
app.listen(8888, function () {
console.log('Server running on port 8888');
});
So when passing in the route localhost:8888/start there should be my index.handlebars
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Foo</title>
</head>
<link href="../../CSS/requirements.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<body>
<p>TEST - This is on all pages</p>
{{{body}}}
</body>
</html>
and the template to load (start.handlebars)
<script src="../Client/start.js"></script>
<p>Template 1 is active</p>
My directory structure
When running the server, my route is loading fine but the problem is, that the browser is not able to find the script and css files.
I checked my paths but I think they might be correct. Am I wrong?
You have to set static folder in your express app. Add following middleware
app.use(express.static(path.join(__dirname, 'public')));
right after
app.set('view engine', 'handlebars');
Create a public folder at your root level and move your Client and CSS folder in that public folder.
Ref: Link

Implement Posted Form from NodeJS into HTML

I recently switched from starting to learn PHP to NodeJS since I have more knowledge in JS. My question is how do I display posted form data into a HTML File?
server.js
const app = require('express')(),
bodyParser = require('body-parser'),
path = require('path');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.get('/', (req, res) => res.sendFile(path.join(__dirname, 'html/index.html')));
app.post('/student', (req, res) => res.send(req.body.user.name));
app.listen(3000, (req, res) => console.log('Listening on port 3000.'));
html/index.html
<body>
<form method='post' action='post'>
<input type='text' name = 'user[name]'>
<input type='submit' value='submit'>
</form>
</body>
However in the post method, I want to send a HTML file, instead of req.body.user.name which I could obviously do like I did on the home page (/), I want to be able to include some variables into the new HTML File, maybe something looking along the lines of:
<body>
<h1><? req.body.user.name + 's page. ?></h1>
<!-- rest of code -->
</body>
I use ejs template for this purpose and it is very easy to use.
First of all, download ejs with npm install ejs -s and create a views folder inside your main directory. Inside that folder, create a normal html file but this time with an extension of .ejs.
App Directory
-views/myFile.ejs
/post.ejs
-html/index.html
-server.js
Now let's go to your server.js file. You need to use app.set('view engine', 'ejs') to run ejs. When you do res.render() you don't have specify the path because the program already looks for views/ folder in the main directory.
const app = require('express')(),
bodyParser = require('body-parser'),
path = require('path');
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.get('/', (req, res) => res.render('myFile.ejs', {username: 'myUser'}));
app.post('/student', function(req, res){
var username = req.body.user.name;
res.render('post.ejs', {user: username});
});
app.listen(3000, (req, res) => console.log('Listening on port 3000.'));
This is our sample myFile.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p><%=username%></p>
</body>
</html>
And this is our sample post.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p><%=user%></p>
</body>
</html>
You should use some template engine, there is tutorial on express page https://expressjs.com/en/guide/using-template-engines.html.
There is always possibility that you can write your own module for handling this.
You can also install express generator
npm install express-generator -g
then call:
express
Thanks to this you will setup express project with jade as template engine(it is default), it should allow you to progress further.

Categories

Resources