I am a newbie to NodeJS. I am trying to make a simple API relating to a bookstore.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const mongoose = require('mongoose');
app.use(bodyParser.json());
Genre = require('./models/genre.js');
Book = require('./models/book.js');
mongoose.connect('mongodb://localhost/bookstore');
const db = mongoose.connection;
app.post('/api/genres', function(req, res) {
const genre = req.body;
Genre.addGenre(genre, function(err, genre) {
if(err) {
throw err;
}
res.json(genre);
});
});
app.listen(3000);
console.log('Running on port 3000...');
Here is the genres.js
var mongoose = require('mongoose');
const genreSchema = mongoose.Schema({
name:{
type: String ,
required: true
},
create_date:{
type: Date,
default: Date.now
}
});
const Genre = module.exports = mongoose.model('Genre', genreSchema);
//Add Genre
module.exports.addGenre = function(genre, callback){
Genre.create(genre, callback);
}
I tried both RestEasy and Postman. Get request is successful but nothing on Post request. It gives this error in the IDE when I make a request.
ValidationError: Genre validation failed: name: Path name is
required.
Also, when I check on MongoShell it does not create date for books and genres.
Alright, I tried it out and your code does work for me, so it probably was just CORS-problems after all.
This is how I made my test request:
<html>
<head><script src="https://unpkg.com/axios/dist/axios.min.js"></script></head>
<body>
<script>
axios
.post('http://localhost:3000/api/genres', { name: "my genre" })
.then(response => {
document.body.innerHTML =
`<pre>${JSON.stringify(response.data, null, 4)}</pre>`;
});
</script>
</body>
</html>
This calls the request from localhost:80 and CORS-headers are needed if you request from another port. Still, I got big errors in my console:
Failed to load http://localhost:3000/api/genres: Request header field
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
Meaning I missed a CORS-header I thought we didn't need. Sorry about that, updated headers:
app.use((req,res,next)=>{
res.header("Access-Control-Allow-Headers", "Accept, Accept-Language, Content-Language, Content-Type");
res.header("Access-Control-Allow-Origin", "*");
next();
});
And here is the complete code just to be thorough, including serving my index.html:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const mongoose = require("mongoose");
const path = require("path");
app.use(bodyParser.json());
Genre = require("./genre.js");
mongoose.connect("mongodb://localhost/bookstore");
const db = mongoose.connection;
app.get("/", function(req, res) {
res.sendFile(path.resolve(__dirname, "index.html"));
});
app.use((req, res, next) => {
res.header("Access-Control-Allow-Headers", "Accept, Accept-Language, Content-Language, Content-Type");
res.header("Access-Control-Allow-Origin", "*");
next();
});
app.post("/api/genres", function(req, res) {
const genre = req.body;
Genre.addGenre(genre, function(err, genre) {
if (err) {
throw err;
}
res.json(genre);
});
});
app.listen(3000);
console.log("Running on port 3000...");
You didn't use the genre inside your req to create
module.exports.addGenre = function(genre, callback){
Genre.create(genre, function (err, gen) {
return callback(err, gen)
})
}
Related
so im developing website using nodejs, and then deploying it to microsoft azure, and using Azure Database for mysql server to be exact, and importing my databse using mysql workbench, now the problem is in the CORS, everyhting going well i run it on chrome and firefox in the same pc works fine, but when i try to acces the website using another pc, i get the error says "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3000/data/price%20asc. (Reason: CORS request did not succeed)".
heres my nodejs code:
//use path module
const path = require("path");
//use express module
const express = require("express");
//use hbs view engine
// const hbs = require('hbs');
//use bodyParser middleware
const bodyParser = require("body-parser");
//use mysql database
const mysql = require("mysql");
const app = express();
const db = require("./database");
//cors
const cors = require("cors");
// app.use(cors());
// app.use(
// cors({
// origin: "*",
// })
// );
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
//konfigurasi koneksi
const conn = mysql.createConnection({
// host: 'localhost',
// user: 'root',
// password: '',
// database: 'domdom'
host: "domdom.mysql.database.azure.com",
user: "domdom#domdom",
password: "Banana123",
database: "schema1",
port: 3306,
ssl: true,
});
//connect ke database
conn.connect((err) => {
if (err) throw err;
console.log("Mysql Connected...");
});
//set views file
app.set("views", path.join(__dirname, "/"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.json());
app.use(express.static(__dirname));
app.param("productname", function (request, response, next, product) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.product = product;
return next();
});
app.param("sort", function (request, response, next, price) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.price = price;
return next();
});
app.param("id", function (request, response, next, id) {
// ... Perform database query and
// ... Store the user object from the database in the req object
request.id = id;
ß;
return next();
});
//get all data
app.get("/data/:sort", (req, res) => {
let sql = "SELECT * FROM products Order By " + req.price;
let query = conn.query(sql, (err, results) => {
res.json(results);
});
});
//untuk search and sort
app.get("/data/:productname/:sort", function (req, res) {
let sql =
"SELECT * FROM products WHERE name like '%" +
req.product +
"%' Order By " +
req.price;
let query = conn.query(sql, (err, results) => {
res.json(results);
});
});
//untuk save data
app.post("/save/:id", (req, res) => {
let sql =
"INSERT INTO cart SELECT * from products WHERE id = '" + req.id + "'";
let query = conn.query(sql, (err, results) => {
if (err) throw err;
res.redirect("/");
});
});
//render interface
app.get("/", (req, res) => {
res.render("index");
});
//server listening
app.listen(3000, () => {
console.log("Server is running at port 3000");
});
as you can see in the code i have tried 3 ways trying to solve this problem, but nothing works, please help.
If you are using Azure app service to host your nodejs app,the most fastest way to config CORS on Azure Portal => app service => CORS :
I did some test on my side and this is my nodejs server code(as you can see, no config for CORS) :
const express = require('express')
const app = express()
const port = process.env.PORT || 8080
app.use(express.json())
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.post('/', (req, res) => {
var body = req.body;
res.send(`Hello ${body.name}!`)
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Test HTTP request from an local static web page:
<!DOCTYPE html>
<html>
<body>
<h1>The XMLHttpRequest Object</h1>
<button type="button" onclick="loadDoc()">Request data</button>
<p id="demo"></p>
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("POST", "https://nodeweb05.azurewebsites.net/", true);
xhttp.setRequestHeader("Content-type", "application/json");
var body = {"name":"testuser"};
xhttp.send(JSON.stringify(body));
}
</script>
</body>
</html>
You can try it yourself.
If you want to config CORS on code level, just try the config below:
const express = require('express')
const app = express()
var cors = require('cors')
app.use(cors())
If I set required to false, it will successfully create an object in the MongoDB database with one id. I suffer confusion sometimes, check my profile if you want. I think it's a little thing. If you need more info, just comment.
app.js
var express = require('express');
var bodyParser = require('body-parser');
var product = require('./routes/product'); // Imports routes for the products
var app = express();
var mongoose = require('mongoose'); // Set up mongoose connection
var dev_db_url = 'mongodb://localhost/Product';
var mongoDB = process.env.MONGODB_URI || dev_db_url;
mongoose.connect(mongoDB, {useNewUrlParser: true, useUnifiedTopology: true});
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use('/products', product);
var port = 3002;
app.listen(port, () => {
console.log('Server is up on port numbner ' + port);
});
model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ProductSchema = new Schema({
name: {type: String, required: true, max: 100},
price: {type: Number, required: true},
});
module.exports = mongoose.model('Product', ProductSchema);
controller.js
var Product = require('../models/product');
//Simple version, without validation or sanitation
exports.test = function (req, res) {
res.send('Greetings from the Test controller!');
};
exports.product_create = function (req, res, next) {
var product = new Product(
{
name: req.body.name,
bags: req.body.bags
}
);
console.log(JSON.stringify(req.body))
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Bags Created successfully')
})
};
router.js
var express = require('express');
var router = express.Router();
// Require the controllers WHICH WE DID NOT CREATE YET!!
var product_controller = require('../controllers/product');
// a simple test url to check that all of our files are communicating correctly.
router.get('/test', product_controller.test);
router.post('/create', product_controller.product_create);
module.exports = router;
HTTP POST: http://localhost:3002/products/create?name=Jorge&price=20
ValidationError: Product validation failed: name: Path name is
required
Can you help?
Thanks!
💡 The reason why it's error, because your req.body.name is empty or null. Why it's null or empty or undefined? Because you're not add your data in your body, when you send create request.
You can see your Endpoint:
HTTP POST: http://localhost:3002/products/create?name=Jorge&price=20
It's not about req.body, it's a req.params. So you can use req.params.name and req.params.price.
🕵️♂️ So, If you're passing your data using parameres, your code will looks like this:
exports.product_create = function (req, res, next) {
var product = new Product(
{
name: req.params.name,
price: req.params.price
}
);
console.log(req.params);
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Bags Created successfully')
})
};
If you want to use req.body, than add your json object tobody if you're using Postman.
🕵️♂️ You can see the image below: An example using postman to passing your data into body, before you send create request to your backend.
So, If You're passing your data from body, than your code will looks like this:
exports.product_create = function (req, res, next) {
var product = new Product(
{
name: req.body.name,
price: req.body.price
}
);
console.log(req.body);
product.save(function (err) {
if (err) {
return next(err);
}
res.send('Bags Created successfully')
})
};
I hope it's can help you.
I am new to node and mongoDb,
I have a mongo db account where i created a collection called "dbTestData"
I am trying to create CRUD operation using node express mongoose and express,
and i am using postman to get post update and delete values to mlab db.
My Get call is working fine, but when i try to post values in Json like,
i am getting success message , but when i check the db it is saved as
{
"_id": {
"$oid": "5c3ad1c19bc5932f800d26f7"
},
"__v": 0
}
My app.js
const express = require('express');
const bodyParser = require("body-parser");
const mongoose=require('mongoose');
const app = express();
const dbTestData=require('./models/post')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
mongoose.connect("mongodb://<userName>:<password>#ds221242.mlab.com:21242/kiitasklist").then(()=>{
console.log("hello");
}).catch(
()=>{
console.log("heee");
});
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT,DELETE, OPTIONS"
);
next();
});
app.post("/api/posts", (req, res, next) => {
const post = new dbTestData({
id:req.body.id,
name:req.body.name
});
post.save().then(documents=>{
console.log(post);
res.status(201).json({
message: 'Post added successfully'
});
});
});
app.get("/api/posts",(req,res,next)=>{
dbTestData.find().then(documents=>{
res.status(200).json({
message:'Posts fetched successful',
posts:documents
});
});
});
app.put("/api/posts/:id",(req,res,next)=>{
const post = new dbTestData({
_id:req.body._id,
name:req.body.name
});
dbTestData.updateOne({_id:req.params.id},post).then(result=>{
res.status(200).json({message:"update successfully"});
});
});
app.delete("/api/posts/:id",(req,res,next)=>{
dbTestData.deleteOne({_id:req.params.id}).then(documents=>{
res.status(200).json({
message:'posts fetched successful',
posts:documents
});
});
});
module.exports = app;
My Server.js
const http = require('http');
const app = require('./api/app');
const port = process.env.PORT || 3000;
const server = http.createServer(app);
server.listen(port);
My post.js where i have created the mongoose schema
const mongoose=require('mongoose');
var Schema = mongoose.Schema;
module.exports= mongoose.model("dbTestData", new Schema({}), "DbTestData");
both the get and delete works ,
But the post and put is not happening properly, it returns a success message in my console but empty value like
{
"_id": {
"$oid": "5c3ad1c19bc5932f800d26f7"
},
"__v": 0
}
is saved during POST and nothing happens during PUT.
To solve this post issue
var Schema = mongoose.Schema;
PostSchema = new Schema({
id:Number,
name: String
});
// the compile the model using mongoos model function giving the schema u created
const Post = module.exports= mongoose.model("dbTestData", PostSchema, "DbTestData");
after that in your post req do it like this
//before posting you need to require the model first
const Post = require('./models/post'); // your post.js
app.Post("/api/posts", (req, res, next) => {
const post = new Post({
id:req.body.id,
name:req.body.name
});
post.save().then(documents=>{
console.log(post);
res.status(201).json({
message: 'Post added successfully'
});
});
});
make sure you create/define your schema correctly in order to save data using it.
after that put is the same the way u did it should work fine after u define your schema correctly
and finally try this also. make sure you add these tow line the exact same way I have given in your case you have made them switched
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
I am stuck with a problem from last 3 hours, I was trying to upload file and other post data to the server side, I am using angular for frontend part and node for server side.
This is my component.ts code
save(data) {
console.log(data);
const files: Array<File> = this.filesToUpload;
console.log(files);
for(let i = 0; i < files.length; i++){
this.formData.append("image[]", files[i], files[i]['name']);
}
//trying to send some dummy entry but no luck
this.formData.append('title','dasdasdas');
// console.log(this.formData.getAll('image'));
// console.log('form data variable : '+
this.formData.toString());
// console.log(this.formData.getAll('image[]'));
this.restApi.addRecipe(this.formData).subscribe(res =>
{
console.log(res);
});
This is my angular service code:
addRecipe(data){
console.log(this.baseUrl);
const headers = new Headers({});
let options = new RequestOptions({ headers });
return this.http.post(this.baseUrl+'addRecipe',data,options).map(res=>res.json());
}
This is my server.js code:
const express = require('express');
const mongoose = require('mongoose');
const admin = require('./routes/admin');
const path = require('path');
const app = express();
const config = require('./config/config');
const bodyParser = require('body-parser');
const cors = require('cors');
mongoose.Promise = global.Promise;
mongoose.connect(config.database, (err) => {
if (err) {
console.log(err);
} else {
console.log('connected')
}
})
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'client/dist')));
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
//admin route
app.use('/admin', admin);
app.listen(3000, (err) => {
if (err) console.log("err");
console.log("port started");
})
This is the controller code where I have written the logic of inserting:
module.exports.addRecipe = (req, res) => {
const body = req.body
console.log(body);
return;
...
}
whenever I console.log(body), I am getting a empty object {}, from the angular side I have tried changing the content type but nothing seems to be working, I am new to node and angular and I searched a lot about this problem but no solution seems to be working.
First time posting. I'm building a blog site and using Node.js, Express.js, MongoDB, and Mongoose for my back-end. GET and POST work for getting and creating posts. However, PUT and DELETE are not working when using POSTMAN as I get "Cannot DELETE(PUT) /api/blog". I feel like it's related to routes, particularly when I'm trying to findById (/api/blog/:blog_id).
Server.js
var express = require('express');
var mongoose = require('mongoose');
var port = process.env.PORT || 8080;
var logger = require('morgan');
var favicon = require('serve-favicon');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var app = express();
mongoose.connect('mongodb://127.0.0.1:27017/blog');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
db.once('open', function callback () {
console.log("Scrolls are ready to be written!!!");
});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.text());
app.use(methodOverride());
app.use(express.static(__dirname + '/client'));
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, HEAD, DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, content-type, Accept');
next();
});
// *Routes*
require('./app/routes.js')(app);
// *App Start*
// http://localhost:8080
app.listen(port);
console.log('Connected to port ' + port);
exports = module.exports = app;
app/routes.js
var Blog = require('./models/blog');
module.exports = function(app) {
// *Server Routes*
// Place API calls here
// Place Authentication routes here
//var express = require('express');
//var router = express.Router();
// *API Routes*
// Uses Mongoose to GET all Blog Posts from database
app.get('/api/blog', function(req, res, next) {
Blog.find(function(err, blog) {
// If error
if (err) return next(err);
//res.send(err);
res.json(blog);
});
});
// Uses Mongoose to POST new Blog Posts in database
app.post('/api/blog', function(req, res) {
Blog.create({
title: req.body.title,
body: req.body.body,
author: req.body.author,
comments: req.body.comments,
likes: req.body.likes,
dislikes: req.body.dislikes,
image: req.body.image,
createdOn: req.body.createdOn
}, function(err, blog) {
if (err)
res.send(err);
Blog.find(function(err, blog) {
if (err)
res.send(err)
res.json({ message: 'Blog Post Created!' });
});
});
});
// Uses Mongoose to GET Blog Post by _id from database
app.get('/blog/:blog_id', function(req, res) {
Blog.findById(req.params.blog_id, function(err, blog) {
if (err)
res.send (err);
res.json(blog);
});
})
// Uses Mongoose to PUT updates for Blog Posts by _id in database
app.put('/blog/:blog_id', function(req, res) {
Blog.findById(req.params.blog_id, function (err, blog) {
if (err) res.send(err);
if (req.body.title) blog.title = req.body.title;
if (req.body.body) blog.body = req.body.body;
if (req.body.author) blog.author = req.body.author;
if (req.body.comments) blog.comments = req.body.comments;
if (req.body.likes) blog.likes = req.body.likes;
if (req.body.dislikes) blog.dislikes = req.body.dislikes;
if (req.body.image) blog.image = req.body.image;
if (req.body.createdOn) blog.createdOn = req.body.createdOn;
blog.save( function (err) {
if (err) send (err);
res.json({message: 'Blog Post Updated!'});
});
});
});
// Uses Mongoose to DELETE Blog Posts by _id in database
app.delete('/blog/:blog_id', function(req, res) {
Blog.remove({
_id: req.params.blog_id
}, function (err, blog) {
if (err) return res.send(err);
res.json({ message: 'Blog Post Deleted'});
});
});
// API's for PUT, POST, DELETE go here
// *Frontend Routes*
// Route to handle all AngularJS requests
app.get('*', function(req, res) {
res.sendfile('./client/views/index.html');
});
};