How to save a variable before serving a file in nodejs - javascript

given the following code:
const https = require('https');
const fs = require('fs');
var path = require('path');
const express = require('express');
const app = express();
const router = express.Router();
const pool = require('./mysqldb.js');
const pathView = __dirname + "/views/";
const IMGPath = "/public";
var bodyParser = require("body-parser");
const listenPort = 8010;
var id = null ;
router.get('/details/:id', async function (req, res, next) {
id = req.params.id;
if ( typeof req.params.id === "number"){id = parseInt(id);}
res.render('details.ejs' );
});
The main goal is to save that req.params.id(the id from the url) in the id variable before serving the details.ejs file.I tried to remove the async but didn't work.Can you help me please?

You can make use of the await keywords inside your async function like so:
router.get('/details/:id', async function (req, res, next) {
await (() => { id = req.params.id; })(); // Will run first
await (() => { res.send(id); })(); // Will run second
})
res.send(id) or res.render('details.ejs') ( in your case ) will run after the id is retrieved

It seems to be working fine for me. Below, I launch this server, then I go to http://localhost:3050/123 and suddenly I'm console.logging '123' over and over again, and the correct text displays on the screen.
So... idk what else if going on for you, but it might help if you try your best to distill your code down to the simplest possible iteration to try to debug. Just try to replicate it elsewhere. You might find one of your additional modules is causing an issue.
const express = require('express')
const app = express();
const port = 3050;
let id = null;
app.get('/:id', (req, res) => {
return res.send('Hello World!')
});
app.get('/details/:id', (req, res) => {
if (req.params.id){
id = req.params.id;
}
// 'id' will appear in browser
return res.send(`See details for id: ${id}`);
});
// console logs of 'id'
setInterval(() => { console.log(`id is currently ${id}`); }, 1000);
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
I don't think async/await will have any effect on this specific issue. I doubt they're related.

This seems to work for me,
router.get('/details/:id', async function (req, res, next) {
id = typeof req.params.id === 'number' ? parseInt(id) : req.params.id;
console.log(id);
res.send('details.ejs' );
});

Related

TypeError: Prismic.getApi is not a function

i'm really struggling while trying to build a website from scratch without a framework. And now i'm integrating Prismic in through node.js, but as I'm following all the passages i'm getting stuck by this error shown in the log of the terminal: TypeError: Prismic.getApi is not a function.
As a consequence of this i can see the local website but the about link doesn't load. How can i fix that?
This is the main code related to the package.json
require('dotenv').config()
console.log(process.env.PRISMIC_ENDPOINT, process.env.PRISMIC_CLIENT_ID)
const express = require('express')
const app = express()
const path = require('path')
const port = 3000
const Prismic = require('#prismicio/client')
const PrismicDOM = require('prismic-dom')
const initApi = req => {
return Prismic.getApi(process.env.PRISMIC_ENDPOINT, {
accessToken: process.env.PRISMIC_ACCESS_TOKEN,
req
})
}
const handlelinkResolver = doc => {
// Define the url depending on the document type
// if (doc.type === 'page'){
// return '/page/' + doc.uid;
// } else if (doc.type === 'blog_post'){
// return '/blog/' + doc.uid;
// }
// Default to homepage
return '/'
}
app.use((req, res, next) => {
res.locals.ctx = {
endpoint: process.env.PRISMIC_ENDPOINT,
linkResolver: handlelinkResolver
}
res.locals.PrismicDOM = PrismicDOM
next()
})
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.get('/', async (req, res) => {
res.render('pages/home')
})
app.get('/about', async (req, res) => {
initApi(req).then((api) => {
api.query(
Prismic.Predicates.at('document.type', 'about')
).then(response => {
console.log(response)
res.render('pages/about')
})
})
})
app.get('/personaggi', (req, res) => {
res.render('pages/personaggi')
})
app.get('/detail/:uid', (req, res) => {
res.render('pages/detail')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
You can use :
const Prismic = require('prismic-javascript')
// NB : This package has been deprecated but it's still working.
Instead of :
const Prismic = require('#prismicio/client')
OR you can use the actual setup guide of Prismic at https://prismic.io/docs/technologies/express-install
As user bmz1 mentionned, getApi() is no longer used in version 6+. Downgrade #prismicio/client.
In your package.json dependencies, replace by :
"#prismicio/client": "5.1.0"
Don't forget to run npm i to reset your dependencies

How to update content in dynamic URLs in Express?

Below have I created 3 URL's from the fn array. In real life, this would be approx 200 different filenames.
After I have created them, would I like to be able to update the content of the URL's to be either 1 or 0.
With the below PoC, the content doesn't change.
Question
Does anyone know how I can change the content of the URL's on-the-fly?
const express = require('express');
const app = express();
const fn = ['filename1', 'filename2', 'filename3'];
for (const e of fn) {
app.get(`/${e}`, (req, res) => {
res.send(e);
});
};
app.get(`/filename1`, (req, res) => {
res.send('test');
});
const port = 1900;
app.listen(port, () => {
console.log(`http://localhost:${port}/`);
});
You can create one wildcard route listener and add your logic inside of it
const express = require('express');
const app = express();
const fn = ['filename1', 'filename2', 'filename3'];
app.get("/*", (req, res) => {
// Do your logic inside
if(fn.includes(req.url.replace('/',''))) return res.send('ok');
res.status(404).send('Not Found');
});
const port = 1900;
app.listen(port, () => {
console.log(`http://localhost:${port}/`);
});

While running a MOCK API server in Node.js, getting an error message CANNOT GET /

I am getting "CANNOT GET/" error message while running a MOCK API server opening my localhost on port 3000 via my browser (http://localhost:3000) using the following index.js file. It's listening to the port at 3000 when I do the npm start run. When I try to open the browser it comes up with the error message above. Can you please tell me what I am doing wrong?
I have tried to replace const fixtures = require('./data/fixtures'); with app.use(express.static('./data/fixtures')); Run npm install and npm start run but it's still same error. Can someone please help?
"use strict";
const express = require('express');
const bodyParser = require('body-parser');
const port = 3000;
const hostname = '127.0.0.1';
const app = express();
app.use(bodyParser.json());
const fixtures = require('./data/fixtures');
let fixturesDB = JSON.parse(JSON.stringify(fixtures));
const HTTP_STATUS_CODE_NOT_FOUND = 404;
const getFixtureById = id =>
fixturesDB.find(fixture => fixture.fixtureId === id);
const getFixtureIndex = id =>
fixturesDB.findIndex(fixture => fixture.fixtureId === id);
const randomIntBetweenMinMax = (min, max) =>
Math.floor(Math.random() * max) + min;
const secondsToMillis = seconds => seconds * 1000;
const betweenOneAndFiveSecondsInMillis = () =>
secondsToMillis(randomIntBetweenMinMax(1, 5));
const delayPutAction = fixture =>
new Promise((resolve, reject) => {
setTimeout(() => {
fixturesDB.push(fixture);
resolve();
}, betweenOneAndFiveSecondsInMillis());
});
const checkIfFixtureExists = fixtureId => getFixtureIndex(fixtureId) !== -1;
const fixtureNotFound = res =>
res.status(HTTP_STATUS_CODE_NOT_FOUND).send("Fixture not found");
app.get("/fixtures", (req, res) => res.json(fixturesDB));
app.get("/fixture/:id", (req, res) => {
const fixtureId = req.params.id;
checkIfFixtureExists(fixtureId)
? res.json(getFixtureById(fixtureId))
: fixtureNotFound(res);
});
app.post("/fixture", async (req, res) => {
await delayPutAction(req.body);
res.send("Fixture has been added");
});
app.delete("/fixture/:id", (req, res) => {
const fixtureId = req.params.id;
if (checkIfFixtureExists(fixtureId)) {
fixturesDB = fixturesDB.filter(fixture => fixture.fixtureId !== fixtureId);
res.send("Fixture has been deleted");
} else {
fixtureNotFound(res);
}
});
app.listen(port, hostname, () => console.log("Server is listening on port 3000"));
The url http://localhost:3000 should display the content of the ./fixtures which are the reponse Json data instead of the error message "CANNOT GET/"
You don't have a '/' route, hence CANNOT GET /. If you want it to point to an existing '/fixture' route, you can do something like app.get('/', (req, res) => res.redirect('/fixtures'))
You could use static middleware (although it's not very appropriate in your case):
you need to point it to a directory, e.g. app.use('/', express.static('./data/fixtures'))
the files in ./data/fixtures/ directory are made available at the specified route, e.g. http://localhost:3000/fixtures/list.html points to './data/fixtures/list.html'
you can override a default index file for static middleware, e.g. app.use('/', express.static('./data/fixtures', {index: 'list.html'})) will make http://localhost:3000 show ./data/fixtures/list.html

how to fix "can't read property push of undefined" error in Nodejs?

I have coded a simple app to learn Nodejs but when i run "nodemon index.js" in cmd i have this error
TypeError: Cannot read property 'push' of undefined
app crashed - waiting for file changes before starting...
i have follow all instruction in the udemy course for learn nodejs
and i faced this problem when i separated the file into two files index.js and genres.js
genres.js
const express = require('express');
const router = express.Router;
//simple data
const genres = [{
id: 1,
name: 'course1'
},
{
id: 2,
name: 'course2'
},
{
id: 3,
name: 'course3'
}
];
//////////////////////////////////////////////////////////////////////
/////////////////////////////////// Get //////////////////////////////
//////////////////////////////////////////////////////////////////////
router.get('/', (req, res) => {
res.send(genres);
});
router.get('/:id', (req, res) => {
const genre = genres.find(c => c.id ===
parseInt(req.params.id)); //req.params.id return string
if (!genre)
return res.status(404).send('The course is not found...');
res.send(genre);
res.send(req.params.id);
});
router.get('/:year/:month', (req, res) => {
res.send(req.params);
});
router.post('/', (req, res) => {
const {
error
} = validategenre(req.body);
if (error)
return res.status(400).send(error.details[0].message);
const genre = {
id: genres.length + 1,
name: req.body.name
}
genres.push(genre);
res.send(genre);
});
router.put('/:id', (req, res) => {
const genre = genres.find(c => c.id === parseInt(req.params.id));
if (!genre)
return res.status(404).send('The course does not exist !!! ');
const result = validategenre(req.body);
if (result.error)
return res.status(400).send(result.error.details[0].message);
genre.name = req.body.name;
res.send(genre);
});
function validategenre(genre) {
const schema = {
name: Joi.string().min(3).required()
};
return Joi.validate(genre, schema);
}
module.exports = router;
index.js
const Joi = require('joi');
const genres = require('./routes/genres');
const express = require('express');
const app = express();
app.use(express.json());
app.use('/api/genres', genres);
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listining on port ${port}...`));
In genres.js, you should import
const router = express.Router();
instead of
const router = express.Router;
Also, the error you mention could be from any push in your code (without any more info), please specify the stacktrace next time :)
Use const router = express.Router() instead of const router = express.Router.
It can be wrong variable name :)
I made a mistake due to intelligence in my quick sample -
Typically signature of a ReST call is
router.get("/something", (req: any, res: any, next: any) => {
response.write("test");
response.end();
});
Here if you will notice I was using response where as i was suppose to use res
Moreover ensure you have registered your routes using
app.use(router);

Route.delete() requires a callback function but got a [object Object]

I have node-express app where I have bunch of Routes for login, logout and signup and one Route for checking authorised Route which can be accessed only through providing authToken. I moved the Routes to separate Route file and I got the above error.
This is my Users Routes File:
const express = require('express');
const authenticate = require('./../middleware/authenticate');
const router = express.Router();
const {User} = require('./../models/user');
router.post('/',(req, res) => {
var body = _.pick(req.body,['email','password']);
var user = new User(body);
user.save().then(() => {
return user.generateAuthToken()
}).then((token) => {
res.header('x-auth', token).send(user);
}).catch((e) => {
res.status(400).send(e);
});
});
router.post('/login',(req, res) => {
var body = _.pick(req.body, ['email', 'password']);
User.findByCredentials(body.email, body.password).then((user) => {
return user.generateAuthToken().then((token) => {
res.header('x-auth', token).send(user);
});
}).catch((e) => {
res.status(400).send(e);
});
});
router.delete('/logout',authenticate, (req, res) => {
req.user.removeToken(req.token).then(() => {
res.status(200).send();
},(e) => {
res.status(400).send(e);
}) ;
});
router.get('/me',authenticate, (req,res) => {
res.send(req.user);
});
module.exports = router;
Following is my main server.js file:
const express = require('express');
const _ = require('lodash');
var app = express();
const usersRoutes = require('./routes/users');
app.use(express.json());
app.use('/users', usersRoutes);
var {mongoose} = require('./db/mongoose');
var {User} = require('./models/user');
var {authenticate} = require('./middleware/authenticate');
const port = process.env.PORT || 3000 ;
app.listen(port, () => console.log(`Listening on ${port}...`))
I have a model/Schema(mongoose) file for User so If You feel you need that I am ready to edit my question. Thanks.
The problem is that router.delete is expecting a function on the middleware parameter (like you did in your server.js file with app.use(express.json())) so it can be used like a callback which gets called whenever a request reach your route.
Try changing authenticate to authenticate().
It seems like in your users routes file you are importing the entire module who contains the authenticate function, so when try to access it like a function you'll get an error. You need to import it like you did in your server.js file.
Change the line const authenticate = require('./../middleware/authenticate'); for const {authenticate} = require('./../middleware/authenticate');.

Categories