John S.
John S.

Reputation: 514

First NodeJS Application - How do I resolve MODULE NOT FOUND, and other issue?

Application Summary

This is my first attempt at writing a NodeJS application, and this is a learning project only. It's a simple CRUD web application to manage items. For this first project, I am trying to follow some best practices I have learned in other languages, namely, trying to keep separate the input, processing, and output of the application.

The Problem(s)

It don't work. I know there are a couple issues preventing this from running properly, but I have gone as far as I can. 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: []

Problem #2 - n: Since I can't figure out how to get by problem #1, I am unsure of how to address my next problem - which I already know.

When we hit the /create route, how do I perform the insert, and THEN based on the outcome, display a page with appropriate message

So basically, Problem #2 is, how do I finish the /create route? I know somewhere I need to re-direct the user either to a SUCCESS page, or display a failure message.

I am unsure where to put the createPage function to display the form.

My Folder Structure

I decided on structuring my app like this:

Files

File Descriptions

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 As you have no-undoubtedly figured out, I am VERY new to NodeJS. Also, I have pieced this app together by using code from various tutorials. I would like to think I am close to getting the problem resolved, but you would know better. Any help would be greatly appreciated. I am just plain stuck.

Thank you.

Upvotes: 0

Views: 378

Answers (1)

Benz Stevox
Benz Stevox

Reputation: 162

For your 1st problem, you're trying to access a file that doesn't exist. Since you did not post your package.json file, I can only guess but I think it's in the start script. The start script should be node run index.js rather than node run server.js.

For the 2nd problem, I don't know what you expect the /create route to do but it appears that its purpose is already being fulfilled by the POST /item. Just set the form action to "/item" to create a new item. You can then show the success or failure message in the Item.create callback function.

I am unsure where to put the createPage function to display the form.

Maybe put a link in your index.ejs file that navigates to the page with the form ("/items")


Outside of your questions, there's still quite a number of errors with your code. console.log is your friend. Log within functions that you expect are being called to see if they are actually being called and what data is being passed to the function. Work your way up from there.

You should also not directly assign to module.exports more than once in a single file (as you did in ./app/item-routes.js). Also, prefer using module.exports over exports when exporting stuff from a file.

Read up on scoping in JavaScript. Function parameters are only accessible within that function as well as any variables declared within it (there's exceptions to this when using the var keyword so prefer using let and const). Trying to access properties of app in ./app/item-routes.js will throw an Error because of this.

I would also recommend moving the getHomePage() function out of the items-route file since it has nothing to do with items. Maybe put it directly in your base index.js file or create a separate route for it.

Upvotes: 1

Related Questions