Express gives the same response even with different input-values in MongoDB - javascript

I'm new learning Express and MongoDB. I'm following an Udemy course, and I'm sure that my code is exactly the same.
My problem:
When I post some data to a MongoDB collection, it works as expected. But when I try to add a new value, it works, but inserts the same value that the first post, even when the inputs values are differents.
Here is some of my code:
pacienteControllers.js
const Paciente = require('../models/Paciente');
exports.newClient = async (request, response, next) =>{
const paciente = new Paciente(request.body);
try {
await paciente.save();
response.json({mensaje: 'El cliente se agregó correctamente'});
} catch (error) {
console.log(error);
next();
}
}
routes/index.js:
const express = require('express');
const router = express.Router();
const PacienteController = require('../controllers/PacienteControllers');
module.exports = () =>{
router.get('/', () =>{
console.log("Petición enviada");
})
router.post('/pacientes',
PacienteController.newClient
)
return router;
}
index.js:
const express = require('express');
const mongoose = require('mongoose');
const routes = require('./routes/index');
const bodyParser = require('body-parser');
const server = express();
mongoose.Promise = global.Promise;
mongoose.connect('mongodb+srv://AlexisDominguez:11399102a#my-free-cluster-ojd2d.mongodb.net/veterinaria?retryWrites=true&w=majority', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
});
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({extended: true}));
server.use('/', routes());
server.listen(4000, () => console.log("servidor funcionando"));
Note: username and password are correct values, just censured for security reasons.
I would like to know why is this happening. ¿Is there some kind of cache?
TESTS
I'm using Postman to do posts tests. When I do the first post I get the message: El cliente se agregó correctamente meaning that the client was added successfuly.
But when I try to add a new register to the database, I get the same message but, when I update the database to see new changes, I get the new register but with the same values of the first post.
EDIT
Added server.use(bodyParser.json()); but still getting same results.

You only import routes folder but not index.js file in your root file index.js so import as
const routes = require('./routes/index');
You are sending message in JSON object But you didn;t use middleware in index.js so add
server.use(bodyParser.JSON());
Your routes and controller can be merged like this: In your routes/index.js file add this code:
const express = require('express');
const router = express.Router();
const Paciente = require('../models/Paciente');
router.post('/pacientes', async (req, res) => {
const paciente = new Paciente(req.body);
try {
const saveData = await paciente.save();
res.json({ message: "El cliente se agregó correctamente" });
}
catch ( err ) {
res.json({ message: err });
}
});
//You can view all the data from here
router.get('/', async (req,res) => {
const data = await Paciente.find();
try {
res.json(data);
} catch( err ) {
res.json({ message: err })
}
});
module.exports = router;
You can now remove pacienteController.js file

Related

How to wait for GET Request with Axios to complete

I am making a Web-Notepad using Nodejs and express where all the data is gonna be saved in MongoDB. I want to grab the data through my Rest API making an HTTP request with Axion.
When I send the GET request, the program doesn't wait for the JSON file, continues and because of that, it exports an undefined file with the site is getting shown without the data.
With the console.log after the GET request, I get all the data I need - but too late.
app.js:
const express = require('express');
const chalk = require('chalk');
const debug = require('debug')('app');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv/config')
const app = express();
const port = 3000;
app.use(cors());
app.use(express.static('views'));
app.use(bodyParser.json());
app.set('views', './views');
app.set('view engine', 'ejs');
const postsRoute = require('./routes/posts');
// Here i import the data from the GET request
const getData = require('./routes/router');
app.use('/posts', postsRoute);
// The outcome of this log is; Promise {<pending>}
console.log(getData);
app.get('/', (req, res) => {
res.render(
'index',
{
// Here i want to send the Data to the ejs file
getData,
title: 'Notepad'
});
});
// Connect to DB
mongoose.connect(
process.env.DB_CONNECTION,
{useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true, useFindAndModify: false}, () =>
debug('Connected correctly to MongoDB')
);
app.listen(port, () => {
debug(`Listening on port ${chalk.green(port)}`);
});
router.js where i make the GET request (i should change the name of the file...)
const axios = require('axios').default;
async function getData() {
try {
const response = await axios.get('http://localhost:3000/posts');
console.log(response);
return response.data
} catch (err) {
console.log(err);
}
}
module.exports = getData();
GET Request:
router.get('/', async (req, res) => {
try {
const posts = await post.find();
res.json(posts);
} catch (err) {
res.json({message: err})
}
});

How to save data in mongodb with express node.js?

I am encountering a problem when I try to make a post request with mogoose using the Postman, i get the following answer:
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /</pre>
</body>
</html>
I can't understand the reason, my index.js code:
const express = require("express");
const mongoose = require("mongoose");
const cors = require('cors')
const bodyParser = require('body-parser')
mongoose.connect(
process.env.MONGODB_URL || "mongodb://localhost/trading",
{
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
}
).then(item => {
console.log('conectado com o banco')
}).catch((err)=>{
console.log(err)
});
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}))
const candlesRoute = require("./routes/candles");
const home = require("./routes/home");
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", 'GET,PUT,POST,DELETE');
app.use(cors());
next();
})
app.use("/", home);
app.use("/candles", candlesRoute);
const PORT = 8080;
app.listen(PORT, () => {
console.log("Servidor Conectado");
});
my route candles.js :
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
require("../models/Candles");
const candlesTick = mongoose.model("candles");
router.post('/candles', async (req, res) => {
try {
const velas = req.body
await new candlesTick(velas).save();
console.log('successe')
} catch (error) {
console.log(error);
}
});
module.exports = router;
and finally my model Candles.js:
const mongoose = require('mongoose')
//const Schema = mongoose.Schema
const Candles = new mongoose.Schema({
titulo: {
type: String,
},
})
mongoose.model("candles", Candles);
my request in the Postman is as follows
{
"titulo": "DENT/ETH"
}
I have already tmbm send the data directly and even then it does not work, I do not understand the reason for this, please if anyone can help thanks
app.use("/candles", candlesRoute); will add namespace to that route and router also has candles in the post request. At the end the available route will be POST {{host}}/candles/candles.
Please try remove candles from
router.post('/candles', async (req, res) => {
...
})
or have the URL in postman as {{host}}/candles/candles
I think req.body is not parsed, because you've set bodyparser extendedUrl to false. Try this:
app.use(bodyParser.urlencoded({extended: true}))
Also you simply create your object with MyModel.create(myContent) instead of using new Model() + save().
you should have posted your terminal logs also but nvm :)
I can guess the problem by looking at your code : -
Your mongodb local URL is wrong there is no mention of port.
it is always like mongodb://localhost:27017/trading for local server
I have less idea about this but you didn't export model in Candles.js

CRUD - I can't insert data using express and mongodb

I am trying to insert a category in the database following the instructions of a course I am taking and I am unable to insert it with the create method. It shows ... loading in Postman and nothing happens and no error message appears on the console. Here are my files.
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', authRoutes)
app.use('/api', userRoutes)
app.use('/api', categoryRoutes)
const port = process.env.PORT || 8000
app.listen(port, () => {
console.log(`Server is running on port ${port}`)
})
routes/category.js
const express = require('express')
const router = express.Router()
const { create } = require('../controllers/category')
const { requireSignin} = require('../controllers/category')
const { userById } = require('../controllers/user')
router.post('/category/create/:userId', function(req, res){
requireSignin,
create
});
router.param("userId", userById)
module.exports = router
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 })
})
}
models/category.js
const mongoose = require('mongoose')
const categorySchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
required: true,
maxlength: 32
}
},
{ timestamps: true }
);
module.exports = mongoose.model('Category', categorySchema)
In order to make sure that data is actually being returned, your create function needs to be asynchronous. Adding async/await to the save function should confirm that you are properly saving the data to the database before returning.
It appears you have an error in your route setup. I assume requireSignin and create should be middleware functions.
So instead of
router.post('/category/create/:userId', function(req, res){
requireSignin,
create
});
you should try this
router.post('/category/create/:userId', requireSignin, create);
// assuming 'create' is the last one, since you are ending the request there
// also assuming that 'requireSignin' is setup as middleware, calling next function

Express routes stopped working after setting app in production on Heroku

I've deployed my app on Heroku and after some tweaking, everything works except when I try to retrieve data from the Mongo database. The console error I get is: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0.
I have the feeling that it won't go into the get request while that should be the case. (Because it's not logging anything in the console)
Am I missing something in the way routes are handled in production?
Everything in development is working.
I'm very confused at this point, hope someone can help me
Server.js:
const bodyParser = require('body-parser')
const path = require('path');
const express = require('express');
const morgan = require('morgan');
const MongoClient = require('mongodb').MongoClient;
const cors = require('cors')
const compression = require('compression');
const helmet = require('helmet')
const app = express();
const port = process.env.PORT || 5000;
app.use(helmet())
app.use(compression());
if (process.env.NODE_ENV === 'production') {
const publicPath = path.join(__dirname, 'client/build');
const apiPath = path.join(__dirname, 'api');
app.use(express.static(publicPath));
app.use('/overview', express.static(apiPath));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/build/index.html'));
})
}
app.use(cors())
app.use(morgan('tiny'));
app.use(bodyParser.json())
const apiRouter = require('./api/api');
app.use('/overview', apiRouter);
// connect to the db and start the express server
let db;
const url = process.env.MONGODB_URI
MongoClient.connect(url, {useUnifiedTopology: true,useNewUrlParser: true,}, (err, client) => {
if(err) {
return console.log(err);
}
console.log('mongo connected')
db = client.db('kvdlaanmeldingen');
// start the express web server listening on port 5000
app.listen(port, () => console.log(`Listening on port ${port}`));
});
apiRouter, api.js in api/api.js:
const express = require('express');
const apiRouter = express.Router()
const MongoClient = require('mongodb').MongoClient;
const mongodb = require('mongodb');
const url = process.env.MONGODB_URI
console.log('api.js is activated') //this is logged to console, so file can be read.
let db;
MongoClient.connect(url, {useUnifiedTopology: true,useNewUrlParser: true,}, (err, client) => {
db = client.db('kvdlaanmeldingen');
});
let aanmeldingen = [];
// this is where I believe it gets stuck
apiRouter.get('/', (req, res) => {
console.log(db)
db.collection('kvdlaanmeldingen').countDocuments({}, function(err, result) {
console.log(result)
if (err) return console.log(err);
res.send(JSON.stringify(result));
})
});
module.exports = apiRouter;
The get request should be done as soon as this React component is rendered:
import React from 'react';
import './Aanmeldingen.css';
import { Link, Route } from "react-router-dom";
import XPress from './utils/Xpress.js';
import TaakComponent from './TaakComponent';
import { snakeCase } from "snake-case";
class Aanmeldingen extends React.Component {
constructor (props) {
super(props);
this.state = {
dataLoaded: 0,
taken: [// an array of different names that will be loaded as headers],
taakKlik: false,
taakData: null,
taakNaam: null,
}
}
componentDidMount(){
XPress.getTaken().then(data => {
console.log(data)
if (data) {
this.setState({
taakData: data,
dataLoaded: 1,
});
}
});
}
{...}
render(){
return (
<div className="Aanmeldingenpage">
<div className="statistics" onClick={this.aanmeldingen}>
<p className="statistics" id="counterAanmeldingen">{this.state.dataLoaded ? `Aantal aanmeldingen: ${this.state.taakData}` : 'Data aan het laden..'}</p>
</div>
</div>
);
}
}
and Xpress.getTaken is looking like this:
const XPress = {};
const baseUrl = window.location.origin;
XPress.getTaken = () => {
const url = `${baseUrl}/overview`;
return fetch(url, {method: 'GET'}).then(response => {
if (!response.ok) {
return new Promise(resolve => resolve([]));
}
return response.json().then(jsonResponse => {
return jsonResponse
}
)
})
}
The error you posted is often seen when parsing JSON fails. I guess this happens when fetch fails to parse the result in the frontend at this line: return response.json().then(jsonResponse => {.
Instead of returning valid JSON, the backend returns a file that starts with "<" (the unexpected token). Your backend responds with an HTML page instead of JSON.
Issue comes from here most likely:
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/build/index.html'));
})
This basically says that all GET requests should serve index.html. That's why the request doesn't go to apiRouter.get('/'), it stops at the first match, which is the code above. It works on localhost because this code path is inside a conditional that checks NODE_ENV for production.
Not sure why you have it in there, but removing it would solve the issue.
Please try adding the heroku postbuild script to your json file in the root directory as same as the existence of the server.js file, that might help, using in react we must add heroku postbiuld so that the build is saved in the server, and that might not produce an issue,

How to properly export a mongoDB instance between various files?

I'm tryin to connect to mongoDB database and then export the database connection variable so that I can use it across various files, but when I import that variable in another files, it gives an error.
server.js
const express = require('express'),
cors = require('cors'),
MongoCLient = require('mongodb').MongoClient,
expressGraphQL = require('express-graphql'),
schema = require('./graphql/schema');
const app = express();
const mongoURL = 'mongodb://localhost:27017',
dbName = 'graphql-starter',
client = new MongoCLient(mongoURL, {
useNewUrlParser: true,
useUnifiedTopology: true
});
let db;
client.connect(async err => {
if (err) {
console.log(
'There was an error while connecting to database. Error: ',
err
);
} else {
db = client.db(dbName);
console.log(`Successfully connected to ${dbName} database. ENJOY..!!`);
}
});
app.use(
'/graphql',
expressGraphQL({
schema,
graphiql: true
})
);
app.use((req, res, next) => {
cors();
next();
});
app.listen(3002, () => {
console.log('Server running on port 3002.');
});
module.exports = {
db
};
anotherFile.js
const { db } = require('./server');
db.collection('collectionName').find({}).toArray();
In this file, I get an error saying cannot read property collection of undefined? Does anyone know what I'm doing wrong? Thanks in advance.

Categories