I was actually following a nodejs course on Udemy and suddenly down the course, the code started breaking and giving some errors. I then tried copying the instructor's code, but still, the problem was the same.
I also followed this answer on StackOverflow itself but the problem remains the same.
I am attaching all the js files below and also the error message from the terminal below:
Error message from the terminal
This is what the file structure looks like
Now the js files:
app.js file:
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const errorController = require('./controllers/error');
const app = express();
app.set('view engine', 'ejs');
app.set('views', 'views');
app.use(bodyParser.urlencoded({extended:false}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.use(errorController.get404Page);
app.listen(3000);
controllers/error.js file:
exports.get404 = (req, res, next) => {
res.status(404).render('404', { pageTitle: 'Page Not Found' });
};
controllers/products.js file
const Product = require('../models/product');
exports.getAddProduct = (req, res, next) => {
res.render('add-product', {
pageTitle: 'Add Product',
path: '/admin/add-product',
formsCSS: true,
productCSS: true,
activeAddProduct: true
});
};
exports.postAddProduct = (req, res, next) => {
const product = new Product(req.body.title);
product.save();
res.redirect('/');
};
exports.getProducts = (req, res, next) => {
Product.fetchAll(products => {
res.render('shop', {
prods: products,
pageTitle: 'Shop',
path: '/',
hasProducts: products.length > 0,
activeShop: true,
productCSS: true
});
});
};
models/product.js file :
const fs = require('fs');
const path = require('path');
const p = path.join(
path.dirname(process.main.filename),
'data',
'products.json'
);
const getProductsFromFile = cb => {
fs.readFile(p, (err, fileContent) => {
if (err) {
cb([]);
} else {
cb(JSON.parse(fileContent));
}
});
};
module.exports = class Product {
constructor(t) {
this.title = t;
}
save() {
getProductsFromFile(products => {
products.push(this);
fs.writeFile(p, JSON.stringify(products), err => {
console.log(err);
});
});
}
static fetchAll(cb) {
getProductsFromFile(cb);
}
};
routes/admin.js file:
const path = require('path');
const express = require('express');
const productsController = require('../controllers/products');
const router = express.Router();
// /admin/add-product => GET
router.get('/add-product', productsController.getAddProduct);
// /admin/add-product => POST
router.post('/add-product', productsController.postAddProduct);
module.exports = router;
routes/shop.js file:
const path = require('path');
const express = require('express');
const productsController = require('../controllers/products');
const router = express.Router();
router.get('/', productsController.getProducts);
module.exports = router;
util/path.js file:
const path = require('path');
module.exports = path.dirname(process.main.filename);
I am new to backend development, nodejs to be specific. Please help me find my mistake.
In many file you have used process.main.filename, but there is no property named process.name for node.js process, so process.main is undefined. As a result reading the property process.main.filename gives the error.
So, to solve your problem:
Replace every process.main.filename with
process.mainModule.filename OR require.main.filename
(there is difference in both, but it will not matter in your app.)
and see if it works. I guess this is a mistake on your part while writing the code.
Tip: Always try to understand the error using terminal output. That way You can solve most of the problems.
Related
I'm trying to create a Note taker app, but when click on save any information, is coming a TypeError: Cannot read properties of undefined (reading 'push')
Below the code for Note.js
const path = require('path');
const fs = require('fs');
const uniqid = require('uniqid');
let noteList = [];
function findById(id, noteList) {
return noteList.filter(note => note.id === id)[0];
}
function addNewNote(body, noteList) {
let newNote = body;
newNote.id = uniqid();
noteList.push(newNote);
fs.writeFileSync(
path.join(__dirname, '../db/db.json'),
JSON.stringify({db: noteList}, null, 2)
);
return newNote;
}
function removeNote (id, noteList) {
const removeThisNote = findById(id, noteList);
for (let i = 0; i<noteList.length; i++){
if (noteList[i].id === removeThisNote.id) {
noteList.splice(i, 1);
fs.writeFileSync(
path.join(__dirname, '../db/db.json'),
JSON.stringify({db: noteList}, null, 2)
);
}
};
}
module.exports = {
findById,
addNewNote,
removeNote
};
api index.js
const router = require('express').Router();
const {db} = require('../db/db.json');
const { addNewNote, removeNote} = require('../lib/note.js');
router.get('/notes', (req, res) => {
let results = db;
res.json(results);
})
router.post('/notes', (req, res) => {
const newNote = addNewNote(req.body, db);
res.json(newNote);
})
router.delete('/notes/:id', (req, res) => {
removeNote(req.params.id, db);
res.json(req.body);
})
module.exports = router;
Server.js
const express = require(`express`);
const apiRoutes = require('./routes/apiRoutes.js');
const path = require('path');
// const htmlRoutes = require('./routes/htmlRoutes.js');
const PORT = process.env.PORT || 3001;
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/api', apiRoutes)
// app.use('/', htmlRoutes)
app.use(express.static(`public`));
//Routes
app.get(`/notes`, (req, res) => {
console.log(`Note page requested`);
res.sendFile(path.join(__dirname, `public/notes.html`));
});
app.get(`/`, (req, res) => {
console.log(`Home page requested`);
res.sendFile(path.join(__dirname, `public/index.html`));
});
app.listen(PORT, () =>
console.log(`App listening at http://localhost:${PORT}`)
);
Can anyone help with this ?
I want to deploy this using Heroku but when testing save any info, error comes up.
push() is an Array method. Therefore, the error shows that some variable is not array but undefined.
The addNewNote function contains a variable called noteList and the error says it is not an array.
So, the argument you pass to this function is not an array.
I suggest you check the db variable you import from db.json and see if this is an array because this is the variable you pass as an argument in addNewNote.
I created a simple application. Until I split the application code into an MVC template, everything worked. Below I present the code of my application. After going to localhost:3000/add-service you will see Cannot Get /add-service message.
Where is the problem that I unfortunately cannot solve?
app.js
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const expressLayouts = require('express-ejs-layouts');
const adminRoutes = require('./Routes/admin');
const shopRouters = require('./Routes/shop');
const app = express();
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.set('views', './views');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/add-service', adminRoutes);
app.use(shopRouters);
app.use('/', (req, res, next) => {
res.status(404).render('./pages/404', {
title: '404 Page Not Found',
path: '',
});
});
app.listen(3000);
admin.js - this is my router file
const express = require('express');
const router = express.Router();
const bikesController = require('../controllers/bikes');
router.get('/add-service', bikesController.getAddBike);
module.exports = router;
bikes.js - this is my controller
const bikes = [];
exports.getAddBike = (req, resno) => {
res.render('../views/pages/add-service', {
path: 'pages/add-service',
title: 'Add in Service',
});
};
exports.postAddBike = (req, res) => {
bikes.push({ title: req.body.bikeModel });
res.redirect('/');
};
exports.getBikes = (req, res) => {
res.render('./pages/shop', {
model: bikes,
docTitle: 'List of Bikes',
path: '/',
title: 'Main Page',
});
};
App Tree
app.use('/add-service', adminRoutes);
You've mounted adminRoutes at /add-service
router.get('/add-service', bikesController.getAddBike);
The only end point that service provides is /add-service
Combine them and you have the URL: /add-service/add-service, which isn't what you are asking for.
The point of the router is that it doesn't need to know about the URLs above where it sits.
The router should just be dealing with its own section of the URL hierarchy:
router.get('/', bikesController.getAddBike);
I am looking to start including my route files in my Node.js and express application. However, when I require the local route files into my server.js file, and try to run that on Nginx, I get a 502 Bad Gateway error.
The code that is giving me trouble is currently commented out. Any ideas on what might be causing this performance?
server.js
require('dotenv').config();
const express = require('express');
const bodyparser = require('body-parser');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
// const oidc = require('./okta');
// const searchRouter = require('./routes/search');
// const inputRouter = require('./routes/input');
// const dataRouter = require('./routes/view-all');
const app = express();
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.sendFile(__dirname + '/views/index.html');
});
app.get('/page', function(req, res) {
res.render(__dirname + '/views/optishop.ejs');
});
const listener = app.listen(8080, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
Edit: This is the file being required in the searchRouter declaration.
search.js
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const oidc = require('../okta');
const router = express.Router();
router.post('/search', oidc.ensureAuthenticated(), async (req, res) => {
await MongoClient.connect(
process.env.MONGODB_URI,
{ useUnifiedTopology: true },
async (err, client) => {
assert.equal(null, err);
const db = client.db('test');
const arr = req.body.item.trim().split(/; */gi);
const user = req.session.passport.user.userinfo.sub;
const cursor = await db
.collection('test')
.find({
user
})
.toArray();
const filteredCursor = cursor.filter(obj => {
return arr.includes(obj.item);
});
res.render('index', {
cursor: filteredCursor
});
// res.send(filteredCursor);
client.close();
}
);
});
module.exports = router;
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);
I am trying to get server side rendering set up in a Vue application. I have imported the server side renderer bundle and I believe included everything necessary for it to work, however, when refreshing my webpage I am getting the error Cannot read property 'renderToString' of undefined from my server.js file.
I've tried to debug but it appears as though my bundle never gets set to anything and so is always undefined.
dev-server.js
const webpack = require('webpack')
const clientConfig = require('./webpack.client.config')
const serverConfig = require('./webpack.server.config')
const MFS = require('memory-fs')
const path = require("path")
module.exports = function setupDevServer (app, onUpdate) {
clientConfig.entry.app = [
'webpack-hot-middleware/client',
clientConfig.entry.app
]
clientConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
)
const clientCompiler = webpack(clientConfig)
app.use(
require('webpack-dev-middleware')(clientCompiler, {
stats: {
colors: true
}
})
)
app.use(require('webpack-hot-middleware')(clientCompiler))
const serverCompiler = webpack(serverConfig)
const mfs = new MFS()
const outputPath = path.join(serverConfig.output.path, 'server/main.js')
serverCompiler.outputFileSystem = mfs
serverCompiler.watch({}, () => {
onUpdate(mfs.readFileSync(outputPath, 'utf-8'))
})
}
server.js
const express = require("express");
const app = express();
const fs = require("fs");
const path = require("path");
const { createBundleRenderer } = require('vue-server-renderer');
let renderer;
const indexHTML = (() => {
return fs.readFileSync(path.resolve(__dirname, "./index.html"), "utf-8");
})();
app.use("/dist", express.static(path.resolve(__dirname, "./dist")));
require("./build/dev-server")(app, bundle => {
renderer = createBundleRenderer(bundle)
});
app.get("*", (req, res) => {
renderer.renderToString({ url: req.url }, (err, html) => {
if (err) {
return res.status(500).send('Server Error')
}
html = indexHTML.replace('{{ APP }}', html)
res.write(html);
res.end();
})
});
const port = process.eventNames.PORT || 3000;
app.listen(port, () => {
console.log(`server started at http://localhost:${port}`);
});