The link to go to the `ejs` page does not work - node.js

I can't go to another ejs page.
Description
The link to go to the ejs page does not work
I have an existing project... Everything works in it...
Example: a transition is made from Index -> to a subpage.
In the current state of the project, the subpage is located at localhost:3000/0/articles/14
The subpage is filled with data from the database.
I did.
created my own Index page;
Index page- opens;
created my own About Subpage;
Result: switching from the Index page to About does not work.
Index.ejs
<h1>Index page</h1>
<a href="/about" >About-1. Описание</a> </br>
<a href="http://localhost:3000/About/" >About-2. Описание</a>
I added to the file routes.js
.get('/about', (req, res) => {
res.render('about');
})
The whole code routes.js
const multer = require('multer');
const rand = require('randomstring');
const filesStorage = multer.diskStorage({
destination: (req, file, next) => {
next(null, 'static/uploads/files');
},
filename: (req, file, next) => {
const ext = file.originalname.split('.').pop();
next(null, rand.generate({
length: 32,
charset: 'alphabetic'
}) + '.' + ext);
}
});
const filesUpload = new multer({
storage: filesStorage
});
const site = {
main: require('./controllers/main')
};
const cms = {
articles: require('./controllers/cms/articles'),
files: require('./controllers/cms/files'),
lang: require('./controllers/cms/lang'),
slideshow: require('./controllers/cms/slideshow')
};
module.exports = (app, passport) => {
app
.get('/', site.main.lang)
.get('/video', site.main.video)
.get('/slideshow', site.main.slideshow)
.get('/:lang', site.main.index)
/*articles*/
.get('/:lang/articles', site.main.index)
.get('/:lang/articles/:id', site.main.article)
.get('/:lang/panomuseum', site.main.panomuseum)
.get('/:lang/panomuseum/2', site.main.panomuseum2)
.get('/:lang/panotheatre', site.main.panotheatre)
/*My*/
// .get('/:lang/articles', site.main.index)
.get('/Index', site.main.index)
.get('/history', site.main.history)
// .get('/history', (req, res) => {
// res.render('history');
// })
.get('/about', (req, res) => {
res.render('about');
})
;
app
.get('/cms/lang', cms.lang.index)
.post('/cms/lang', filesUpload.any(), cms.lang.save)
.get('/cms/:lang/articles', cms.articles.index)
.post('/cms/articles/saveOrder', cms.articles.saveOrder)
.get('/cms/:lang/articles/add', cms.articles.add)
.post('/cms/:lang/articles/add', filesUpload.any(), cms.articles.postAdd)
.get('/cms/:lang/articles/:id/edit', cms.articles.edit)
.post('/cms/:lang/articles/:id/edit', filesUpload.any(), cms.articles.postEdit)
.get('/cms/:lang/articles/:id/delete', cms.articles.delete)
.get('/cms/:lang/articles/:id', cms.articles.subArticle)
.get('/cms/:lang/articles/add/:id', cms.articles.add)
.post('/cms/files/delete', cms.files.delete)
.post('/cms/files/saveFile', filesUpload.single('file'), cms.files.saveFile)
.post('/cms/files/saveThumb', filesUpload.single('thumb'), cms.files.saveThumb)
.get('/cms/slideshow', cms.slideshow.index)
.post('/cms/slideshow/save', filesUpload.any(), cms.slideshow.save);
return app;
controllers\main.js
const db = require('../db');
const fs = require('fs');
const path = require('path');
const config = require('../config.js');
class Main {
async video(req, res, next) {
const videoFolder = './static/video'
let videos = []
fs.readdirSync(videoFolder).forEach((file) => {
let extension = path.extname(file)
let filename = path.basename(file, extension)
videos.push({
file,
filename: parseInt(filename),
})
})
videos = videos.sort((a, b) => {
return a.filename - b.filename
})
return res.render('video', {
domain: config.express.domain,
videos,
})
}
async panomuseum(req, res) {
const article = await db.article.getByID(req.params.lang);
const sub = await db.article.getRoot(req.params.lang);
const files = await db.files.getByOwnerId(req.params.lang);
const lang = await db.lang.getById(req.params.lang);
return res.render('panomuseum', {
article,
sub,
files,
lang
});
}
async panomuseum2(req, res) {
const article = await db.article.getByID(req.params.lang);
const sub = await db.article.getRoot(req.params.lang);
const files = await db.files.getByOwnerId(req.params.lang);
const lang = await db.lang.getById(req.params.lang);
return res.render('panomuseum2', {
article,
sub,
files,
lang
});
}
async panotheatre(req, res) {
const article = await db.article.getByID(req.params.lang);
const sub = await db.article.getRoot(req.params.lang);
const files = await db.files.getByOwnerId(req.params.lang);
const lang = await db.lang.getById(req.params.lang);
return res.render('panotheatre', {
article,
sub,
files,
lang
});
}
async index(req, res) {
const article = await db.article.getByID(req.params.lang);
const sub = await db.article.getRoot(req.params.lang);
const files = await db.files.getByOwnerId(req.params.lang);
const lang = await db.lang.getById(req.params.lang);
const timeout = await db.settings.getByID("timeout");
const caption = await db.settings.getByID("caption");
return res.render("index", {
article,
sub,
files,
lang,
timeout,
caption,
domain: req.app.get("domain"),
});
}
// async history(req, res) {
// // const article = await db.article.getByID(req.params.lang);
// // const sub = await db.article.getRoot(req.params.lang);
// // const files = await db.files.getByOwnerId(req.params.lang);
// // const lang = await db.lang.getById(req.params.lang);
// // const timeout = await db.settings.getByID("timeout");
// // const caption = await db.settings.getByID("caption");
// return res.render("history", {
// domain: req.app.get("domain")
// });
// }
async history(req, res) {
console.log('Request for history page recieved');
return res.render("history");
}
async about(req, res) {
console.log('Request for about page recieved');
return res.render("about");
}
async menu(req, res) {
return res.render("menu", {
domain: req.app.get("domain"),
});
}
async slideshow(req, res) {
const slideshow = await db.files.getSlideshow();
const timer = await db.settings.getByID("timer");
return res.render("slideshow", {
slideshow,
timer,
domain: req.app.get("domain"),
});
}
async slide(req, res) {
const slideshow = await db.files.getByID(req.params.id);
const timer = await db.settings.getByID("timer");
return res.render("slideshow", {
slideshow: [slideshow],
timer,
domain: req.app.get("domain"),
});
}
async article(req, res) {
const article = await db.article.getByID(req.params.id);
const sub = await db.article.getSub(req.params.id);
const files = await db.files.getByOwnerId(req.params.id);
const id = req.params.id;
const lang = await db.lang.getById(req.params.lang);
const timeout = await db.settings.getByID("timeout");
const caption = await db.settings.getByID("caption");
return res.render("index", {
id,
article,
sub,
files,
lang,
timeout,
caption,
domain: req.app.get("domain"),
});
}
async lang(req, res) {
const langs = await db.lang.getAll();
let activeCount = 0;
for (let lang of langs) {
if (lang.value == 1) {
activeCount++;
}
}
if (activeCount == 0) {
return res.redirect("/0");
} else if (activeCount == 1) {
for (let lang of langs) {
if (lang.value == 1) {
return res.redirect("/" + lang.id);
}
}
}
const timeout = await db.settings.getByID("timeout");
return res.render("lang", {
langs,
timeout,
});
}
async openSlide(req, res) {
console.log("openSlide");
let files = await db.files.getSyncSmartHome();
parentIO.sockets.in("client").emit("goToUrl", {
message: "/slide/" + files[parseInt(req.params.id)].id,
});
return res.json({
success: true,
});
}
async openSlideshow(req, res) {
console.log("open slideshow");
parentIO.sockets.in("client").emit("goToUrl", {
message: "/slideshow",
});
return res.json({
success: true,
});
}
}
module.exports = new Main();

Related

Nodejs how to use Multer on function

I have created controller, routes and functions base api. What issue I am getting is how can I use Multer on function.
I have function like this
const { Users } = require('../models/user');
const { Company } = require('../models/company');
const { Jobs } = require('../models/job');
var mongoose = require('mongoose');
const multer = require('multer');
const FILE_TYPE_MAP = {
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/jpg': 'jpg'
};
const storage = multer.diskStorage({
destination: function (req, file, cb) {
const isValid = FILE_TYPE_MAP[file.mimetype];
let uploadError = new Error('invalid image type');
if (isValid) {
uploadError = null;
}
cb(uploadError, 'public/uploads');
},
filename: function (req, file, cb) {
const fileName = file.originalname.split(' ').join('-');
const extension = FILE_TYPE_MAP[file.mimetype];
cb(null, `${fileName}-${Date.now()}.${extension}`);
}
});
const uploadOptions = multer({ storage: storage });
const createJob = function async(req, res) {
const job = new Jobs({
jobTitle: req.body.jobTitle,
jobDescription: req.body.jobDescription,
jobImage: req.body.userType,
jobType: req.body.jobType,
jobNumberOfPeople: req.body.jobNumberOfPeople,
jobHireTime: req.body.jobHireTime,
jobMinPay: req.body.jobMinPay,
jobMaxPay: req.body.jobMaxPay,
jobday: req.body.jobday,
jobRecieveApplication: req.body.jobRecieveApplication,
jobSubmitResume: req.body.jobSubmitResume,
jobApplicationDeadline: req.body.jobApplicationDeadline,
jobCommunationSetting: req.body.jobCommunationSetting,
jobMessageSetting: req.body.jobMessageSetting,
companyID: req.body.companyID,
});
try {
const jobsave = await job.save();
res.status(200).json({ success: true, data: jobsave })
} catch (err) {
if (err.name === 'ValidationError') {
console.error(Object.values(err.errors).map(val => val.message))
return res.status(400).json({ success: false, message: Object.values(err.errors).map(val => val.message)[0] })
}
res.status(400).json({ success: false, message: err })
}
};
module.exports = { createJob };
and routes like this
const express = require('express');
const router = express.Router();
const userController = require('../controllers/user');
const jobController = require('../controllers/jobs');
router.post('/createJob', jobController.createJob);
module.exports = router;
now I need to add uploadOptions.single('jobImage') in function
I am doing like this const createJob =
const createJob = uploadOptions.single('jobImage'), async(req, res) => { };
Its showing this error on comma don't know why
Its working directly on router but I need to do In function
You can use this:
module.exports = {
createJob : [ uploadOptions.single('jobImage'), createJob ]
};

Azure: INFO - Waiting for response to warmup request for container ... Elapsed time = x sec

My app fails on prod and can't find a way how to fix. It works on another environments.
Some logs from the console:
2022-08-22T23:56:05.760Z INFO - Waiting for response to warmup request for container projectprod-fe_0_fd84e. Elapsed time = [225.2643051] sec
2022-08-22T23:56:35.818Z ERROR - Container projectprodfe_0_fd84e for site teamgullitpreview-fe did not start within expected time limit. Elapsed time = 255.322965 sec
It is next.js app and I create middlewares for it.
const next = require('next');
const { parse } = require('url');
nextMiddleware
async function nextMiddleware(dev = false) {
const app = next({ dev });
const handle = app.getRequestHandler();
await app.prepare();
return function nextHandler(req, res) {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
};
}
redirectMiddleware
const path = require('path');
const fs = require('fs');
const staticFiles = ['_next', '/', 'images', 'api'];
const getRedirect = async (srcPath) => {
try {
const url = `${process.env.NEXT_PUBLIC_apiUrl}/redirect?path=${srcPath}`;
const response = await fetch(url);
const json = await response.json();
return json;
} catch (e) {
throw new Error(e);
}
};
function redirecter(pathname) {
return new Promise((resolve, reject) => {
const pathParts = pathname.split('/');
if (staticFiles.indexOf(pathParts[1]) > -1) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
const possibleFile = `${path.resolve(
__dirname,
'../../public',
)}${pathname}`;
if (fs.existsSync(possibleFile)) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
getRedirect(pathname)
.then((result) => {
resolve({
shouldRedirect: true,
redirectData: result,
});
})
.catch((e) => {
reject(e);
});
}
}
});
}
async function redirectMiddleware(req, res, next) {
const parsedUrl = parse(req.url, true);
const { pathname } = parsedUrl;
try {
const { shouldRedirect, redirectData } = await redirecter(pathname);
if (shouldRedirect && redirectData.destination) {
const redirectUri = `${process.env.NEXT_PUBLIC_hostname}${
redirectData.type ? redirectData.type : ''
}${redirectData.destination}`;
res.writeHead(redirectData.statusCode[0], {
Location: redirectUri,
});
res.end();
}
} catch (e) {
next();
} finally {
next();
}
}
What I do wrong in this file or whenever?
const http = require('http');
const express = require('express');
const redirectMiddleware = require('./src/server/redirectMiddleware');
const nextMiddleware = require('./src/server/nextMiddleware');
const port = process.env.PORT || 3000;
async function bootstrap() {
const isDevelopment = process.argv.includes('--dev');
const app = express();
app.use(await redirectMiddleware);
app.use(await nextMiddleware(isDevelopment));
const server = http.createServer(app);
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
}
bootstrap().catch((err) => {
console.error('something went wrong booting up the server.');
console.error(err);
process.exit(1);
});
I have no idea what's wrong and how to debugg it. Is anyone who experienced it before?

Fastifyis not defined and fastify-postgres Fastify.pg.connect not working

I have defined my fastify like so:
const fastify = require('fastify')({logger: true})
fastify
.register(require('./setup/envs'))
.after(async (err) => {
if (err) console.log(err);
fastify.register(require('./setup/db'))
await fastify.after()
fastify.register(require('./setup/jwt'))
await fastify.after()
fastify.register(require('./setup/auth'))
await fastify.after()
// load routes
// fastify.register(require('./routes/test'))
fastify.register(require('./routes/posts/index'), { prefix: '/posts' })
})
const start = async () => {
try {
await fastify.ready()
fastify.listen(3000)
} catch (e) {
fastify.log.error(e)
process.exit(1)
}
}
start();
Now in my post routes, I have the following:
const postRoutes = require('../../controllers/posts');
async function PostRoutes(fastify, options) {
fastify.addHook('preValidation', fastify.verifyJWT)
fastify.addHook('preHandler', function (req, reply, done) {
if (req.body) {
req.log.info({ body: req.body }, 'parsed body')
}
if (req.params) {
req.log.info({ params: req.body }, 'parsed params')
}
done()
})
// get all posts
fastify.get('/:limit/:page', postRoutes.getPosts)
fastify.post('/signup', async (req, reply) => {
// some code
const token = fastify.jwt.sign({ test: 'hello' })
reply.send({ token })
})
fastify.get(
"/test-auth",
async function(request, reply) {
return { test: 'auth' }
}
)
}
module.exports = PostRoutes;
and my controller file is the following:
const fastify = require('fastify');
const getPosts = async (req, reply) => {
try {
const client = await fastify.pg.connect()
const { rows } = await client.query(
'SELECT * FROM POSTS LIMIT $1 OFFSET $2;', [req.params.limit, req.params.offset],
)
client.release()
return rows
} catch (e) {
req.log.error('Getting posts failed with params')
throw new Error(e)
}
}
module.exports = {
getPosts,
};
The const client = await fastify.pg.connect() is giving me fastify is not defined and if I require it by adding const fastify = require('fastify') at the top, I get TypeError: Cannot read properties of undefined (reading 'connect').
the following is my db.js:
const fastifyPlugin = require('fastify-plugin');
const fastifyPostgres = require('fastify-postgres');
async function dbConnector (fastify, options) {
const dbUser = encodeURIComponent(fastify.config.DATABASE_USERNAME)
const dbPassword = encodeURIComponent(fastify.config.DATABASE_PASSWORD);
const dbHost = encodeURIComponent(process.env.DATABASE_HOST);
const dbName = encodeURIComponent(fastify.config.DATABASE_NAME);
fastify.register(fastifyPostgres, {
connectionString: `postgres://${dbUser}:${dbPassword}#${dbHost}/${dbName}`
})
}
// Wrapping a plugin function with fastify-plugin exposes the decorators
// and hooks, declared inside the plugin to the parent scope.
module.exports = fastifyPlugin(dbConnector);
I had to change my route to
fastify.get('/:limit/:page', (req, reply) => postRoutes.getPosts(fastify, req, reply))
and then I was able to access the fastify object in my controller.

UnhandledPromiseRejectionWarning: TypeError: questionList is not iterable

I'm trying to make questionList a global variable so both router.post can use it because questionList use aggregate to take 10 random objects from a database, but it keeps having this error:
(node:17008) UnhandledPromiseRejectionWarning: TypeError: questionList
is not iterable
const mongodb = require('mongodb');
const express = require('express');
const router = express.Router();
const app = express();
app.use(express.urlencoded());
app.use(express.json());
var questionList = async function (req, res, next) {
next();
const questionList = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray();
return questionList;
};
app.use(questionList);
router.post('/attempts', async (req, res) => {
let correctAnswers = {};
for (const questions of questionList) {
correctAnswers[questions._id] = questions.correctAnswer;
}
let attemptQuiz = {
questions: questionList,
correctAnswers,
completed: false,
startAt: new Date(),
};
let newAttemptQuiz = await req.database
.collection('attempts')
.insertOne(attemptQuiz);
let renderAttemptsQuiz = await req.database
.collection('attempts')
.findOne({ _id: mongodb.ObjectID(`${newAttemptQuiz.insertedId}`) });
const quesShow = renderAttemptsQuiz.questions;
let objAll = [];
let quest = {};
for (const part of quesShow) {
quest._id = part._id;
quest.text = part.text;
quest.answers = part.answers;
objAll.push(quest);
}
let responseAttempt = {
_id: renderAttemptsQuiz._id,
questions: objAll,
completed: false,
startAt: new Date(),
};
res.status(200).json(responseAttempt);
});
router.post('/attempts/submit', async (req, res) => {
let correctAnswers = {};
for (const questions of questionList) {
correctAnswers[questions._id] = questions.correctAnswer;
}
const clientAnswers = req.body;
const count = 0;
for (const ques of questionList) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count++;
}
}
res.json({ score: count });
});
module.exports = router;
Please help me fix this!! Thanks very much
You will need to cache your response in another variable.
let sample = []
var questionList = async function (req, res, next) {
sample = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray()
next()
};
for (const ques of sample) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count++;
}
}
Уou can also stash it in the request object.
var questionList = async function (req, res, next) {
req._sample = await req.database
.collection('questions')
.aggregate([{ $sample: { size: 10 } }])
.toArray()
next()
};
for (const ques of req._sample) {
if (correctAnswers[ques._id] == clientAnswers[ques._id]) {
count++;
}
}
Also, install your middleware on the router.
router.use(questionList);
// app.use(questionList);

Error: connect ECONNREFUSED 127.0.0.1:5000

I´ve the file cases.js to create the route I want:
const express = require("express");
const { requireSignin } = require("../controllers/auth");
const { getCases } = require("../controllers/cases");
const { scrapingData } = require("../scrapingData");
const router = express.Router();
router.get("/cases", requireSignin, scrapingData, getCases);
module.exports = router;
requireSignin from controllers/auth looks like this:
exports.requireSignin = expressJwt({
secret: process.env.JWT_SECRET,
userProperty: "auth",
});
scrapingData as middleware I have:
const updateMongoRecords = async () => {
mongoose.Promise = global.Promise;
mongoose.set("debug", true);
Case.deleteMany({}, (err, result) => {
if (err) {
console.log(err);
} else {
console.log("Successfully deleted all records");
}
});
const dataPath = Path.join(__dirname, "files", "covid-data.csv");
try {
let headers = Object.keys(Case.schema.paths).filter(
(k) => ["_id", "__v"].indexOf(k) === -1
);
await new Promise((resolve, reject) => {
let buffer = [],
counter = 0;
let stream = fs
.createReadStream(dataPath)
.pipe(csv())
.on("error", reject)
.on("data", async (doc) => {
stream.pause();
buffer.push(doc);
counter++;
// log(doc);
try {
if (counter > 10000) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
}
} catch (e) {
stream.destroy(e);
}
stream.resume();
})
.on("end", async () => {
try {
if (counter > 0) {
await Case.insertMany(buffer);
buffer = [];
counter = 0;
resolve();
}
} catch (e) {
stream.destroy(e);
}
});
});
} catch (e) {
console.error(e);
} finally {
process.exit();
}
};
exports.scrapingData = async (req, res, next) => {
const url = "https://covid.ourworldindata.org/data/owid-covid-data.csv";
const path = Path.resolve(__dirname, "files", "covid-data.csv");
const response = await Axios({
method: "GET",
url: url,
responseType: "stream",
});
response.data.pipe(fs.createWriteStream(path));
return new Promise((resolve, reject) => {
response.data.on("end", () => {
resolve(updateMongoRecords());
next();
});
response.data.on("error", (err) => {
reject(err);
});
});
};
And getCases.js inside controllers/cases I have:
const Case = require("../models/case");
exports.getCases = async (req, res) => {
const cases = await Case.find().then((cases) => res.json(cases));
};
With this code I am able to fetch in the route /cases all the cases in the client side (like postman) and it shows all of them. But the problem is that I can´t make any other requests (like signing out, which works fine if I don´t make the get request for the cases like before) afterwards because client (postman) gives the error: GET http://localhost:5000/signout
Error: connect ECONNREFUSED 127.0.0.1:5000
in case you want to see the code for signout is like this:
const express = require("express");
const { signup, signin, signout } = require("../controllers/auth");
const router = express.Router();
router.post("/signup", userSignupValidator, signup);
router.post("/signin", userSigninValidator, signin);
router.get("/signout", signout);
inside controllers/auth.js:
exports.signout = (req, res) => {
res.clearCookie("t");
return res.json({ message: "Signout successfully done" });
};
Any help on this??

Resources