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})
}
});
Related
I want to send data for products from my post request
router.post("/addProduct",(req, res) => {
const {addName, addDescription, addPrice, addImg} = req.body;
console.log(`${addName} added, the price is ${addPrice}`)
})
into the get request
router.get("/addProduct",(req, res) => {
//console.log(`getting ${addName}, and the price is ${addPrice}`)
console.log(`getting the response ${addName}`)
})
i want to send the const {addName, addDescription, addPrice, addImg} = req.body; into the get request, but I haven't found a lot of info on how to do that
You can, but it's against the convention.
const express = require("express");
const app = express();
const router = express.Router();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(router);
router.get("/addProduct", (req, res) => {
const { addName } = req.body;
console.log(`getting the response ${addName}`);
return res.json(addName);
});
app.listen(3000, (req, res) => {
console.log("listening...");
});
I want to send some data to my MongoDB database, but in router.post my req.body is empty, if I use stuff that I put in my send function in User(req.body) instead of req.body data will be send to my MongoDB database correctly.
This is my router that I use, router.get work fine, it return database tables correctly on /api page:
const router = require("express").Router();
const User = require("./model/models");
const parser = require("body-parser").json();
router.get("/", async (req, res) => {
const data = await User.find({});
res.json(data);
});
router.post("/",parser,async (req, res) => {
console.log('1')
console.log(req.body)
console.log('2')
parser.v
await User(req.body).save();
res.json({"msg": "ok"});
});
module.exports = router
This is my index.js file code:
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
const parser = require("body-parser").json();
var path = require('path');
app.use(express.urlencoded(true));
app.use(express.json());
app.use(parser);
app.use('/',require("./routes/routes"))
app.use(express.static(__dirname +'/public'))
app.use("/api", require('./data/api'))
app.listen(5000,function(){
console.log('server is alive')
})
This is function that what I use to send data:
const btn1 = document.getElementById('btnEnter')
let Login = "123"
btn1.addEventListener('click' ,e=>{
send({newsTxT : "someTextHere",newsZag:"someZag",author:"SomeAuthor"})
})
const send = async(body) => {
let res = await fetch("/api", {
method: "post",
header: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(body)
});
let data = await res.json();
console.log(data)
}
The only weird thing I see is that you are using a json body-parser and also the express.json() both technically do the same, but body-parser is deprecated so it might be causing a bug.
Also you don't have to import it again in the routes, placing app.use(express.json()) at index.js will make it work for all endpoints/routes.
See how this refactor goes:
const router = require('express').Router()
const User = require('./model/models')
router.get('/', async (req, res) => {
const data = await User.find({})
res.json(data)
})
router.post('/', async (req, res) => {
console.log('1')
console.log(req.body)
console.log('2')
await User(req.body).save()
res.json({ 'msg': 'ok' })
})
module.exports = router
index.js
const express = require('express')
const app = express()
var path = require('path')
app.use(express.urlencoded(true))
app.use(express.json())
app.use('/', require('./routes/routes'))
app.use(express.static(__dirname + '/public'))
app.use('/api', require('./data/api'))
app.listen(5000, function () {
console.log('server is alive')
})
The following worked fine:
const express = require("express")
const app = express()
const router = express.Router()
router.use(express.json())
app.use(router)
router.post('/api/user', function(req, res) {
// ...
}
I see the difference may be using the: app.use(router)
Note that in the above code the statement:
router.use(express.json())
can be replaced with (using the body-parser):
const bodyParser = require('body-parser')
router.use(bodyParser.json())
This worked fine with express version 4.17.1, body-parser version 1.19.0 and NodeJS version 12.18.3
I'm making a POST request from a React front-end using axios to an endpoint to save some data to my DB (MongoDB). I'm getting an error that one cannot read property 'name' of undefined. I think that's occurring because req.body is undefined but I can't understand what's wrong with my axios request. I logged all the parameters and they are there (not undefined). The axios request and the endpoint are written below. Any help will be appreciated. Thanks!
Axios Request
const uploadElement = async (name, HTMLCode, JSCode, CSSCode, screenshot) => {
console.log(name)
try {
await axios({
method: 'post',
url: '/api/elements',
data: {
name: name,
HTMLCode,
JSCode,
CSSCode,
screenshot
}
});
} catch (e) {
console.log(e);
}
}
Endpoint for POST Request
router.post("/", upload.single("screenshot"), async (req, res) => {
try {
const newElement = new Element({
name: req.body.name,
JSCode: req.body.JSCode,
HTMLCode: req.body.HTMLCode,
CSSCode: req.body.CSSCode,
screenshot: req.file.buffer,
});
await newElement.save();
res.send("Data uploaded successfully!");
} catch (e) {
console.error(e);
}
});
Server.js
const express = require("express");
const passport = require("passport");
const session = require("express-session");
const cors = require('cors');
const elementRouter = require("./routes/elementRoute");
const authRouter = require("./routes/authRoute");
const connectDB = require("./config/db");
const app = express();
const port = process.env.PORT || 5000;
connectDB();
app.use(
session({
secret: "googleOAuth",
resave: false,
saveUninitialized: true,
})
);
app.use(cors());
// Passport Config
require("./config/passport")(passport);
app.use(passport.initialize());
app.use(passport.session());
app.use("/api/elements", elementRouter);
app.use("/api/auth", authRouter);
app.listen(port, () => {
console.log(`Server is up on port ${port}`);
});
You need to install and require body-parser in your serverside code
First run npm i --save body-parser
Then require it like this
const bodyParser = require("body-parser");
Then use it after you declare your app ( after this line const app = express();)
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
This makes the data of your request available in req.body
I am looking to start including my route files in my Node.js and express application. However, when I require the local route files into my server.js file, and try to run that on Nginx, I get a 502 Bad Gateway error.
The code that is giving me trouble is currently commented out. Any ideas on what might be causing this performance?
server.js
require('dotenv').config();
const express = require('express');
const bodyparser = require('body-parser');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
// const oidc = require('./okta');
// const searchRouter = require('./routes/search');
// const inputRouter = require('./routes/input');
// const dataRouter = require('./routes/view-all');
const app = express();
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.sendFile(__dirname + '/views/index.html');
});
app.get('/page', function(req, res) {
res.render(__dirname + '/views/optishop.ejs');
});
const listener = app.listen(8080, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
Edit: This is the file being required in the searchRouter declaration.
search.js
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const oidc = require('../okta');
const router = express.Router();
router.post('/search', oidc.ensureAuthenticated(), async (req, res) => {
await MongoClient.connect(
process.env.MONGODB_URI,
{ useUnifiedTopology: true },
async (err, client) => {
assert.equal(null, err);
const db = client.db('test');
const arr = req.body.item.trim().split(/; */gi);
const user = req.session.passport.user.userinfo.sub;
const cursor = await db
.collection('test')
.find({
user
})
.toArray();
const filteredCursor = cursor.filter(obj => {
return arr.includes(obj.item);
});
res.render('index', {
cursor: filteredCursor
});
// res.send(filteredCursor);
client.close();
}
);
});
module.exports = router;
I'm working on a project that uses ReactJS typescript for the front-end, express for the back-end, and MongoDB for the database.
The main issue I am having is that I want to somehow send data from my React component to the express app so that it can query and add things to the database.
Currently, I have the express server running on http://localhost:9000, and the React app on http://localhost:3000, and I can connect them using routes.
My express app looks like the following:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testAPIRouter = require('./routes/testAPI');
var testAddUser = require('./routes/addUser');
const MongoClient = require('mongodb').MongoClient;
const mongoose = require('mongoose');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use("/testAPI", testAPIRouter);
app.use("/addUser", testAddUser);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
const dbRoute = 'mongodb+srv://Adminname:fjfeinjd#pawornaw-b4vzg.gcp.mongodb.net/test?retryWrites=true&w=majority';
mongoose.connect(dbRoute,
{useNewUrlParser: true})
.then(() => console.log("Connected to MongoDB"))
.catch(err => console.error("Could not connected to Mongo"));
module.exports = app;
and my React Component is this, minus import statements. The render function only contains a button that has an onlclick that executes doThing()
constructor(props: any) {
super(props);
this.state = {
showHomePage: true,
showAnimalUploadSearch: false,
showProfile: false,
showAnimal: true,
apiResponse: "",
fName: "bob"
};
this.changeView = this.changeView.bind(this);
// this.callAPI = this.callAPI.bind(this);
// this.componentWillMount = this.componentWillMount.bind(this);
this.doThing = this.doThing.bind(this);
}
callAPI() {
fetch("http://localhost:9000/testAPI")
.then(res => res.text())
.then(res => this.setState({apiResponse: res}))
.catch(err => err);
}
componentWillMount(): void {
this.callAPI();
}
changeView() {
this.setState({showHomePage: !this.state.showHomePage});
this.setState({showAnimalUploadSearch: !this.state.showAnimalUploadSearch});
this.setState({showAnimal: true});
this.setState({showProfile: false});
}
doThing() {
Axios.post('http://localhost:9000/testAPI', ({firstName: this.state.fName}))
.then(res => console.log(res));
}
and finally, testAPI.js looks like this
const router = express.Router();
const axios = require('axios');
router.get('/', function(req, res, next) {
//res.send('API is working properly');
axios.get('http://localhost:3000')
.then(res => console.log("got it"))
.catch(err => err);
});
module.exports = router;
I want to be able to access and use the data that is sent from my react component so that I can query my database with user input in the future. The API does connect with my React code, and when the testAPI function only contains these lines:
const router = express.Router();
const axios = require('axios');
router.get('/', function(req, res, next) {
res.send('API is working properly');
});
module.exports = router;
the message can be displayed on my react app in the browser via the state.
If anyone could help me see what I am doing wrong, or maybe give me a clue as to what other options I can try, please let me know.
Thank you.
When you send post request from client side, it will be in body property of req object
const router = express.Router();
// you shoud listen post request
router.post('/', function(req, res) {
const { body } = req;
// do somethin with data which you recieved in body, save to database for example
// and send response to the client
res.json({ message: 'your data was saved'});
});
module.exports = router;
to send data to client use:
router.get('/', function(req, res) {
res.json({ data: 'Some data'}); // or res.send('some text') to send plain text
});