Express not seving static images from view/subfolders - node.js

I have a problem where my static images work perfectly when linked from /views folder and from /views/partials folder, but when I put a subfolder between /views/courses/partials my image stops working.
I am using
app.use(express.static(__dirname + "/public"));
My file structure:
> app
- app.js
> public
> assets
> images
> icons
- link.png
> views
- landing.ejs
> partials
- header.ejs
> courses
- courses.ejs (images is working when linked from here)
> partials
- lectures.ejs //This file is a partial of courses.ejs (images not working when linked from here)
The path I use is /assets/images/icons/link.png
Here is my app.js if needed
//REQUIREMENTS - requiering files for App.js
var express = require("express"),
app = express(),
passport = require("passport"),
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
flash = require("connect-flash"),
passportSetup = require("./config/passport"),
methodOverride = require("method-override"),
User = require("./models/user"),
Course = require("./models/course"),
middleware = require("./middleware"),
path = require("path");
//REQUIERING ROUTES - requiering routes files
var indexRoutes = require("./routes/index");
var authRoutes = require("./routes/auth");
var adminRoutes = require("./routes/admin");
var messageRoutes = require("./routes/message");
var courseRoutes = require("./routes/courses");
// DATABASE CONNECTION - conecting to mongoDB using enviroment variables
var dbUrl = "mongodb://localhost/example" || process.env.DATABASEURL;
mongoose.connect(dbUrl);
//METHOD OVERRIDE - override http method
app.use(methodOverride("_method"));
//FLASH MESSAGES - use flash messages
app.use(flash());
//BODY PARSER - using bodyparser to easily retrieve http info
app.use(bodyParser.urlencoded({extended: true}));
//STATIC DIRECTORIES - use static directories for clientside linking
app.use(express.static(__dirname + "/public"));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//VIEW ENGINE - default view engine
app.set("view engine", "ejs");
//PASSPORT CONFIGURATION - setting express session secret
app.use(require("express-session")({
secret: "************************",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
//CURRENT USER - sending current user to every route
app.use(function(req, res, next){
res.locals.currentUser = req.user;
next();
});
//ROUTES - all routes are used here
app.use(authRoutes);
app.use(adminRoutes);
app.use(messageRoutes);
app.use(courseRoutes);
app.use(indexRoutes);
//LISTENING PORT - port to listen to
var port = 4000 || process.env.PORT;
//LISTEN - listen on chosen port
app.listen(port, process.env.IP,function(){
//Startup message
console.log("Server has started!");
});
And here is my lectures.ejs file:
<div id="lectures-content" class="page-section--small">
<div class="wrapper--no-padding course-lectures">
<div class="course-lectures__lecture flex">
<div class="course-lectures__left">
<div class="text-area">
<div class="text-area__smallheading">Lecture 1</div>
<div class="text-area__text text-area__text--small">This is the first lecture</div>
</div>
</div>
<div class="course-lectures__right flex">
<div class="course-lectures__number">Lecture: 1</div>
<div class="course-lectures__arrow">
<img class="course-lectures__image" src="/assets/images/icons/link.jpg" alt="">
^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
</div>
</div>
</div>
</div>
</div>

I think there's a mismatch in the filetype of you picture:
link.jpg != link.png

Try this: It may help you
app.use(express.static('./public'));
Make sure that your app.js must be in the same directory,

Related

Node-Express error: No default engine was specified and no extension was provided

I've just started learning Node.js and i'm trying to create a web application that returns the form in users.ejs when http://localhost:8083 is entered. What is going wrong here?
./index.js
var express = require("express");
var mysql=require("mysql");
var app = express();
var usersRouter=require('./routes/users');
app.use("/",usersRouter);
var server = app.listen(8083, function(){
var port = server.address().port;
console.log("Server started at http://localhost:%s", port);
});
./routes/users.js
var express=require("express");
var router=express.Router();
router.get('/',function(req,res){
res.render("./views/users");
})
module.exports = router;
./views/users.ejs
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="user-detail">
<h2>Create User Data</h2>
<form action="/users/create" method="POST">
<label>Full Name</label>
<input type="text" placeholder="Enter Full Name" name="fullName" required>
<label>Email Address</label>
<input type="email" placeholder="Enter Email Address" name="emailAddress" required>
<label>City</label>
<input type="city" placeholder="Enter Full City" name="city" required>
<label>Country</label>
<input type="text" placeholder="Enter Full Country" name="country" required>
<button type="submit">Submit</button>
</div>
</div>
</body>
</html>
The view engine for rendering the template file is not configured.
You need to setup the view engine on the app level via app.set method, by setting view engine to ejs :
view engine
String The default engine extension to use when omitted. NOTE:
Sub-apps will inherit the value of this setting.
https://expressjs.com/en/5x/api.html#app.settings.table
so in index.js add this:
app.set('view engine', 'ejs');
also, you need to install ejs
npm i -S ejs
and include it, so your index.js file should look like this
var ejs = require('ejs');
app.set("view engine", "ejs");
Now the view engine is set, but your users router will fail with this error:
Error: Failed to lookup view "./vies/users" in views directory
It's this method here:
res.render("./views/users");
It's now trying to load users template from views/views, i.e. there's an extra view. It's coming from yet another app setting - views, a directory to store and read view templates:
views
String or Array A directory or an array of directories for the
application's views. If an array, the views are looked up in the order
they occur in the array
Default: process.cwd() + '/views'
https://expressjs.com/en/5x/api.html#app.settings.table
It's configured by setting the views path on the app level, like so:
app.set('views', path.join(__dirname, 'views'));
And as you can see, it's already set to process.cwd() + '/views' by default, so it's optional, which means that's where that extra view is coming from, so you just need to remove views/ in the users router, so it'll pick it up from the root by default:
res.render("./users");
Final code:
./index.js
var express = require("express");
var app = express();
// load ejs template renderer
var ejs = require("ejs");
// register the given template engine
app.set("view engine', 'ejs");
// optional, as it defaults to process.cwd() + '/views'
// needs path too:
// var path = require("path");
//app.set("views", path.join(__dirname, "views"));
var usersRouter = require("./routes/users");
app.use("/", usersRouter);
var server = app.listen(8083, function() {
var port = server.address().port;
console.log("Server started at http://localhost:%s", port);
});
./routes/users.js
var express=require("express");
var router=express.Router();
router.get('/',function(req,res){
res.render("./users");
})
module.exports = router;
Check Express guide and examples here:
https://expressjs.com/en/starter/examples.html

images not rendering in production

I have deployed my node.js express app to production via a docker file, however, the images are not being rendered, and browser standard placeholder images are being rendered in-place of these.
In order for my app to render these images, is there something I am doing wrong? Is there a piece of code I need to include?
My file structure is as follows
base directory > public > icons
base directory > index.js
Relevant portion of my index.js server file
const { join } = require("path");
app.set('views', join(__dirname, 'views'));
app.use(express.static(join(__dirname, 'public')));
const port = 3000
var cookieParser = require('cookie-parser')
app.use(cookieParser())
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
app.use(cookieParser());
process.env.NODE_ENV === 'production'
app.set('view engine', 'ejs');
app.get('/',(req,res)=>{
res.render('index',{
data: 'name'
})
})
Here is the error message I get when I try to open the image file
ejs file:
<% data.countries.forEach(function(count){ %>
<div class="flex">
<div class="template">
<div class=“Country>
<img class="img" src="/icons/<%= count.icon %> " width="25" height="25" /> <%= count.name %>
</div>
<div class ="Category">
<%= count.categories.map(cat=>cat.name).join(' | ') %>
</div>
</div>
</div>
<% }); %>
Can you open the file directly by his path?
One possible answer is because inside your EJS file, your image is pointing at a URL that looks something like /icons/HK.png, but your ExpressJS public path is set to /public indeated here:
app.use(express.static(join(__dirname, 'public')));
So one possible solutions is to add a new public path for your icons set by adding this code:
app.use('/icons', express.static(join(__dirname, '/public/icons')))

How to handle POST request using express in Node.js? I have written following code which is not working

Not able to handle post request data using express in Node.js. I want to handle form data from index.html file in test.js file. Getting error:
POST /test" Error (404): "Not found"
Following is the code which I have written:
index.html
<html>
<body>
<form action="/test" method="POST">
Name: <input type="text" name="name"/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
test.js
var express = require("express");
var bodyParser = require('body-parser');
var app = express();
var urlEncodedParser = app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: false
}));
app.post('/test',urlEncodedParser, function(req,res){
console.log("Kushagra "+req.body);
});
app.listen(8080,function(){
console.log("Started in port 8080");
});
What to be done in order to receive form data from index.html file to test.js file.
// TODO: Place this code before route & put index.html to public directory
const path = require("path");
app.use(express.static(path.join(__dirname, "public")));

Cant get the data from form post to nodeJS server

I am trying to write a login page . i got the html page with the login box
im enter email and password than submit to server , on server i got route who get the data check on db if doc exists , if its exists should redirect to main page
the problem is the data i send from form to server always undefined i check here on other ppl questions and i didnt find any good result for this
html login page :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/css/style.css" />
<title>{{PageTitle}}</title>
</head>
<body>
{{> header}}
<div class="login-box">
<div class="form">
<form action="/get_user" method="post" class="login-form">
<input type="email" name="Email" placeholder="Email"/>
<input type="password" name="Password" placeholder="Password"/>
<button type="submit">login</button>
</form>
</div>
</div>
{{> footer}}
</body>
server code :
const _ = require('lodash');
const express = require('express');
const bodyParser = require('body-parser');
const {mongoose} = require('./db/mongoose');
const hbs = require('hbs');
var {User} = require('./models/user');
var app = express();
app.set('view engine', 'hbs');
const port = process.env.PORT;
hbs.registerPartials(__dirname + '/../views/partials');
app.user(bodyParser.json());
app.use(express.static(__dirname + '/../public'));
app.use(express.static(__dirname + '/../public/images'));
app.use(express.static(__dirname + '/../public/fonts'));
app.listen(port, () => {
console.log(`Started on port ${port}`);
});
app.get('/', (req, res) => {
res.render('login.hbs', {
PageTitle: 'Log In',
ConnectUser: 'Guest'
});
});
app.post('/get_user', (req, res) => {
var body = _.pick(req.body, ['Email , 'Password']);
User.findOne({
Email: body.Email,
Password: body.Password
}).then((user) => {
console.log(body.Email + ' ' + body.Password);
if(!user) {
return res.status(404).send();
}
var fullName = user.First_Name + ' ' + user.Last_Name;
res.redirect('/mainPage', {ConnectUser: fullName});
}).catch((e) => {
res.status(400).send();
});
});
i did few checks and when i call /get_user req.body->var body -> user r empty
the data arnt pass from form to server im also check this route on postman and its work find when i write the body by myself the only problem i can think is the data i send from form arnt send as json and the body parser send only in json format so maybe i need to change the line
app.use(bodyParser.json());
if any 1 can put in the right direction ill appraise that ty.
When using an html form with method post, the data is posted to the server withContent-Type: application/x-www-form-urlencoded instead of JSON.
Json bodyparser will not do anything with that, as its not using JSON format to send the data. See MDN guide under post method.
In your server code, below app.use(bodyParser.json()) add the following:
app.use(bodyParser.urlencoded({extended: true}));
This will add the data onto the request body the way you expect.
Try playing with the form enc-type attribute and see how to configure the bodyparser to get the values you need based on the enc-type.
application/x-www-form-urlencoded
multipart/form-data
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype

can not read image from folder in node.js

I have put images inside "/public/images" path. Now in the respose I am getting url as I wanted. But as soon as I paste that url to web browser, it says Cannot GET /public/images/food-1-xxhdpi.png. So should I write separate API to handle that?
Main file app.js
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
var PORT = 3000;
var foodtrucklist = require('./controller/foodtrucklist.js');
var foodtruck = require('./model/datafoodtruck');
var db = mongoose.connect('mongodb://127.0.0.1:27017/quflip');
mongoose.connection.once('connected', function() {
console.log("Connected to database")
foodtruck.save(function(err,foodtrucks){
if (err) res.send(err);
});
});
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public/images'));
app.get('/foodtrucklist',foodtrucklist);
app.listen(PORT,function() {
console.log('express listining on port' + PORT);
});
This line
app.use(express.static(__dirname + '/public/images'));
Maps the static content in the /public/images folder to the root of your web application. So the request /public/images/food-1-xxhdpi.png will only work if the full path is .../public/images/public/images/food-1-xxhdpi.png
You should either make your request for /food-1-xxhdpi.png or change the line of code to something like:
app.use('/my-virtual-directory',express.static(__dirname + '/public/images'));
so that requests can be picked up in what ever you choose to make /my-virtual-directory
So... Your file in this case becomes /my-virtual-directory/food-1-xxhdpi.png
Obviously, you can still do this to make it map externally to the same way you have it internally with:
app.use('/public/images', express.static(__dirname + '/public/images'));
Here is more info on the static middleware for express: https://expressjs.com/en/starter/static-files.html
Try:
Backend:
var path = require('path');
var app = express();
var express = require('express');
app.use(express.static(path.join(__dirname, 'public')));
Frontend:
<img src="/images/food-1-xxhdpi.png" alt="">
You can try back-end look like this.
app.use(express.static(__dirname + '/public'));
Then front end use this extract location like
<img src="images/your image name" alt="" />
I am currently working on project and next snippet of code working fine for me:
app.use(express.static('public'));
and when I try to reach this in .hbs it is easy as:
<img src='/images/image.jpg' alt='...' />
Just type following code in your app.js file
app.use('/static/category/', express.static(__dirname+'/public/assets/category_pic/'));
now i will access image by using following code
<img src="/static/category/myimage.jpg" width="50" height="50">
here my actual path is /public/assets/category_pic/ but i convert it /static/category/ using above line of code
now i able to access image file using this url http://localhost:3000/static/category/myimage.jpg

Resources