How can I seperate different routes in different files in nodejs? - node.js

I'm learning reactjs and nodejs and with help of fellow stackoverflow members i've been able to successfully create the front end. Now i'm working on the back end in nodejs. Nodejs is also working fine but right now all my code is in single index.js file and i'm worried that its going to get bigger and bigger.
I just want to know how can I move stuff from index.js to seperate files ? For eg. I have catgeories (add,modify,delete list) then same for products, users etc.
My routes are like:
/add-category
/mod-category
/del-category
/categories
/add-user
/mod-user
/del-user
/users
/add-product
/mod-product
/del-product
/products
They're all working fine, just that they're in a single index.js file. How can I move routes of products into products.js and subsequently categories into categories.js and users into users.js ?
Some of my code is following as to how my index.js is:
const express = require("express");
const app = express();
const mysql = require("mysql");
const cors = require("cors");
app.use(cors());
app.use(express.json());
const db = mysql.createConnection({
user: "root",
host: "localhost",
password: "",
database: "shop",
});
app.get("/admin/categories", (req, res) => {
db.query("SELECT * FROM categories ORDER BY catg_name", (err, result) => {
if (err) {
console.log(err);
} else {
res.send(result);
}
});
});
app.put("/admin/mod-category", (req, res) => {
const id = req.body.id;
const name = req.body.name;
const description = req.body.description;
const status = req.body.status;
db.query(
"UPDATE categories SET catg_name = ?, catg_description = ?, catg_status = ? WHERE catg_id = ? LIMIT 1",
[name, description, status, id],
(err, result) => {
if (err) {
console.log(err);
} else {
res.send(result);
}
}
);
});
app.delete("/admin/del-category/:id", (req, res) => {
const id = req.params.id;
db.query(
"DELETE FROM categories WHERE id = ? LIMIT 1",
[id],
(err, result) => {
if (err) {
console.log(err);
} else {
res.send(result);
}
}
);
});
app.listen(3001, () => {
console.log("Server is running on port 3001");
});
Any help is appericiated.
Thanks.

you can create a separate file for each collection.
categories routes file
const router = require('express').Router();
router.get('/categories/:id', (req, res) => {
// get a category by ID
});
router.post('/categories', () => {
// create a category
});
module.exports = router;
then a file for the products
const router = require('express').Router();
router.get('/products/:id', (req, res) => {
// get a product by id
});
router.post('/products', () => {
// create a product
});
module.exports = router;
after that import the exported routers to your index file and use them with
app.use() function
const express = require('express');
const productsRouter = require("./src/productsRouter");
const categoriesRouter = require("./src/categoriesRouter");
const app = express();
app.use(productsRouter);
app.use(categoriesRouter);

In this particular case, you can define each endpoint action as a file function.
You can do a categories.js file with any function that you need
const database = require('./connection.js')
const CATEGORIES = {
edit_categories : (req, res) => {
...
},
delete_categories : (req, res) => {
...
},
find_categories : (req, res) => {
...
}
}
module.exports = CATEGORIES
And apart you can define your connection.js
const mysql = require("mysql");
const database = () =>{
const db = mysql.createConnection({
user: "root",
host: "localhost",
password: "",
database: "shop"
});
return db;
}
module.exports = database();
And then use it all
const express = require("express");
const app = express();
const cors = require("cors");
const CATEGORIES = require('./categories.js');
app.use(cors());
app.use(express.json());
app.get("/admin/categories", CATEGORIES.find_categories );
app.put("/admin/mod-category", CATEGORIES.edit_categories );
app.delete("/admin/del-category/:id", CATEGORIES.delete_categories );
app.listen(3001, () => {
console.log("Server is running on port http://127.0.0.1:3001");
});
Obviously there is some many different ways for structure your project (you can separate routes, modeling and views on that way)

Related

How to create GET request including table name using sequelize?

I have this code in routes/apiRoutes.js that gets employees from the database but I need to include the table name with it.
const express = require("express");
const router = express.Router();
const db = require("../models");
//get all
router.get("/all", (req, res) => {
db.employee.findAll().then((employees) => res.send(employees));
});
//post new
router.post("/new", (req, res) => {
db.employee
.create({
text: req.body.text,
})
.then((submitedemployee) => res.send(submitedemployee));
});
module.exports = router;
I did try to use MYSQL syntax but it doesn't work
var seq = new Sequelize('mysql://localhost/mysql');
seq.query('show tables').then(function(rows) {
console.log(JSON.stringify(rows));
});

Chai testing TypeError: Converting circular structure to JSON

I'm a new learner express.js I want to test simple post and get operations with tdd mechanism. I created the test, route, index and db files but when I try to test POST method it gives me this error.
This is my routes/task.js
const express = require('express');
const router = express.Router();
router.post("/api/task", async (req,res) => {
try {
const task = await new Task(req.body).save();
res.send(task);
} catch (error) {
res.send(error);
}
})
This is my test/task.js
let chai = require("chai");
const chaiHttp = require("chai-http");
const { send } = require("process");
let server = require("../index");
//Assertion Style
chai.should();
chai.use(chaiHttp);
describe('Tasks API', () => {
/**
* Test the POST Route
*/
describe('POST /api/task', () => {
it("It should POST a new task", () => {
const task = {task: "Wake Up"};
chai.request(server)
.post("/api/task")
.send(task)
.end((err, response) => {
response.should.have.status(201);
response.body.should.be.a('string');
response.body.should.have.property('id');
response.body.should.have.property('task');
response.body.should.have.property('task').eq("Wake Up");
response.body.length.should.be.eq(1);
done();
});
});
});
});
This is my db.js
var sqlite3 = require('sqlite3').verbose()
const DBSOURCE = "db.sqlite"
let db = new sqlite3.Database(DBSOURCE, (err) => {
if (err) {
// Cannot open database
console.error(err.message)
throw err
}else{
console.log('Connected to the SQLite database.')
db.run(`CREATE TABLE IF NOT EXISTS todo (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task text
)`,
(err) => {
if (err) {
// Table already created
console.log(err);
}
});
}
});
module.exports = db
And this is my index.js
const connection = require('./db');
const express = require('express');
const app = express();
const cors = require("cors");
const port = process.env.PORT || 8080;
app.use(express.json());
app.use(cors());
app.get('/', (req, res) => {
res.send('Hello World');
});
app.post('/api/task', (req, res) => {
res.status(201).send(req);
});
app.listen(port, () => console.log(`Listening on port ${port}...`));
module.exports = app;
The thing that I try to do is building a test case to test the post method. I think I couldn't built the correct relations the files.
Currently, just by doing a POST request to /api/task, the error will appear. That is because of these lines in index.js:
app.post('/api/task', (req, res) => {
res.status(201).send(req);
});
The req parameter is circular, hence cannot be JSON-stringified.
Solution
In routes/task.js export the router:
const express = require('express');
const router = express.Router();
router.post("/api/task", async (req,res) => {
try {
const task = await new Task(req.body).save();
res.send(task);
} catch (error) {
res.send(error);
}
})
// By adding this line you can export the router
module.exports = router
In index.js, include the routes/task.js file and pass it to app.use(...), also remove the now-obsolete /api/task route:
const connection = require('./db');
const express = require('express');
const app = express();
const cors = require("cors");
const taskRoutes = require("./routes/task")
const port = process.env.PORT || 8080;
app.use(express.json());
app.use(cors());
app.get('/', (req, res) => {
res.send('Hello World');
});
app.use(taskRoutes)
app.listen(port, () => console.log(`Listening on port ${port}...`));
module.exports = app;
This way we got rid of the circular structure stringifying and the tests should now pass.

Can i add mongodb _id to localhost adress to display one post from database?

I have set up my project to display posts from a MongoDB database. My localhost address is http://localhost:5000/api/posts and it displays my two saved posts. How can I add MongoDB _id to localhost adress to only display one post?
MongoDB _id: 6061890d59ec3b6abcb011fb
I have tried this:
http://localhost:5000/api/posts/6061890d59ec3b6abcb011fb
http://localhost:5000/api/posts/id:6061890d59ec3b6abcb011fb
http://localhost:5000/api/posts/_id:6061890d59ec3b6abcb011fb
All of them returns error Cannot GET /api/posts/and_the_above_parameters_for_each_example`
Index.js to connect my backend to my application.
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
//Middleware
app.use(bodyParser.json());
app.use(cors());
const posts = require("./routes/api/posts");
app.use("/api/posts", posts);
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
posts.js to connect to MongoDB database. Below Password, MY_DATABASE and TABLE is changed to real values in my code.
const express = require("express");
const mongodb = require("mongodb");
const router = express.Router();
//Get posts
router.get("/", async (req, res) => {
const posts = await loadPostCollection();
res.send(await posts.find({}).toArray());
});
//Add post
router.post("/", async (req, res) => {
const posts = await loadPostCollection();
await posts.insertOne({
text: req.body.text,
createdAt: new Date(),
});
res.status(201).send();
});
router.delete("/:id", async (req, res) => {
const posts = await loadPostCollection();
await posts.deleteOne({
_id: req.params.id,
});
res.status(200).send();
});
async function loadPostCollection() {
const client = await mongodb.MongoClient.connect(
"mongodb+srv://MongoDB:PASSWORD#cluster0.5pnzd.mongodb.net/MY_DATABASE?retryWrites=true&w=majority",
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
);
return client.db("MY_DATABASE").collection("TABLE");
}
module.exports = router;
PostService.js to display posts on localhost and methods to post and delete.
import axios from "axios";
const url = "http://localhost:5000/api/posts/";
class PostService {
// Get posts
static getPosts() {
return new Promise((resolve, reject) => {
axios
.get(url)
.then((res) => {
const data = res.data;
resolve(
data.map((post) => ({
...post, //spread operator
createdAt: new Date(post.createdAt),
}))
);
})
.catch((err) => {
reject(err);
});
});
}
// Create posts
static insertPost(text) {
return axios.post(url, {
text,
});
}
static deletePost(id) {
return axios.delete(`${url}${id}`);
}
}
export default PostService;
router.get("/:id", async (req, res) => {
const posts = await loadPostCollection();
res.send(await posts.findOne({
_id: req.params.id,
}));
});
Number 1: http://localhost:5000/api/posts/6061890d59ec3b6abcb011fb is correct, but you're going to need to create a new route to handle that request.
These are often called 'show' routes.
router.get("/:id", async (req, res) => {
// code to handle the logic of that request
// access the url parameter via: req.params.id
});

req.body undefined...how can i solve

[ server.js ]
const fs = require("fs");
const express = require("express");
const bodyParser = require("body-parser");
const mysql = require("mysql");
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
const data = fs.readFileSync("./database.json");
const conf = JSON.parse(data);
const connection = mysql.createConnection({
host: conf.host,
user: conf.user,
password: conf.password,
port: conf.port,
database: conf.database
});
connection.connect();
app.get("/api/users", (req, res) => {
connection.query(
"select * from users where isDeleted = 0",
(err, rows, fields) => {
res.send(rows);
// console.log(err);
// console.log(rows);
}
);
});
app.post("/api/users", (req, res) => {
let sql = "insert into users values (null,?,?,now(),now(),0)";
let name = req.body.name;
let dsc = req.body.dsc;
let params = [name, dsc];
console.log(params);
connection.query(sql, params,
(err, rows, fields) => {
res.send(rows);
// console.log(err);
// console.log(rows);
});
});
app.delete("/api/users/:id", (req, res) => {
let sql = "update users set isDeleted = 1 where id = ?";
let params =[req.params.id];
connection.query(sql,params,
(err, rows, fields)=>{
res.send(rows);
// console.log(err);
// console.log(rows);
});
});
app.listen(port, () => console.log(`Listening on port http://localhost:${port}`));
Describe the bug
I am trying to send form data to my API but req.body is undefined for some reason.
To Reproduce
Steps to reproduce the behavior:
create a new request
enter your API endpoint URL
select the body tab and then select the form-data tab
enter the key name of the form data you are trying to send so your API can recognize it and then the value.
Click send and you should get a response with a status code of 200. If you get an error like me telling me that req.body is undefined then you have the same problem as me.
You are using bodyparser.json(). From the documentation, this will parse requests that are only in JSON. You are better off using bodyParser.urlencoded([options]).
I advise using express.urlencoded instead.
Read this for clarification
you are missing the router
[ server.js ]
const fs = require("fs");
const express = require("express");
const bodyParser = require("body-parser");
const mysql = require("mysql");
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
const data = fs.readFileSync("./database.json");
const conf = JSON.parse(data);
const connection = mysql.createConnection({
host: conf.host,
user: conf.user,
password: conf.password,
port: conf.port,
database: conf.database
});
connection.connect();
// u need a router
const router = express.Router();
router.get("/api/users", (req, res) => {
connection.query(
"select * from users where isDeleted = 0",
(err, rows, fields) => {
res.send(rows);
// console.log(err);
// console.log(rows);
}
);
});
router.post("/api/users", (req, res) => {
let sql = "insert into users values (null,?,?,now(),now(),0)";
let name = req.body.name;
let dsc = req.body.dsc;
let params = [name, dsc];
console.log(params);
connection.query(sql, params,
(err, rows, fields) => {
res.send(rows);
// console.log(err);
// console.log(rows);
});
});
router.delete("/api/users/:id", (req, res) => {
let sql = "update users set isDeleted = 1 where id = ?";
let params =[req.params.id];
connection.query(sql,params,
(err, rows, fields)=>{
res.send(rows);
// console.log(err);
// console.log(rows);
});
});
app.use(router);
app.listen(port, () => console.log(`Listening on port http://localhost:${port}`));

problem in creating a simple API service in different file

I want to create a simple RESTful service for managing the list of genres of movies. First I tried to handle all the HTTP requests to a given route('/api/genres') in a single file (server.js), and my code worked, i.e I was able to Post movies, update movies when I handled the routes from the main server.js file. But then, I tried to handle the routes in a separate file, but I'm getting problems.
Problems:
It seems my movies variable from server.js has not been able to export itself, as, I'm getting 'undefined' on console.log(movies) in generes.js. So for post and put request, nothing is being displayed
I have read that router.get and app.get are not much different, still, app.get doesn't work in genres.js
Server.js
const app = express();
const generes = require("./routes/api/genres");
app.use(express.json());
var movies = [
{
name: "harry potter",
genere: "fiction"
},
{
name: "IT",
genere: "horror"
},
{
name: "chicchore",
genere: "comedy"
},
{
name: "A walk to remember",
genere: "romantic"
}
];
app.use("/api/genres", generes);
const port = process.env.PORT || 3000;
app.listen(port, () => console.log("Server running..."));
module.exports.movies = movies;
genres.js
var express = require("express"),
app = express();
const server = require("../../server");
const router = express.Router();
app.use(express.json());
//importing movies array
var movies = server.movies;
router.get("/", (req, res) => {
res.send(movies);
});
router.post("/", (req, res) => {
var movie_obj = {
name: req.body.name,
genere: req.body.genere
};
movies.push(movie_obj);
res.send(movie_obj);
});
router.put("/:id", (req, res) => {
var flag = 0;
movies.forEach(ele => {
if (ele.name == req.params.id) {
ele.name = req.body.name;
flag = 1;
res.send(movies);
}
});
//if (flag == 0) res.send(`no such movie exists ${req.params.id}`);
});
module.exports = router;
function newFunction() {
return "movies";
}
Also,When I used app.get instead of router.get. I got the following error:

Resources