First NodeJS app - how can I fix MODULE NOT FOUND and other issues?
Application Summary
This is my first time writing a NodeJS application and it's just a learning project. This is a simple CRUD web application for managing projects . For the first project, I tried to follow some best practices I've learned from other languages, which is to try to separate the input, processing, and output of the application .
question
It didn't work I know there are several issues preventing this from working properly, but I've tried my best. I don't know how to proceed.
Problem 1: Module not found
Error: Cannot find module 'C:\wamp64\www\aaa-node-mvc\server.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:982:15)
at Function.Module._load (internal/modules/cjs/loader.js:864:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
at internal/main/run_main_module.js:18:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
Question 2-n: Since I don't know how to solve question 1, I'm not sure how to solve the next question - I already know.
How do we perform the insert when we hit the /create route and then depending on the result, then display the page with the corresponding message
So basically, question 2 is, how is the /create route done? I know I need to redirect the user to a " success" page, or display a failure message .
I'm not sure where to show the createPage function .
my folder structure
I decided to build my app like this:
file description
- app/config/db.config.js - exports MySQL connection information
- app/models/db.js - connect to database
- app/routes/item-routes.js - defines all routes for "item"
- app/controllers/item-controller.js - has methods for items (create, delete, etc)
- app/models/item-model.js - handles the actual data manipulation
- app/views/index.ejs - homepage
- app/views/item-add.ejs - create item page
source code
index.js
// Dependencies
const bodyParser = require("body-parser");
const app = express();
const {getHomePage} = require('./app/routes/item-routes');
// Enable content-types
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Define Routes
app.get('/', getHomePage);
require("./app/routes/item-routes.js")(app);
// Listen for requests
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port: <a href='${port}'>RUN</a>`);
});
./app/config/db.js
module.exports = {
HOST: "localhost",
USER: "root",
PASSWORD: "",
DB: "marketplace"
};
./app/routes/item-routes.js
module.exports = app => {
const items = require("../controllers/item-controller.js");
}
// ROUTE FOR: Creating a new item
app.post("/items", items.create);
app.get("/items", items.createPage);
module.exports = {
getHomePage: (req, res) => {
res.render('index.ejs', {
title: "Welcome to ITEMS Homepage"
});
},
};
./app/controllers/item-controller.js
const Item = require("../models/item-model.js");
// Create and Save a new Item
exports.create = (req, res) => {
// Validate request
if (!req.body) {
res.status(400).send({
message: "Item can not be empty!"
});
}
const item = new Item({
title: req.body.title,
price: req.body.price,
location: req.location,
imgUrl: req.body.imgUrl,
itemURL: req.body.itemURL,
is_deleted: req.body.is_deleted
});
// Insert Item
Item.create(item, (err, data) => {
if (err)
res.status(500).send({
message: err.message || "Error inserting Item into the database."
});
else res.send(data);
});
};
./app/models/item-model.js
const sql = require("./db.js");
// Constructor
const Item = function(item) {
this.title = item.title;
this.price= req.body.price;
this.location= req.location;
this.imgUrl =req.body.imgUrl;
this.itemURL= req.body.itemURL;
this.is_deleted= req.body.is_deleted;
};
// Create and Save a new Item
Item.create = (newItem, result) => {
sql.query("INSERT INTO jeeps SET ?", newItem, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created item: ", { id: res.insertId, ...newItem });
result(null, { id: res.insertId, ...newItem });
});
};
module.exports = Item;
./app/views/item-add.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=title%></title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<div class="container">
<form action="" method="POST">
<div class="form-group row">
<label for="title" class="col-4 col-form-label">Title</label>
<div class="col-8">
<input id="title" name="title" type="text" class="form-control" required="required">
</div>
</div>
<div class="form-group row">
<label for="price" class="col-4 col-form-label">Price</label>
<div class="col-8">
<input id="price" name="price" type="text" class="form-control" required="required">
</div>
</div>
<div class="form-group row">
<label for="location" class="col-4 col-form-label">Location</label>
<div class="col-8">
<input id="location" name="location" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="imgUrl" class="col-4 col-form-label">ImgUrl</label>
<div class="col-8">
<input id="imgUrl" name="imgUrl" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="itemURL" class="col-4 col-form-label">Item URL</label>
<div class="col-8">
<input id="itemURL" name="itemURL" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="is_deleted" class="col-4 col-form-label">Is Deleted</label>
<div class="col-8">
<input id="is_deleted" name="is_deleted" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<div class="offset-4 col-8">
<button name="submit" type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
</body>
</html>
SQL
-- phpMyAdmin SQL Dump
-- version 4.9.2
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1:3306
-- Generation Time: May 13, 2020 at 04:11 AM
-- Server version: 5.7.28
-- PHP Version: 7.3.12
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `marketplace`
--
-- --------------------------------------------------------
--
-- Table structure for table `jeeps`
--
DROP TABLE IF EXISTS `jeeps`;
CREATE TABLE IF NOT EXISTS `jeeps` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`price` varchar(255) DEFAULT NULL,
`location` varchar(255) DEFAULT NULL,
`itemURL` text,
`imgUrl` text,
`is_deleted` tinyint(1) NOT NULL,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
--
-- Dumping data for table `jeeps`
--
INSERT INTO `jeeps` (`id`, `title`, `price`, `location`, `itemURL`, `imgUrl`, `is_deleted`, `created_date`) VALUES
(1, '1999 Jeep Wrangler', '$5,998', 'Tampa', 'http://localhost/fgdgdgfd', 'http://localhost/fgdgdgfd/ffd.jpg', 0, '2020-05-09 17:48:21'),
(2, '2001 Jeep Wrangler Sport', '$9000', 'Mass', 'http://www.', 'http://img', 0, '2020-05-12 03:35:35');
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Final Thoughts No doubt you are new to NodeJS. Also, I pieced this application together by using code from various tutorials. I think I'm pretty close to solving the problem, but you'll know more. Any help would be greatly appreciated. I'm just stuck.
thanks.
For the first question, you are trying to access a file that does not exist. Can only guess since you didn't post your package.json file, but I think it's in the startup script. The start script should be node run index.js
not node run server.js
.
For your second question, I don't know what you expect the /create route to do, but POST /item seems to have served its purpose. Just set the form action to "/item" to create a new item. You can then display a success or failure message in the Item.create
callback function .
I'm not sure where to show the createPage function.
Maybe put a link in your index.ejs file that navigates to the page as ("/items")
Beyond your question, your code still has a lot of bugs. console.log
is your friend. Log the functions you expect to be called to see if they are actually called and what data is passed to the function. Start there.
You also shouldn't assign multiple times directly module.exports
in one file (as you do in ./app/item-routes.js). Also, like when using module.exports
something exports
exported from a file.
Read about JavaScript scope definitions. Function parameters can only be accessed within that function and any variables declared within the function ( exceptions to this are made when using the var
keyword , so using let
and is recommended const
). So trying to access properties app
in ./app/item-routes.js throws an error.
I would also recommend moving the getHomePage()
functionality out of the project route file as it is not related to the project. Maybe put it directly in the base index.js
file, or create a separate route for it.