I cannot get my post meetingtype route to work. the problem seems to be between my model and my DAO as some of my code tweaking got MeetingType.create is not a function errors. Currently I just get Cannot POST /api/meetingtype in insomnia. The Sequelize create is not a function answers on stack overflow arn't helping. Here is my code:
//database/index
const { Sequelize } = require('sequelize');
const DB = new Sequelize({
dialect: 'sqlite',
storage: 'C:/Users/bubblegum/Desktop/programming projects/Oconnell/database/db.db',
define: {timestamps: false}
}
);
module.exports.DB = DB;
//models/meetingtype.js
'use strict';
const DB = require('../database/index');
const { Sequelize, Model, DataTypes, INTEGER} = require('sequelize');
module.exports = (DB, DataTypes) => {
class MeetingType extends Model {
static associate(models) {
// define association here
}
};
MeetingType.init({
MeetingTypeID: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
MeetingTypeDescription: DataTypes.STRING
}, {
DB,
modelName: 'MeetingType',
});
return MeetingType;
};
/DAO/MeetingTypeDAO.js
const Sequelize = require('sequelize'); // attempt to get create to work
const DB = require('../database/index').DB;
const MeetingType = require('../models/MeetingType');
var MeetingTypeDao = {
create: create
}
function create(MeetingType) {
MeetingType.create(MeetingType).then(NewMeetingType => { //MeetingType is json of not autoincrement properties
return NewMeetingType;
});
}
module.exports = MeetingTypeDao;
//controllers/MeetingTypeController.js
const MeetingTypeDao = require('../DAO/MeetingTypeDao');
var MeetingTypeController = {
addMeetingType: addMeetingType
}
function addMeetingType(req, res) {
MeetingTypeDao.create(req.body). //json of non autoincrement MeetingType properties
then((MeetingType) => {
res.send(MeetingType);
})
.catch((error) => {
console.log(error);
});
}
module.exports = MeetingTypeController;
//routers/MeetingTypeRouter
const Express = require('express');
const router = Express.Router();
const MeetingTypeController = require('../Controllers/MeetingTypeController');
router.post('/', MeetingTypeController.addMeetingType);
module.exports = router;
//app.js
const Express = require('express');
const { Sequelize } = require('sequelize');
const {DB} = require('./database');
let app = Express();
const MeetingTypeRouter = require('./routers/MeetingTypeRouter');
app.use(Express.urlencoded({ extended: true }));
app.use(Express.json());
app.use('api/meetingtype', MeetingTypeRouter);
DB.authenticate().then(()=>{
console.log('Connection has been established successfully.');
}).catch(err => console.log("Error: " + err));
const PORT = process.env.PORT || 3000;
try {
app.listen(PORT, console.log(`Server started on port ${PORT}`));
} catch (error) {
console.log("Error: " + error);
};
Related
I'm following this tutorial and I'm stuck at the end. getting 404's in postman when using POST with this URL http://localhost:5050/api/projects its been 3 days any one know what I'm doing wrong?
server.js
const express = require("express");
const app = express();
const PORT = 5050;
// Connect to the database
require("./src/server/database/connection");
const bodyParser = require("body-parser");
const cors = require("cors");
var corsOptions = {
origin: "http://localhost:5051"
};
app.use(cors(corsOptions));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Code Wire Server." });
});
require("./src/server/routes/routes")(app);
app.listen(PORT, () => {
console.log(`Server is listening at http://localhost:${PORT}`);
});
connection.js
How to connect to the database
const db = require("../model/index.js");
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
index.js
const dbConfig = require("../config/db.config.js");
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.url = dbConfig.url;
db.project = require("./projects_db.js")(mongoose);
module.exports = db;
db.config.js
module.exports = {
url: "mongodb://127.0.0.1:27017/code-wire-db"
}
projects_db.js
A database schema for my project I'm working on
module.exports = mongoose => {
var schema = mongoose.Schema({
project_title: String,
description: String,
} );
schema.method("toJSON", function() {
// eslint-disable-next-line no-unused-vars
const { __v, _id, ...object } = this.toObject();
object.id = _id;
return object;
});
const projectsDB = mongoose.model("projectsDB", schema);
return projectsDB;
projects_controller.js
const db = require("../model/index");
const project = db.project;
// Create and Save a new project
exports.create = (req, res) => {
// Validate request
if (!req.body.title) {
res.status(400).send({ message: "Content can not be empty!" });
return;
}
// Create a project
const Project = new project({
project_title: req.body.project_title,
description: req.body.description
});
// Save project in the database
Project
.save(Project)
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the Project."
});
});
};
routes.js
module.exports = app => {
const projects = require("../controller/projects_controller.js");
var router = require("express").Router();
// Create a new project
router.post("/", projects.create);
app.use('/api/projects', router);
};
I found the problem.
[![problem][1]][1]
See that return symbol, I found out 4 days later that means there is 2 lines or more. Meaning postman was sending 2 lines instead of one. With no error message
[1]: https://i.stack.imgur.com/VVlha.jpg
I am building a MERN app and when I try to console.log(req.file) on the server I get undefined. I've checked the multer github page and other SO articles, but I still haven't been able to figure it out using React hooks and jsx. I'm newish to SO so, I will add edits since I can't comment yet.
Here is a link to the branch in GitHub if you want to see all the files. https://github.com/BenjDG/puzzle-gallery/tree/so
I'm new to multer and react so any help is appreciated.
Here is my code:
server\controllers\puzzleController.js
const multer = require('multer');
const upload = multer({ dest: './uploads'});
const db = require('../models');
const fs = require('fs');
const type = upload.single('picFile');
// Defining methods for the puzzleController
module.exports = {
findAll: function (req, res) {
db.Puzzle
.find(req.query)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
save: (type, function (req, res) {
// console.log(req);
console.log(req.file);
console.log(req.body);
res.sendStatus(200);
}),
remove: function (req, res) {
db.Puzzle
.findById({ _id: req.params.id })
.then(dbModel => dbModel.remove())
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
}
};
client\src\components\gallery\index.js
import React, { useState } from 'react';
import './styles.css';
import API from '../../services/API';
export default function Gallery () {
const [picFile, setPicFile] = useState();
const handleGetClick = async () => {
API.findAll()
.then(res => {
console.log(res)
})
.catch(err => console.error(err))
}
const handleUploadClick = async (e) => {
e.preventDefault();
// console.log(picFile);
// create new formData instance
const bodyFormData = new FormData();
// append single file to formData instance
bodyFormData.append('picFile', picFile.selectedFile);
// log items in formData object
for (const element of bodyFormData) {
console.log(element);
}
// send formData obj to axios function
API.save(bodyFormData)
.then(res => {
//console.log(res)
})
.catch(err => console.error(err))
}
const onFileChange = (e) => {
console.log(`e.target.files[0]`, e.target.files[0])
setPicFile({ selectedFile: e.target.files[0] });
}
return (
<div>
<h1>My Puzzle Gallery</h1>
<form encType='multipart/form-data'>
<input type='file' name='picFile' onChange={onFileChange} />
<br />
<br />
<button onClick={handleUploadClick}>Upload a picture</button>
</form>
<br />
<br />
<button onClick={handleGetClick}>Get pictures</button>
<br />
<br />
<img src='https://placekitten.com/640/360' alt='kitten' />
</div>
);
}
client\src\services\API.js
import axios from 'axios';
const API = {
login: (username, password) => {
const obj = {
username: username,
password: password
};
return axios.post('/api/auth/login', obj);
},
register: (username, password) => {
const obj = {
username: username,
password: password
};
return axios.post('/api/auth/register', obj);
},
logout: function () {
return axios.get('api/auth/logout');
},
save: function (form) {
return axios.post('api/puzzle/', form).catch(err=>console.error(err));
},
findAll: function () {
return axios.get('api/puzzle/');
},
}
export default API;
server\routes\api\puzzle\index.js
const router = require('express').Router();
const puzzleController = require('../../../controllers/puzzleController');
// Matches with '/api/puzzle'
router.route('/')
.get(puzzleController.findAll)
.post(puzzleController.save);
// Matches with '/api/books/:id'
router.route('/delete/:id')
.delete(puzzleController.remove);
module.exports = router;
server\server.js
const path = require('path');
const express = require('express');
const passport = require('./config/passport');
const mongoose = require('mongoose');
const cors = require('cors');
const session = require('express-session');
const helmet = require('helmet');
const morgan = require('morgan');
const corsOptions = require('./config/cors.js');
const routes = require('./routes');
const { v1: uuidv1 } = require('uuid');
// console.log(uuidv1());
const PORT = process.env.PORT || 3001;
const app = express();
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/puzzlegallery', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
});
mongoose.set("useCreateIndex", true);
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(helmet({ contentSecurityPolicy: false }));
app.use(session({ secret: 'sassy', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(cors(corsOptions));
app.use(morgan('dev'));
app.use(routes);
// for Reactjs ##################
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
}
// #################################################
if (process.env.NODE_ENV === 'production') {
app.get('*', (_, res) => {
res.sendFile(path.join(__dirname, '../client/build/index.html'));
});
}
app.listen(PORT, (err) => {
if (err) throw err;
console.log(
`🌎 Server is Ready and Listening on http://localhost:${PORT}`
); // eslint-disable-line no-console
});
EDIT:
This seemed to work. Thanks again!!
const path = require('path');
const router = require('express').Router();
const puzzleController = require('../../../controllers/puzzleController');
const multer = require('multer');
const { v1: uuidv1 } = require('uuid');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../../../../tmp/my-uploads'))
},
filename: function (req, file, cb) {
cb(null, uuidv1())
}
})
const upload = multer({ storage: storage });
// Matches with '/api/puzzle'
router.route('/')
.get(puzzleController.findAll)
// Matches with '/api/books/:id'
router.route('/delete/:id')
.delete(puzzleController.remove);
router.use(upload.single('picFile'));
router.route('/')
.post(puzzleController.save);
module.exports = router;
you cannot call the middleware inside the save function like this.
I cloned your repo and added the following code in server.js and it's working fine and I got the value in the req.file.
const multer = require('multer');
const upload = multer({ dest: 'uploads/'});
app.post('/api/puzzle/', upload.single('pictureFile'),(req,res,next)=>{
console.log("req.file22222222", req.file);
})
I am trying to insert a category and it is not sending its 'name' to the database. On Postman and Robo Mongo I see that I sent '_id', 'createdAt', 'updatedAt' and "_V" all correctly. But the 'name' is not sending. Does anyone know what's going on? Thanks.
app.js
const express = require('express')
const mongoose = require('mongoose')
const morgan = require('morgan')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const expressValidator = require('express-validator')
require('dotenv').config()
//import routes
const authRoutes = require('./routes/auth')
const userRoutes = require('./routes/user')
const categoryRoutes = require('./routes/category')
// app
const app = express()
// db
mongoose.connect(process.env.DATABASE, {
useNewUrlParser: true,
useCreateIndex: true
})
.then(() => console.log('DB Connected'))
// middlewares
app.use(morgan('dev'))
app.use(bodyParser.json())
app.use(cookieParser())
app.use(expressValidator())
// routes middleware
app.use('/api', categoryRoutes)
const port = process.env.PORT || 8000
app.listen(port, () => {
console.log(`Server is running on port ${port}`)
})
controllers/category.js
const Category = require("../models/category")
const { errorHandler } =
require("../helpers/dbErrorHandler")
exports.create = (req, res) => {
const category = new Category(req.body)
category.save((err, data) => {
if(err) {
return res.status(400).json({
error: errorHandler(err)
})
}
res.json({ data })
})
}
routes/category
const express = require('express')
const router = express.Router()
const { create } = require('../controllers/category')
router.post('/category/create/:userId', create);
router.param("userId", userById)
module.exports = router
models/category
const mongoose = require('mongoose')
const categorySchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
required: false,
maxlength: 32
}
},
{ timestamps: true }
);
module.exports = mongoose.model('Category', categorySchema)
config the header request in postman like this
and the body of request
this is my app.js
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const mongoose = require("mongoose");
const inputRoutes = require("./routes/input");
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.use(cors());
app.use((req, res, next) => {
res.setHeader("Acess-Control-Allow-Origin", "*");
res.setHeader(
"Acess-Control-Allow-Methods",
"OPTIONS ,GET ,POST ,PUT,PATCH , DELETE"
);
res.setHeader("Acess-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
app.use("/input", inputRoutes);
mongoose
.connect("mongodb://localhost:27017/MEAN", { useNewUrlParser: true })
.then(result => {
app.listen(2400);
})
.catch(err => console.log(err));
this is my routes/input.js
const express = require("express");
const router = express.Router();
const inputController = require("../controller/input");
router.post("/todo", inputController.createTodos);
module.exports = router;
this is my controller,input.js
const Todo = require("../models/todos");
const { validationResult } = require("express-validator/check");
exports.createTodos = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
const error = new Error("validation failed due to incorrect data");
error.statusCode = 442;
throw error;
}
const task = req.body.task;
const status = req.body.status;
console.log(task);
console.log(status);
const todo = new Todo({
task: task,
status: status
});
todo
.save()
.then(result => {
console.log(task);
res.status(201).json({
message: "post created sucessfully",
post: result
});
})
.catch(err => {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
});
};
this is my model.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const todoSchema = new Schema(
{
task: {
type: String,
required: true
},
status: {
type: Boolean,
default: false
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Todo", todoSchema);
You need to send JSON request in the postman first choosing raw option, and then json in the right dropdown.
Also you seem to use express-validator package, but you don't use it in router.
In the router you can use it like this:
const express = require("express");
const router = express.Router();
const { check } = require("express-validator");
const inputController = require("../controller/input");
router.post("/todo", [
check("task")
.not()
.isEmpty()
], inputController.createTodos);
module.exports = router;
Also in controller you should import the validationResult from express-validator,
and validate the result like this:
const { validationResult } = require('express-validator');
exports.createTodos = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
....
}
I'm still having some exception errors about JSON web token Private Key. It says it's not defined but I think I already put the JSON web token private key and still throwing an error. I'm not sure where the problem is maybe in the user module or auth module or on the config. Please see the below code and any help would be appreciated.
//default.json
{
"jwtPrivateKey": "",
"db": "mongodb://localhost/vidly"
}
// test.json
{
"jwtPrivateKey": "1234",
"db": "mongodb://localhost/vidly_tests"
}
// config.js
const config = require('config');
module.exports = function() {
if (!config.get('jwtPrivateKey')) {
throw new Error('FATAL ERROR: jwtPrivateKey is not defined.');
}
}
// users.js
const auth = require('../middleware/auth');
const jwt = require('jsonwebtoken');
const config = require('config');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const {User, validate} = require('../models/user');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.get('/me', auth, async (req, res) => {
const user = await User.findById(req.user._id).select('-password');
res.send(user);
});
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (user) return res.status(400).send('User already registered.');
user = new User(_.pick(req.body, ['name', 'email', 'password']));
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
const token = user.generateAuthToken();
res.header('x-auth-token', token).send(.pick(user, ['id', 'name', 'email']));
});
module.exports = router;
// auth.js
const Joi = require('joi');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const {User} = require('../models/user');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (!user) return res.status(400).send('Invalid email or password.');
const validPassword = await bcrypt.compare(req.body.password, user.password);
if (!validPassword) return res.status(400).send('Invalid email or password.');
const token = user.generateAuthToken();
res.send(token);
});
function validate(req) {
const schema = {
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(5).max(255).required()
};
return Joi.validate(req, schema);
}
module.exports = router;
// db.js
const winston = require('winston');
const mongoose = require('mongoose');
const config = require('config');
module.exports = function() {
const db = config.get('db');
mongoose.connect(db)
.then(() => winston.info(Connected to ${db}...));
}
// logging.js
const winston = require('winston');
// require('winston-mongodb');
require('express-async-errors');
module.exports = function() {
winston.handleExceptions(
new winston.transports.Console({ colorize: true, prettyPrint: true }),
new winston.transports.File({ filename: 'uncaughtExceptions.log' }));
process.on('unhandledRejection', (ex) => {
throw ex;
});
winston.add(winston.transports.File, { filename: 'logfile.log' });
// winston.add(winston.transports.MongoDB, {
// db: 'mongodb://localhost/vidly',
// level: 'info'
// });
}
// index.js
const winston = require('winston');
const express = require('express');
const app = express();
require('./startup/logging')();
require('./startup/routes')(app);
require('./startup/db')();
require('./startup/config')();
require('./startup/validation')();
const port = process.env.PORT || 3000;
app.listen(port, () => winston.info(Listening on port ${port}...));
// user.test.js
const {User} = require('../../../models/user');
const jwt = require('jsonwebtoken');
const config = require('config');
const mongoose = require('mongoose');
describe('user.generateAuthToken', () => {
it('should return a valid JWT', () => {
const payload = {
_id: new mongoose.Types.ObjectId().toHexString(),
isAdmin: true
};
const user = new User(payload);
const token = user.generateAuthToken();
const decoded = jwt.verify(token, config.get('jwtPrivateKey'));
expect(decoded).toMatchObject(payload);
});
});
// package.json
"scripts": {
"test": "jest --watchAll --verbose"
},
the structure of your config files are wrong. if u check the https://www.npmjs.com/package/config
this is the structure of file:
{
"Customer": {
"dbConfig": {
"host": "prod-db-server"
},
"credit": {
"initialDays": 30
}
}
}
that page also provides this info:
config.get() will throw an exception for undefined keys to help catch typos and missing values. Use config.has() to test if a configuration value is defined.
I think set does not work with visual studio code terminal. I had same issue, when i executed in Windows CMD it worked.
Try config.get instead of config.has()
module.exports = function() {
if (!config.has('jwtPrivateKey')) {
throw new Error('FATAL ERROR: jwtPrivateKey is not defined.');
}
if you are using mosh's tutorial as it said here you should have a file named custom-environment-variables.json too and it contains:
{
"jwtPrivateKey": "vidly_jwtPrivateKey"
}
then you have to set an environment variable called vidly_jwtPrivateKey.
in windows you can run this: set vidly_jwtPrivateKey=mySecureKey on CMD.
Hope it solves the problem :)
n
if(!config.has('jwtPrivateKey')) {
console.error("FATAL ERROR: jwtPrivateKey not defined.")
process.exit(1);
}
try to use config.has() instead of config.get()