Issue with rendering view page in node express.js application - html

I am trying to render a static HTML page located in the views directory but when I try to visit that route, the Node.js console firing an error.
Error message
TypeError: path must be absolute or specify root to res.sendFile
at ServerResponse.sendFile (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\response.js:425:11)
at C:\Users\Administrator\Desktop\node-mvc-setup\app.js:21:7
at Layer.handle [as handle_request] (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\express\lib\router\index.js:275:10)
at urlencodedParser (C:\Users\Administrator\Desktop\node-mvc-setup\node_modules\body-parser\lib\types\urlencoded.js:91:7)
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Node MVC Front Page</title>
</head>
<body>
<h1>Great index font page</h1>
</body>
</html>
Index route
const express = require("express");
//require the express router
const router = express.Router();
router.get("/", function(req, res, next) {
res.sendFile("/views/index.html");
});
module.exports = router;

Can you require path module in your code and try doing this instead:
router.get("/", function(req, res, next) {
res.sendFile(path.join(__dirname, '../views', 'index.html'));
});

//require path
const path = require('path');
//require express
const express = require("express");
//require express router
const router = express.Router();
router.get("/", function(req, res, next) {
res.sendFile(path.join(__dirname, '../', 'views', 'index.html'));
});
module.exports = router

Related

Refused to apply style from auth/css when rendering

Problem:
I quite confused to why my render is not loading my css and images from uploads.
When I do not try to log in, every page loads it's images and css applies it's styles..
But when I try to render my page like so:
if(!results.length){
res.status(401).render('home/login', {
message: 'The email or password is incorrect'
});
}
I get this error:
I realized it says ...:3000/auth/css/.. - it's not suppose to load auth?
This is my tree:
Index.js
|
├───controllers
├───helpers
│
├───public
│ ├───css
│ ├───javascript
│ └───uploads
├───routes
│ └───home
└───views
├───home
├───layouts
└───partials
└───home
index.js
const express = require('express');
const path = require('path');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
const app = express();
// Public path
app.use(express.static(path.join(__dirname, './public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//Parse URL encoded bodies
app.use(express.urlencoded({ extended: false }));
//Parse JSON bodies as sent by API clients
app.use(express.json());
app.use(cookieParser());
// View engine
app.engine('handlebars', exphbs({defaultLayout: 'home-index'}));
app.set('view engine', 'handlebars');
// Routing
app.use('/', require('./routes/home/page_routes'));
app.use('/auth', require('./routes/auth'));
app.listen(3000, () => {
console.log('Listening');
});
views/layouts/home-index.handlebars
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/home.css">
<title></title>
</head>
<body>
{{> home/home-nav}}
{{{body}}}
</body>
</html>
routes/auth.js
const { db } = require('./db');
var jwt = require('jsonwebtoken');
var bcrypt = require('bcryptjs');
var { promisify } = require('util');
// Login
exports.login = async function(req, res) {
try {
var {email, password} = req.body;
if(!email || !password) {
return res.status(400).render('home/login', {
message: 'Please provide an email and password' ///////////////// This is the problem
});
}
db.query('select * from users_website where email = ?', [email], async function(error, results){
console.log(results)
if(!results.length){
res.status(401).render('home/login', {
message: 'The email or password is incorrect' ///////////////// This is the problem
});
}
else{
var id = results[0].id;
var token = jwt.sign({ id }, 'SuperSecretPassword9981998', {
expiresIn: '90d'
});
console.log("The token is: " + token);
var cookieOptions = {
expires: new Date(
Date.now() + 90 * 24 * 60 * 60 * 1000
),
httpOnly: true
}
res.cookie('jwt', token, cookieOptions);
res.status(200).redirect("/");
}
});
} catch (e) {
console.log(e);
}
}
routes/home/page_routes
const express = require('express');
const router = express.Router();
const auth_controller = require('../../controllers/auth');
// Home router
router.get('/', auth_controller.isLoggedIn, (req, res) => {
res.render('home/index');
});
// Login
router.get('/login', (req, res) => {
res.render('home/login');
});
module.exports = router;
Question
How do I get rid of the error - when trying to render the page?
The reason for this is that you are loading assets using relative URLs in your handlebars file, which means that the assets are loaded relative to the page's URL, which, in your case, is :3000/auth. To fix this, use an absolute URL instead.
Like this:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<!-- Notice the leading slash. -->
<link rel="stylesheet" href="/css/home.css">
<title></title>
</head>
<body>
{{> home/home-nav}}
{{{body}}}
</body>
</html>

How to create node.js html server with css

Im trying to create simple node.js server for html using http and express
It's working, but css don't showing
Here is code of my server
const express = require("express");
const app = express();
app.use(express.static("css"));
var router = express.Router()
app.use('/',router)
router.get("/", (req, res) => {
res.sendFile(__dirname + "/index.htm")
})
app.listen(8080)
And code of my server, what created using http
const http = require("http")
const port = 8080
const fs = require('fs')
const server = http.createServer(function(req,res) {
fs.readFile('./index.html', (error, data) => {
if(error) {
res.writeHead("404")
res.write("Error. File not found.")
} else {
res.use
res.write(data)
}
res.end();
})
})
server.listen(port, function(error) {
if(error) {
console.log(error)
} else {
console.log("server is listening on port " + port)
}
})
all my html code
<!DOCTYPE html>
<html lang="en">
<html>
<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>Domodinak</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<p>Hello world</p>
</body>
</html>
also css
body {
background-color: deeppink;
}
if you know how to help me, please help :)
Make sure that you're addressing css folder correctly. It depends on your project folder structure. It is suggested to save your static files in a folder called public and then save your files in separated folder like js and css. For example, i assume that you have a src folder which is your directory for express server file, another folder alongside the src folder, you have a public folder with css subfolder.
Put your stylesheet file in css subfolder, and html file in just public folder and then change your code to this:
const express = require("express");
const path = require("path");
const app = express();
app.use(express.static(path.join(__dirname, "../public")));
// var router = express.Router()
// app.use('/',router)
// router.get("/", (req, res) => {
// res.sendFile(__dirname + "/index.htm")
// })
app.listen(8080)
Your project structure should looks like this:
|-public -| css -| style.css
index.html
|-src -| app.js
Run the server file then check your browser with just localhost:8080. It serves index.html from static directory which you passed to express earlier.

Having trouble sending a json to html and getting <%- to work

So I'm trying to use values in my json file to display on the webpage. For instance, one value will be the text on the accordion button.
I'm using express and ejs, and I've been trying to use <%- %> to call the text in the json file but it won't seem to appear on the webpage.
index.js
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.get('/', function(req, res) {
res.locals.ClinNotes1=('.\ClinNotes.json');
res.render('webpage');
})
webpage.ejs
<div id="Problems" class="tabcontent">
<div class="problemItems">
<button class="accordion" id="accordionDis">
<span><ul><%-ClinNotes1.resourceType%></ul></span>
ClinNotes.json
{ "resourceType": "Bundle",
....}
If you want to show your JSON data on your webpage you can do something like that:
index.js
//here import your json file
const notes = require('./ClinNotes.json'); //suppose your file is in the root directory
app.get('/', function(req, res) {
res.render('webpage', {data: notes});
})
webpage.ejs
<span><ul><%-data.resourceType%></ul></span>
Hopefully, it might help you
Here is a quick example I put together.
Basically, you want to iterate over the JSON file the same way you would a Javascript object.
app.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
//Use EJS Templating Engine
app.set('view engine', 'ejs');
app.get('/', (req, res, next) => {
res.locals.dataFromJSON = require('./data.json');
res.render('index');
});
//Start Server
app.listen(port, () => {
console.log(`Server started on port number ${port}`);
});
index.ejs
<!DOCTYPE html>
<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>Example</title>
</head>
<body>
<h1>Hope this helps!</h1>
<% Object.values(dataFromJSON).forEach((value) => { %>
<button><%= value %></button>
<% }); %>
</body>
</html>
data.json
{
"resourceType": "Bundle",
"resourceType2": "Bundle2",
"resourceType3": "Bundle3",
"resourceType4": "Bundle4"
}
Here is a gitub repo i created
Here is the expected output deployed to heroku
I hope this helps! 👍

failure to load css file when I type in domain

I'm getting the message "Failed to load resource: the server responded with a status of 404 (Not Found)" on my css file. My site is a node app hosted on a Digital Ocean server
const express = require('express');
const app = express();
app.use(express.static('public'));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});
body {
background-color: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Brand Central Network</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>www.brandcentralnetwork.tv</h1>
</body>
</html>

How to navigate between two html files in a Expressjs project

am relatively new to expressjs and for the life of me i can not figure out how to navigate between two HTML files in the root folder. Am using bootstrap anjularjs and expressjs for my project.
I have currently used the following code in the routes directory:
var express = require('express');
var router = express.Router();
var app = express();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('profile', { title: 'Express' });
});
router.get('/profile', function(req, res, next){
res.render('profile', {title: ''});
});
module.exports = router;
In addition to this i have also made use of this statement in the app.js file to try and help with navigation:
app.use('/static',express.static(path.join(__dirname, 'views')))
app.use('/html', express.static("html"));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.get('/profile', function (req,res){
res.render('profile', {
title: 'Profile'
});
});
So my problem is this current error, any assistance with this would be appreciated:
Error: Failed to lookup view "error" in views directory "C:\Users\Brian Manda\Documents\fmg_code\views"
at EventEmitter.render (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\application.js:579:17)
at ServerResponse.render (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\response.js:960:7)
at C:\Users\Brian Manda\Documents\fmg_code\app.js:52:7
at Layer.handle_error (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\router\index.js:310:13)
at C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\router\index.js:280:7
at Function.process_params (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\router\index.js:330:12)
at next (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\router\index.js:271:10)
at C:\Users\Brian Manda\Documents\fmg_code\app.js:41:2
at Layer.handle [as handle_request] (C:\Users\Brian Manda\Documents\fmg_code\node_modules\express\lib\router\layer.js:95:5)
Returns the rendered HTML of a view via the callback function. It accepts an optional parameter that is an object containing local variables for the view. It is like res.render(), except it cannot send the rendered view to the client on its own.
If you dont set the "ejs", automatically the app get the .html file, because res.render is for that.
In the case, my html file have name: index inside public folder.
If your index is .html:
var app = express();
app.get('/', function(req, res){
res.render("../public/index"); //the archive html file
});
If you index is '.ejs':
var app = express();
app.set('view engine', 'ejs'); // set the index.ejs file
app.get('/', function(req, res){
res.render("../public/index.ejs"); // if you want, remove the .ejs, is optional,
});
Reference here.