Sequelize throw AssertionErrors with MySQL - mysql

I'm building an API using nodejs, sequelize, dan MySQL database (10.1.21-MariaDB). When I tried to do some PATCHing (updating data), it throws AssertionErrors, but it works fine with POST (inserting data).
Here's my patch code:
const express = require('express');
const router = express.Router();
const brandModel = sequelize.define('tbl_brand', {
brand_name: {
type: Sequelize.STRING,
allowNull: false
},
}, {
freezeTableName: true,
});
router.patch('/:id', (req, res, next) => {
const id = req.params.id;
const newModel = {
brand_name: req.body.brand_name
};
sequelize.authenticate().then(() => {
const promise = brandModel.update(newModel, {brand_id: id});
return promise.then(function(item){
res.status(201).json({
success: true,
result: item
});
});
})
.catch(err => {
res.status(500).json({
success: false,
result: err
});
});
});
I use postman and access it like this:
http://localhost:3000/brand/1
With Raw JSON:
{
"brand_name" : "Adidasssss"
}
And here's the result:
{
"success": false,
"result": {
"generatedMessage": false,
"name": "AssertionError [ERR_ASSERTION]",
"code": "ERR_ASSERTION",
"expected": true,
"operator": "=="
}
}
What could be the problem?

Nevermind... I was careless, I was updating an empty instance called brandModel. It should be searched first then do the update

Related

How do I skip the primary key auto increment in nodejs ORM sequelize when unique constraint error occurs

How do I skip the primary key auto increment in sequelize node.js when unique constraint error occurs
When I enter same username twice that was defined as unique into mysql by using of Postman my program is running correct way but the problem is the incremental primary key is still continuing.
For example
when I insert another different username value the program is jumping at one of the sequential primary key as expected.
So that, How can I stop the auto increment id as I restricted not to insert duplicate username values in my database
/* DATABASE CONFIGURATION FILE */
const { Sequelize, QueryTypes, DataTypes, Op, UniqueConstraintError, ValidationErrorItem } = require(`sequelize`);
const sequelize = new Sequelize(`tutorialdb`, `root`, ``, {
host: `localhost`,
dialect: `mysql`,
logging: true,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},
});
sequelize
.authenticate()
.then(() => {
console.log(`Connection has been established successfully...`);
})
.catch((err) => {
console.log(`Unable to connect to the database: `, err);
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.QueryTypes = QueryTypes;
db.DataTypes = DataTypes;
db.Op = Op;
db.ValidationErrorItem = ValidationErrorItem;
db.UniqueConstraintError = UniqueConstraintError;
db.postModel = require(`../models/post.model.jsx`)(sequelize, DataTypes);
db.sequelize.sync({ force: false, alter: false, match: /tutorialdb$/ }).then(() => {
console.log(`Tables were synced successfully`);
});
module.exports = db;
/* Model definition File */
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define(
`post`,
{
id: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
title: {
type: DataTypes.STRING(30),
allowNull: false,
validate: {
notEmpty: {
args: true,
msg: `Title is required`,
},
len: {
args: [3, 50],
msg: `Title must between 3 and 30 characters`,
},
},
},
text: {
type: DataTypes.STRING(100),
allowNull: false,
validate: {
notEmpty: {
args: true,
msg: `Text is required`,
},
len: {
args: [5, 100],
msg: `Text must between 5 and 100 characters`,
},
},
},
username: {
type: DataTypes.STRING(20),
allowNull: false,
unique: true,
validate: {
notEmpty: {
args: true,
msg: `Username is required`,
},
len: {
args: [3, 20],
msg: `Username must between 3 and 20 characters`,
},
},
},
},
{
timestamps: true,
paranoid: true,
}
);
Post.beforeCreate(async (post, options) => {
post.username = post.username.toLowerCase();
});
Post.beforeUpdate(async (post, options) => {
post.username = post.username.toLowerCase();
});
return Post;
};
/* Controller File */
const db = require(`../config/db.config.jsx`);
const postModel = db.postModel;
const Sequelize = db.Sequelize;
const sequelize = db.sequelize;
const QueryTypes = db.QueryTypes;
const DataTypes = db.DataTypes;
const Op = db.Op;
const ValidationErrorItem = db.ValidationErrorItem;
const UniqueConstraintError = db.UniqueConstraintError;
/* Create new Post */
exports.create = async (req, res) => {
const transactions = await sequelize.transaction();
try {
const trim = (noSpace) => {
return noSpace.replace(/\s/g, ``);
};
const post = await postModel.create(
{
title: req.body.title,
text: req.body.text,
username: trim(req.body.username),
},
{ transaction: transactions }
);
await transactions.commit();
res.status(200).json(post);
} catch (err) {
await transactions.rollback();
const messages = {};
let message;
err.errors.forEach((error) => {
messages[error.path] = error.message;
message = messages[error.path];
});
res.status(500).json(message);
}
};
/* Find All posts */
exports.findAll = async (req, res) => {
const transactions = await sequelize.transaction();
try {
const title = req.query.title;
const text = req.query.text;
const username = req.query.username;
let finder = title ? { title: { [Op.like]: `%${title}%` } } : text ? { text: { [Op.like]: `%${text}%` } } : username ? { username: { [Op.like]: `%${username}%` } } : null;
const posts = await postModel.findAll({
as: `posts`,
attributes: [`id`, `title`, `text`, `username`, `createdAt`, `updatedAt`, `deletedAt`],
transaction: transactions,
lock: false,
paranoid: false,
order: [[`id`, `DESC`]],
where: finder,
});
await transactions.commit();
res.status(200).json(posts);
} catch (err) {
await transactions.rollback();
res.status(500).json(err.message);
}
};
/* Router File */
module.exports = (app) => {
const router = require(`express`).Router();
const postCtrl = require(`../controllers/post.controller.jsx`);
router.route(`/post`).post(postCtrl.create).get(postCtrl.findAll);
app.use(`/api/v1`, router);
};
/* MiddleWare Logger File */
const moment = require(`moment`);
/* Create Logger */
const logger = (req, res, next) => {
console.log(`${req.protocol}://${req.get(`host`)}${req.originalUrl} : ${moment().format()}`);
next();
};
module.exports = logger;
/* Server File */
const express = require(`express`);
const cors = require(`cors`);
const logger = require(`./src/middleware/logger.jsx`);
const app = express();
const corsOptions = {
origin: `http://localhost:4001`,
optionsSuccessStatus: 200,
};
app
.use(cors(corsOptions))
.use(logger)
.use(express.json())
.use(express.urlencoded({ extended: false }))
.get(`/`, (req, res) => res.status(200).send(`Welcome to fullstack tutorial application`));
require(`./src/routes/routers.jsx`)(app);
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => console.log(`Server is running on port ${PORT}...`));
The output result is working well. But the primary Key auto-increment is still continuing
http://localhost:4000/api/v1/post : 2022-08-28T11:02:47+03:00
Executing (ac12d76f-d7dc-4040-9692-3d6b853feac9): START TRANSACTION;
Executing (ac12d76f-d7dc-4040-9692-3d6b853feac9): INSERT INTO posts
(id,title,text,username,createdAt,updatedAt) VALUES
(DEFAULT,?,?,?,?,?); Executing (ac12d76f-d7dc-4040-9692-3d6b853feac9):
ROLLBACK;
I had attempted the following solution and works me perfectly.
/* Create new User */
exports.create = async (req, res) => {
const trim = (noSpace) => {
return noSpace.replace(/\s/g, ``);
};
const transactions = await sequelize.transaction();
try {
const { username, password } = req.body;
const users = await userModel.findOne({
where: { username: trim(username) },
transaction: transactions,
});
if (users !== null) {
await transactions.rollback();
res.json(`Username ${username} already exist`);
} else {
const user = await userModel.create(
{
username: trim(username),
password: trim(password),
},
{
transaction: transactions,
}
);
await transactions.commit();
res.status(200).json(user);
}
} catch (err) {
await transactions.rollback();
const messages = {};
let message;
err.errors.forEach((error) => {
messages[error.path] = error.message;
message = messages[error.path];
});
res.status(500).json(message);
}
};
exports.create = async (req, res) => {
const transactions = await sequelize.transaction();
try {
const trim = (noSpace) => {
return noSpace.replace(/\s/g, ``);
};
const [user, created] = await userModel.findOrCreate({
where: { username: trim(req.body.username) },
defaults: { password: trim(req.body.password) },
transaction: transactions,
});
return created ? (await transactions.commit(), res.status(200).json(user)) : user ? (await transactions.rollback(), res.json(`Username already exist`)) : err;
} catch (err) {
await transactions.rollback();
const messages = {};
let message;
err.errors.forEach((error) => {
messages[error.path] = error.message;
message = messages[error.path];
});
res.status(500).json(message);
}
};
I am not sure about issue's existence in previous versions of sequelize. But this issue does not exist if using Object.findOrCreate() with following mentioned versions.
However this issue does appear if using Object.create() method with unique constraint set for field value and not checking field value existence prior to using Object.create() e.g in following code email unique property is set and if user.create() is used for an existing email in db an error is thrown but userid is incremented thus for next successful creation userid is not as expected.
An alternate solution is using user.findOne() prior to use user.create() but out of the scope of this answer and issue can be avoided using object.findOrCreate() as following
Versions: "mysql2": "^2.3.3", "sequelize": "^6.28.0"
To avoid the issue try using following approach
const router = require("express").Router();
const { Sequelize, DataTypes, Model } = require("sequelize");
const dotenv = require("dotenv");
dotenv.config();
const sequelize = new Sequelize(
process.env.MYSQL_DB_NAME,
process.env.MYSQL_DB_USER,
process.env.MYSQL_DB_PASS,
{
host: process.env.MYSQL_DB_HOST,
dialect: "mysql",
}
);
class User extends Model {}
User.init(
{
userid: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
field: "fUserID",
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
field: "fEmail",
},
password: {
type: DataTypes.STRING(1024),
allowNull: false,
field: "fPassword",
},
firstname: {
type: DataTypes.STRING,
field: "fFirstName",
},
lastname: {
type: DataTypes.STRING,
field: "fLastName",
},
metadata: {
type: DataTypes.STRING(2048),
field: "fMetaData",
},
created: {
type: DataTypes.DATE,
field: "fCreated",
},
updated: {
type: DataTypes.DATE,
field: "fUpdated",
},
},
{
sequelize,
tableName: "tbl_user",
timestamps: true,
id: "userid",
createdAt: "created",
updatedAt: "updated",
}
);
router.post("/register", async (req, res) => {
try {
const [user, created] = await User.findOrCreate({
where: { email: req.body.email },
defaults: {
password: req.body.password,
firstname: req.body.firstname,
lastname: req.body.lastname,
metadata: "Any thing",
},
});
if (created === false) return res.status(400).send("email already exist");
res.send(user.toJSON());
} catch (ex) {
res.status(400).send(ex.errors[0].message);
}
});
module.exports = router;

nodejs - passport.use callback return dataValues and _previousDataValues instead of a normal object

I am using passport.js module for Authentication and Sequelize mysql for database management.
error occurs when authenticating user:
{
"errors": {
"message": "WHERE parameter \"id\" has invalid \"undefined\" value",
"error": {}
}
}
When authenticating the user, console.log(jwtPayload) in file passport.js shows below results.
{
dataValues: {
id: '06c19eb0-995f-45f4-81d7-26ec3b401234',
email: 'CCCC#gmail.com',
createdAt: '2021-05-14T01:51:31.000Z',
updatedAt: '2021-05-14T01:51:31.000Z'
},
_previousDataValues: {
id: '06c19eb0-995f-45f4-81d7-26ec3b401234',
email: 'CCCC#gmail.com',
createdAt: '2021-05-14T01:51:31.000Z',
updatedAt: '2021-05-14T01:51:31.000Z'
},
_changed: {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [ 'id', 'email', 'createdAt', 'updatedAt' ]
},
isNewRecord: false,
iat: 1620961695
}
instead of
{
id: '06c19eb0-995f-45f4-81d7-26ec3b401234',
email: 'CCCC#gmail.com',
createdAt: '2021-05-14T01:51:31.000Z',
updatedAt: '2021-05-14T01:51:31.000Z'
}
passport.js
var passport = require('passport');
const passportJWT = require("passport-jwt");
const JWTStrategy = passportJWT.Strategy;
var LocalStrategy = require('passport-local').Strategy;
const ExtractJWT = passportJWT.ExtractJwt;
const bcrypt = require('bcryptjs');
var User = require('../models/Users')
module.exports = function(passport) {
passport.use(new JWTStrategy({
jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),
secretOrKey : 'your_jwt_secret'
},
function (jwtPayload, done) {
console.log(jwtPayload)
return User.findOne({where: {id:jwtPayload.id}})
.then(user => {
return done(null, user);
})
.catch(err => {
return done(err);
});
}
));
};
Sequelize returns dataValues and _previousDataValues properties by design. You can pass the current values with a small modification.
return User.findOne({where: {id:jwtPayload.id}})
.then(user => {
return done(null, user.dataValues);
})

error: SequelizeValidationError: string violation: created cannot be an array or an object

I am implementing MERN Stack Login / Registration and trying to test my response in Postman step by step. Firstly, I written the code for Registration then for Login but in case of calling registration link I am getting the following error in postman:
error: SequelizeValidationError: string violation: created cannot be an array or an object
Can someone provide any suggestions to help? I think in User.js findone() function is having some sort of miss from my side.
Could there be any other solution?
./database/DB.js
const db = {}
const sequelize = new Sequelize("mern", "root", "", {
host: "localhost",
dialect: "mysql",
port: "3307",
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
})
db.sequelize = sequelize
db.sequelize = sequelize
module.exports = db
./models/User.js
const db = require("../database/db")
module.exports = db.sequelize.define(
'user',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
first_name: {
type: Sequelize.STRING
},
last_name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
created: {
type: Sequelize.STRING
}
},
{
timestamps: false
}
);
./routes/User.js
const users = express.Router()
const cors = require('cors')
const jwt = require("jsonwebtoken")
const bcrypt = require('bcrypt')
const User = require("../models/User")
users.use(cors())
process.env.SECRET_KEY = 'secret'
users.post('/register', (req, res) => {
const today = new Date()
const userData = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
created: today
}
User.findOne({
where: {
email: req.body.email
}
})
.then(user => {
if(!user){
bcrypt.hash(req.body.password, 10, (err, hash) => {
userData.password = hash
User.create(userData)
.then(user => {
res.json({status: user.email + ' registered'})
})
.catch(err => {
res.send('error: ' + err)
})
})
} else {
res.json({error: "User already exists"})
}
})
.catch(err => {
res.send('error: ' + err)
})
})
users.post('/login', (req, res) => {
User.findOne({
where: {
email: req.body.email
}
})
.then(user => {
if(user) {
if(bcrypt.compareSync(req.body.password, user.password)) {
let token = jwt.sign(user.dataValues, process.env.SECRET_KEY, {
expiresin: 1440
})
res.send(token)
}
} else {
res.status(400).json({error: 'User does not exist'})
}
})
.catch(err => {
res.status(400).json({ error: err})
})
})
module.exports = users
package.json
"name": "login-registration",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^3.0.6",
"bcryptjs": "^2.4.3",
"body-parser": "^1.17.2",
"cors": "^2.8.4",
"express": "^4.16.3",
"jsonwebtoken": "^7.4.2",
"mysql": "^2.14.1",
"mysql2": "^1.6.1",
"nodemon": "^1.18.3",
"sequelize": "^4.38.0"
}
}
Server.js
var cors = require ('cors')
var bodyParser = require("body-parser")
var app = express()
var port = process.env.PORT || 5000
app.use(bodyParser.json())
app.use(cors())
app.use(bodyParser.urlencoded({extended: false}))
var Users = require('./routes/users')
app.use('/users', Users)
app.listen(port, () => {
console.log("Server is running at port: " + port)
})
In ./routes/User.js, under the /post register route, the userData object has a created field with today property which is a Date object.
In ./models/User.js you specify that created should have type Sequelize.STRING.
This is the contradiction that is causing the error. When you call User.create(userData), it gives you that error because the input parameter is of the wrong type.
To fix this, you either need to have created expect a type of Sequlize.Date or convert the today date object to a string.
const today = new Date().toJSON();
There are many different to string functions for the Date class. You should pick the one that best suits you here
This error is as a result of submitting a value of a wrong type compared to the
one declared in the model. Therefore, change it to the appropriate
type which is "JSON" instead of "STRING".
./models/User.js
const db = require("../database/db")
module.exports = db.sequelize.define(
'user',
{
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
first_name: {
type: Sequelize.STRING
},
last_name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
password: {
type: Sequelize.STRING
},
created: {
type: Sequelize.JSON
}
},
{
timestamps: false
}
);
Its the "today" attribute that's causing the issue, you are trying to save a date obj instead of string. Change it to string while saving.

How to fetch associated data with models generated form Sequalize?

I have been developing a NodeJs backend application with an MySQL support with Sequelize as the ORM. I'm trying to fetch data by calling an API that I have created. It sends the data as an response. But it doesn't containg the associated object related to the foriegn key relationships.
I already had a MySQL database and I was using sequelize ORM, I used sequelize-auto to generate the model classes. All the model classes were generated successfully. But the associations were not generated with the models. Therefore to cater to the associations I had to manually add the associations to the model class. Then I create the route files and created the HTTP GET method. But the API endpoint doesn't send the data as expected.
following shows the model classes and route files that I have created.
module.exports = function(sequelize, DataTypes) {
const Department = sequelize.define('Department', {
department_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING(100),
allowNull: false
},
description: {
type: DataTypes.STRING(1000),
allowNull: true
}
}, {
tableName: 'department',
timestamps: false,
underscored: true
});
Department.associate = function(models) {
// associations can be defined here
Department.hasMany(models.Category, {
foreignKey: 'department_id',
as: 'categories',
});
};
return Department;
};
module.exports = function(sequelize, DataTypes) {
const Category = sequelize.define('Category', {
category_id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
department_id: {
type: DataTypes.INTEGER(11),
allowNull: false
},
name: {
type: DataTypes.STRING(100),
allowNull: false
},
description: {
type: DataTypes.STRING(1000),
allowNull: true
}
}, {
tableName: 'category',
timestamps: false,
underscored: true
});
Category.associate = function(models) {
// associations can be defined here
Category.belongsTo(models.Department)
};
return Category;
};
var express = require('express');
var router = express.Router();
var model = require('../models/index');
/* GET departments listing. */
router.get('/', function(req, res, next) {
model.Department.findAll({})
.then(department => res.json({
error: false,
data: department
}))
.catch(error => res.json({
data: [],
error: true
}));
});
module.exports = router;
var express = require('express');
var router = express.Router();
var model = require('../models/index');
/* GET category listing. */
router.get('/', function(req, res, next) {
model.Category.findAll({})
.then(category => res.json({
error: false,
data: category
}))
.catch(error => res.json({
data: [],
error: true
}));
});
module.exports = router;
Response for /department route
{
"error": false,
"data": [
{
"department_id": 1,
"name": "Regional",
"description": "Proud of your country? Wear a T-shirt with a national symbol stamp!"
},
{
"department_id": 2,
"name": "Nature",
"description": "Find beautiful T-shirts with animals and flowers in our Nature department!"
},
{
"department_id": 3,
"name": "Seasonal",
"description": "Each time of the year has a special flavor. Our seasonal T-shirts express traditional symbols using unique postal stamp pictures."
}
]
}
Response for /category route
{
"data": [],
"error": true
}
I was expecting data to come with associated objects as well. But it doesn't send the data as expected. What have I done wrong here.
The thing here is that you are not saying on the query that you need the associate data. To do this you have to use include inside the findAll() function.
/* GET departments listing. */
router.get('/', function(req, res, next) {
model.Department.findAll({
include: [{
model: model.Category
as: 'categories'
}]
})
.then(department => res.json({
error: false,
data: department
}))
.catch(error => res.json({
data: [],
error: true
}));
});
Edit:
I saw that you changed the default primary key for the models, so you also has to specify that on the Category association. Sequelize by default only works with one way association, on your case from Deparment to Category. Sequelize doesn't know about Deparment foreignkey on Category, even when you defined it. You have to define which key are you pointing.
Category.associate = function(models) {
// associations can be defined here
Category.belongsTo(models.Department, {as: 'department', foreignKey: 'department_id'})
};

Insertion issue in Json Array object mongodb with Nodejs?

I am new to mongodb , I have below Json structure in mongodb ,
{
"_id" : ObjectId("59d62452a164b51d64b714c2"),
"folderName" : "Avinash 1234",
"tag" : "search",
"ismainFolder" : true,
"innerFolder" : [
{
"ismainFolder" : false,
"foldername" : "Test12",
"_id" : ObjectId("59d72246e66adf2cfcfdd6e6")
}
],
"innerFiles" : [
{
"filelocation" : "",
"isFolder" : false,
"filename" : "Penguins.jpg",
"_id" : ObjectId("59d7223de66adf2cfcfdd6e5")
},
{
"filelocation" : "",
"isFolder" : false,
"filename" : "Desert.jpg",
"_id" : ObjectId("59d72ff4e66adf2cfcfdd6ec")
},
{
"filelocation" : "",
"isFolder" : false,
"filename" : "Hydrangeas.jpg",
"_id" : ObjectId("59d731dfe66adf2cfcfdd6ed")
},
{
"filelocation" : "",
"isFolder" : false,
"filename" : "Chrysanthemum.jpg",
"_id" : ObjectId("59d73252e66adf2cfcfdd6ee")
}
],
"__v" : 0
}
For innerFiles array i need to insert the Tag field depending on the id ("_id" : ObjectId("59d7223de66adf2cfcfdd6e5")) . I used following nodeJs code but it adding as a new object . Please give me the solution .
exports.addTagForSearch = function (req, res, next) {
var tagDetails = req.body.tagDetails;
console.log("tagDetails", tagDetails);
console.log("tagDetails", tagDetails._id);
Repository.find({ _id: tagDetails._id, }, { innerFiles: { $elemMatch: { _id: tagDetails._id } } },function (err, response) {
$push: {
innerFiles: {
"tagName": tagDetails.tagname,
}
//"filelocation": tagDetails.filelocation
}
}, { upsert: true, new: true }, function (err, post) {
if (err) return next(err);
return res.status(200).json("success");
});
}
but above code inserting as a new object , Please give me solution please .
First I need to create a database for that I had a config.js file . Here is the code
module.exports = {
'secretKey': '12345-67890-09876-54321',
'mongoUrl' : 'mongodb://localhost:27017/innerFiles'
}
Next create a models folder and keep this order.js in it
// grab the things we need
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var folderSchema=new Schema({
ismainFolder:{
type:String,
//required:true,
default:''
},
foldername:{
type:String,
//required:true,
default:''
}
});
var innerSchema=new Schema({
filelocation:{
type:String,
//required:true,
default:''
},
isFolder:{
type:String,
//required:true,
default:''
},
filename:{
type:String,
//required:true,
default:''
}
});
var main= new Schema({
folderName:{type:String},
tag:{type:String},
ismainFolder:{type:String},
innerFolder:[folderSchema],
innerFiles:[innerSchema]
},{ strict: false });
var Order= mongoose.model('main', main);
// make this available to our Node applications
module.exports = Order;
Next create a routes folder and keep this orderRouter.js file in it
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var Orders = require('../models/orders');
var app = express();
var orderRouter = express.Router();
orderRouter.use(bodyParser.json());
orderRouter.get('/get',function (req, res, next) {
Orders.find({}, function (err, order) {
if (err) throw err;
res.json(order);
});
})
orderRouter.post('/post',function (req, res, next) {
Orders.create(req.body, function (err, order) {
if (err) {
res.status(400).send('Bad request');
}
else{
console.log('order created!');
var id = order._id;
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Added the order with id: ' + id);
}
});
})
orderRouter.get('/:orderId',function (req, res, next) {
Orders.findById(req.params.orderId, function (err, order) {
if (err) {
res.status(404).send('OrderId not found');
}
else{
res.json(order);
}
});
})
orderRouter.put('/addingField',function(req,res){
//var tagDetails = req.body;
console.log("tagDetails:"+req.body.subId);
console.log("tagname:"+req.body.tagname);
Orders.update(
{_id:req.body.mainId,'innerFiles._id':req.body.subId},
{$set:{'innerFiles.$.tagName':req.body.tagname}},
function (err, article) {
if (err) return console.log(err);
res.json(article);
});
});
app.use('/orders',orderRouter);
app.use(express.static(__dirname+'/public'));
module.exports = orderRouter;
Next create a app.js file this is the server code
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var config = require('./config');
mongoose.connect(config.mongoUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
// we're connected!
console.log("Connected correctly to server");
});
var orderRouter = require('./routes/orderRouter');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
// passport config
app.use(passport.initialize());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/orders',orderRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.json({
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.json({
message: err.message,
error: {}
});
});
app.listen(3000,function(){
console.log("Server listening on 3000");
});
module.exports = app;
And run the server as node app.js.You can post data using this api http://localhost:3000/orders/post you need to use post method.Here is the sample input example for posting
{
"folderName" : "Avinash 1234",
"tag" : "search",
"ismainFolder" : "true",
"innerFolder" : [
{
"ismainFolder" : "false",
"foldername" : "Test12"
}
],
"innerFiles" : [
{
"filelocation" : "a",
"isFolder" : "false",
"filename" : "Penguins.jpg"
},
{
"filelocation" : "b",
"isFolder" : "false",
"filename" : "Desert.jpg"
},
{
"filelocation" : "c",
"isFolder" : "false",
"filename" : "Hydrangeas.jpg"
},
{
"filelocation" : "d",
"isFolder" : "false",
"filename" : "Chrysanthemum.jpg"
}
]
}
and here is the image for it
After posting data check that your data is stored in db or not.Here whatever the id I am giving in response is mainId . For that run this api http://localhost:3000/orders/get use get method for this. Collect the sub document id which is subId in our code.Sample Image for getting
After this here is the task of adding a new field to sub document for that use this api http://localhost:3000/orders/addingField and you need to use put method for this.Here is the input example
{
"mainId":"59dca6aff968a98478aaaa96",
"subId":"59dca6aff968a98478aaaa9a",
"tagname":"hello"
}
And Image for it
After completion of all these steps check into db.Here is the sample image for
it
That's it. Hope it helps.