NodeJs: Trigger API's which are in another file - javascript

I'm new to NodeJs, apologies if this query is basic one.
Implemented the API's like below and everything working fine
UserServices.js
import mongoose from "mongoose";
const createUserSchema = mongoose.Schema({
companyName: String,
email: String,
contactNumber: String,
password: String
});
export default mongoose.model("users", createUserSchema);
server.js
import express from "express";
import mongoose from "mongoose";
import Cors from "cors";
import GlobalVars from "./utils/GlobalVars";
import createUserSchema from "./apis/services/UserServices";
// App Config
const app = express();
const port = process.env.PORT || 8001;
// Middleware
app.use(express.json());
app.use(Cors());
// DB Config (Connecting DB)
mongoose.connect(GlobalVars.MONGO_DB_URL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
// API Endpoints
app.get("/", (req, res) => res.status(200).send("Hello World"));
app.post("/create_user", (req, res) => {
const userData = req.body;
console.log("userData " + JSON.stringify(userData));
createUserSchema.create(userData, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(201).send(data);
}
});
});
app.get("/users_list", (req, res) => {
createUserSchema.find((err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send(data);
}
});
});
// Listener
app.listen(port, () => console.log(`Listening on host: ${port}`));
but i don't want to mention get and post calls in the server.js, want to make server.js as clean as possible. So, would like to mention get and post calls in UserServices.js. For this, followed below structure but it's not working
UserServices.js
import mongoose from "mongoose";
import express from "express";
const app = express();
const createUserSchema = mongoose.Schema({
companyName: String,
email: String,
contactNumber: String,
password: String
});
mongoose.model("users", createUserSchema);
const createUser = () => {
app.post("/create_user", (req, res) => {
const userData = req.body;
console.log("userData " + JSON.stringify(userData));
createUserSchema.create(userData, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(201).send(data);
}
});
});
};
const getUsersList = () => {
app.get("/users_list", (req, res) => {
createUserSchema.find((err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send(data);
}
});
});
};
export { createUser, getUsersList };
server.js
import express from "express";
import mongoose from "mongoose";
import Cors from "cors";
import GlobalVars from "./utils/GlobalVars";
import { createUser, getUsersList } from "./apis/services/UserServices";
// App Config
const app = express();
// eslint-disable-next-line no-undef
const port = process.env.PORT || 8001;
// Middleware
app.use(express.json());
app.use(Cors());
// DB Config (Connecting DB)
mongoose.connect(GlobalVars.MONGO_DB_URL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
// API Endpoints
app.get("/", (req, res) => res.status(200).send("Hello World"));
createUser();
getUsersList();
// Listener
app.listen(port, () => console.log(`Listening on host: ${port}`));
My query is, how to mention API's globally or how to trigger API's which are written in another file

The problem is that you're creating two different apps here (with two calls to express()). Instead, you can just pass your app reference defined in server.js to the createUser and getUsersList functions:
// server.js
import express from "express";
import mongoose from "mongoose";
import Cors from "cors";
import GlobalVars from "./utils/GlobalVars";
import { createUser, getUsersList } from "./apis/services/UserServices";
// App Config
const app = express();
// eslint-disable-next-line no-undef
const port = process.env.PORT || 8001;
// Middleware
app.use(express.json());
app.use(Cors());
// DB Config (Connecting DB)
mongoose.connect(GlobalVars.MONGO_DB_URL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
// API Endpoints
app.get("/", (req, res) => res.status(200).send("Hello World"));
createUser(app);
getUsersList(app);
// Listener
app.listen(port, () => console.log(`Listening on host: ${port}`));
Then, get rid of const app = express(); in UserServices.js and have the createUser and getUserList functions accept app as a parameter:
// UserServices.js
import mongoose from "mongoose";
const userSchema = mongoose.Schema({
companyName: String,
email: String,
contactNumber: String,
password: String
});
const userModel = mongoose.model("users", userSchema);
const createUser = app => {
app.post("/create_user", (req, res) => {
const userData = req.body;
console.log("userData " + JSON.stringify(userData));
userModel.create(userData, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(201).send(data);
}
});
});
};
const getUsersList = app => {
app.get("/users_list", (req, res) => {
userModel.find({/*query here if any*/}, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send(data);
}
});
});
};
export { createUser, getUsersList };

Related

Firebase functions can't access my middleware routes

///index.js
const functions = require("firebase-functions");
const express = require("express");
const app = express();
const productRouter = require('./routes/productRoutes');
const globalErrorHandler = require('./controllers/errorController');
const AppError = require('./utils/appError');
// Compressing upcompressed files which is been sent to client such text.
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
}
// app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.send('Hello World')
});
app.get('/homepage', (req, res) => {
res.send('Hello People of God')
});
app.use('/products', productRouter);
// Handing Unhandled Routes
app.all('*', (req, res, next) => {
next(new AppError(`Can't find ${req.originalUrl} on this server!`, 404));
});
app.use(globalErrorHandler);
exports.app = functions.https.onRequest(app);
///productRoutes.js
const express = require('express');
const {
getProduct,
getAllProduct,
} = require('./../controllers/productController');
const router = express.Router();
router
.route('/')
.get(getAllProduct);
router
.route('/:id')
.get(getProduct);
module.exports = router;
///productController.js
const AppError = require('../utils/appError');
const Product = require('../modals/productModels');
const catchAsync = require('../utils/catchAsync');
// GET SINGLE PRODUCT CONTROLLER
exports.getProduct = catchAsync(async (req, res, next) => {
const product = await Product.findById(req.params.id)
.populate('reviews');
if (!product) {
return next(new AppError('No product found with that ID', 404));
}
res.status(200).json({
status: 'success',
data: {
product
}
});
});
// GET ALL PRODUCT CONTROLLER
exports.getAllProduct = catchAsync(async (req, res, next) => {
const products = await Product.find();
res.status(200).json({
status: 'success',
results: products.length,
data: {
products
}
});
});
///server.js
const mongoose = require('mongoose');
const app = require('./index')
const dotenv = require('dotenv');
// CONNECTING TO MONGODB SERVER
dotenv.config({ path: './config.env' })
const DB = process.env.DATABASE.replace('<PASSWORD>', process.env.DATABASE_PASSWORD);
mongoose.connect(DB, {
useNewUrlParser: true,
safe: true,
strict: false,
useUnifiedTopology: true
}).then(con => console.log('DB connection successful'))
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`App running on port ${port}...`);
});
After running function serve on my terminal i can access the two '/' and 'homepage' app.get which return the res "Hello world" and "Hello people of God" but can't access app.use('/products', productRouter). Its does take some time to run and throw an error "{"code":"ECONNRESET"}" please why is this so.
Am expecting to get my list of products from my mongodb data base.

Using React.js, Node.js and Multer, how can I console log 'req.file' on the server?

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);
})

How can we add collections in mongoDB dynamically( through users)?

Adding collections manually is easy but adding it dynamically giving me unexpected answer.
I am getting a collection name from frontend to backend using promt and axios but when I am doing
const variable_from_frontEnd = mongoose.model(variable_from_frontEnd, Schema);
it is not adding any collections.
import express from "express";
import mongoose from "mongoose";
import Messages from "./messages.js";
import cors from "cors";
// app configuration
const app = express();
const port = process.env.PORT || 9000;
const pusher = new Pusher({
appId: "1183689",
key: "c9fa659fc6b359a23989",
secret: "9da56a5db535e10c7d95",
cluster: "eu",
useTLS: true
});
//middleware
app.use(express.json());
app.use(cors());
// DB Configuration
const url = "mongodb+srv://suraj_bisht_99:zoe6B82AZjaLXgw7#cluster0.zp9dc.mongodb.net/Whatsapp_MERN?retryWrites=true&w=majority";
mongoose.connect(url, {useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true})
.then(()=> console.log('mongoDB is connected'))
.then(err => console.log(err));
const groupSchema = mongoose.Schema( {
message: String,
name: String,
timestamp: String,
received: Boolean,
});
// API routes
app.get("/", (req, res) => {
res.status(200).send("Hello World");
})
app.get("/messages/sync", async (req, res) => {
await Messages.find( (err, data) => {
if(err){
console.log(err);
res.status(500).send(err);
}else{
res.status(200).send(data);
}
})
})
app.post("/messages/new", async (req, res) => {
try{
const newMessage = new personalGroup(req.body);
const newMessageCreated = await newMessage.save();
res.status(201).send(newMessageCreated);
}
catch(err){
res.status(400).send(err);
}
});
// route for creating new collection in mongoDB
app.post("/room/new", async (req, res) => {
try{
let groupName = req.body.room;
groupName = mongoose.model(groupName, groupSchema);
if(!groupName){
console.log("error is occured");
}else{
console.log(groupName);
}
}
catch(err){
res.status(400).send(err);
}
})
// listening part
app.listen(port, () => console.log(`listening on port number ${port}`));
Let's say I have type a collection name "studyGroup" from frontend then
console is giving me
Model { studyGroup }
Can someone help me why it is happening and how can I add collections manually.

node.js req.body returning undefined

EDIT: #LawrenceCherone solved this, its (req, res, next) not (err, res, req)
I am creating a MERN app (Mongo, express, react, node).
I have some routes that work fine and return data from mongodb. However I created a new controller to access a separate collection and whenever i try to create a new document in it my req.body returns undefined.
I have setup my server.js like this:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const connectDB = require("./db");
const app = express();
const apiPort = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors());
app.use(bodyParser.json());
connectDB();
app.use("/api", require("./routes/router"));
var server = app.listen(apiPort, () => console.log(`Server running on port ${apiPort}`));
module.exports = server;
My router looks like this:
const express = require("express");
const QuizController = require("../controllers/quiz-controller");
const UserController = require("../controllers/user-controller");
const router = express.Router();
// quiz routes
router.post("/quizzes", QuizController.createQuestion);
router.get("/quizzes", QuizController.getAllQuestions);
router.get("/quizzes/:quiz_name", QuizController.getQuestionsByQuiz);
router.get("/quizzes/questions/:question_id", QuizController.getQuestionById);
router.put("/quizzes/:question_id/edit", QuizController.updateQuestionById);
router.delete("/quizzes/:question_id", QuizController.deleteQuestionById);
// user routes
router.post("/users", UserController.createUser);
module.exports = router;
All of the /quizzes routes work perfectly fine and i have had no trouble accessing the body. The UserController.createUser method is almost identical to Quizcontroller.createQuestion too so I am very confused.
Here is the user-controller with the createUser function:
const User = require("../models/User");
createUser = async (err, res, req) => {
const body = req.body;
console.log(req.body);
console.log(req.params);
console.log(body);
if (!body) {
return res.status(400).json({
succes: false,
error: "You must provide a body",
});
}
try {
const newUser = new User(body);
console.log(newUser);
if (!newUser) {
return res.status(400).json({ success: false, error: err });
}
const user = await newUser.save();
return res
.status(200)
.json({ success: true, newUser: user, msg: "New user created" });
} catch (err) {
console.error(err.message);
res.status(500).send("Server error");
}
};
module.exports = { createUser };
Here is an image of the postman request I am using to try test this:
[1]: https://i.stack.imgur.com/UHAK5.png
And the user model:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true,
},
emailAddress: {
type: String,
required: true,
},
permission: {
type: String,
required: true,
},
auth0Id: {
type: String,
required: true,
},
});
module.exports = mongoose.model("users", UserSchema);
The functional parameter order matters.
its
createUser = async (req, res, next) => // correct format
Not
createUser = async (err, res, req) // wrong format

Cannot get "/tinder/cards" route but getting "/" route

This below code is my first react application. After running server.js. After entering "http://localhost:8001/" I got HELLO!!. I expected after entering "http://localhost:8001/tinder/cards" url on chrome and postman too I get following error.
error message: "Cannot GET /tinder/cards".
this is my server.js file.
import mongoose from 'mongoose'
import Cors from 'cors'
import Cards from './dbCards.js'
// App Config
const app = express()
const port = process.env.PORT || 8001
const connection_url = 'mongodb+srv://admin:0tRkopC1DKm4ym4V#cluster0.iw73w.mongodb.net/tinderDB?retryWrites=true&w=majority'
// Middlewares
app.use(express.json())
app.use(Cors())
app.use('/',router);
// DB Config
mongoose.connect(connection_url, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
})
// API Endpoints
app.get("/", (req, res) => res.status(200).send("HELLO!!"))
app.get("/hello", (req, res) => res.status(200).send("Oooooooo!!"))
app.post("/tinder/cards", (req, res) => {
const dbCard = req.body
Cards.create(dbCard, (err, data) => {
if(err) {
res.status(500).send(err)
} else {
res.status(201).send(data)
}
})
})
app.get("/tinder/cards", (req, res) => {
Cards.find((err, data) => {
if(err) {
res.status(500).send(err)
} else {
res.status(200).send(data)
}
})
})
// Listener
app.listen(port, () => console.log(`listening on location: ${port}`)) ```
try this in your app.get('/tinder/cards') section:
// Doing it the Asynchronous way
app.get('/tinder/cards', async (req, res) => {
try { // Trying for getting the cards
const allCards = await Cards.find(); // Getting the cards
res.status(200).send(allCards); // Sending the cards
} catch (error) { // Catching the error
res.status(500).send(error); // Sending the error
}
});
Try to replace cards with card in the URL. Have a look at the image for the same.

Categories

Resources