Search This Blog

2023/04/29

How to add text at start and end of every line in Visual Studio Code

 If in Visual Studio Code you want to add fixed string to start and end of

line in replace window obtained by
Ctrl + H add following regular express also use regular expression
replace option by clicking on third option with *. after first textbox

^(.+)$

then in second textbox add the text you want to add at start of line then
$1 after
that add text you want to add at end of line
e.g.

there is on editor we want to construct a insert statement using this
Italian cuisine

so replace string will be

INSERT INTO Cuisine(name,createdAt,updatedAt) values('$1',now(),now());

Here first part is

INSERT INTO Cuisine(name,createdAt,updatedAt) values('

second part is $1

third part is

',now(),now());

final output will be

INSERT INTO Cuisine(name,createdAt,updatedAt) values('Italian cuisine',
now(),now());

How to remove accidently added directory commited to github

 I accidently commited dist directory in typescript code to github


first modified gitIgnore

added

dist/

then removed directory from github with following commands

git rm -r dist // This deletes from filesystem
git commit . -m "Removed dist directory"
git push

2023/04/28

How to use Sequelize with express in typescript project

 create your project using following generator


ts-express --view=ejs sequelize-typescript

do
npm i

create User Model as
import { DataTypes, Model, Optional } from 'sequelize'
import sequelizeConnection from '../utils/database'

interface UserAttributes {
id: number;
firstName: string;
lastName: string;
email: string;
password: string;
createdAt?: Date;
updatedAt?: Date;
deletedAt?: Date;
}

// we're telling the Model that 'id' is optional
// when creating an instance of the model (such as using Model.create()).
export interface UserInput extends Optional<UserAttributes, 'id'> { }


export class User extends Model<UserAttributes, UserInput> implements UserAttributes {
public id!: number
public firstName!: string
public lastName!: string
public email!: string
public password!: string

// timestamps!
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
public readonly deletedAt!: Date;
}

User.init({
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false
}
}, {
timestamps: true,
sequelize: sequelizeConnection,
paranoid: true
})



create model/index.js

import { User } from './user'

export {
User
}

Now in our user route add

import express from 'express';
import { getLogger } from '@/utils/loggers';
const router = express.Router();
const logger = getLogger('USER_ROUTE');
import { User } from '../models';
import bcrypt from "bcrypt";


router.post('/signin', async function (req, res, next) {
if (!req.body.email || !req.body.password) {
res.status(400).send({
msg: 'Please enter email and password.'
});
} else {
try {
var foundUser = await User.findOne({
where: { email: req.body.email }
})
if (foundUser) {
res.status(400).send({
msg: 'Email ' + foundUser.email + ' already taken ,please login'
});
} else {
let hashedPassword = await bcrypt.hash(req.body.password, bcrypt.genSaltSync(8))
let user = await User.create({
email: req.body.email,
password: hashedPassword,
firstName: req.body.firstName,
lastName: req.body.lastName
})

var returnValue = JSON.parse(JSON.stringify(user))
delete returnValue.password;

res.status(201).send({
msg: 'User created successfully',
data: returnValue
});
}
} catch (exp: any) {
res.status(201).send({
msg: 'Error Occured while creating User:' + exp.toString()
});
}

}


});

export default router;


Util/database


import { Dialect, Sequelize } from 'sequelize'

const dbName = process.env.MYSQL_DATABASE as string
const dbUser = process.env.MYSQL_USER_NAME as string
const dbHost = process.env.MYSQL_HOST
const dbDriver = process.env.NYSQL_DRIVER as Dialect
const dbPassword = process.env.MYSQL_PASSWORD

const sequelizeConnection = new Sequelize(dbName, dbUser, dbPassword, {
host: dbHost,
dialect: dbDriver
})

export default sequelizeConnection

Util/init

import { User } from '../models'
const isDev = process.env.NODE_ENV === 'development'

const dbInit = () => {
User.sync({ alter: isDev })
}
export default dbInit

.env file

MYSQL_USER_NAME = root
MYSQL_PASSWORD = "sangram#81"
MYSQL_PORT = 3306
MYSQL_DATABASE = MatrimonyDb
MYSQL_HOST = localhost
NYSQL_DRIVER = mysql
SECRET_KEY = abcd1234
NODE_ENV = 'development'

bin/www

add following in top in file

import dbInit from '../src/utils/init'
dbInit()


in etc/build.sh

rimraf dist

export NODE_ENV=developement

tsc -p ./tsconfig.build.json --pretty

cp -R src/public dist/src/public

cp package.json dist/

cp .env dist/

Now run application as

npm start

Hit Endpoint using Postman

Endpoint:localhost:3000/users/signin
Body:
{
"firstName": "sanjay",
"lastName": "desai",
"email": "sanjay@gamil.com",
"password": "Wwara#81"
}

Output:
{
"msg": "User created successfully",
"data": {
"id": 2,
"email": "sanjay@gamil.com",
"firstName": "sanjay",
"lastName": "desai",
"updatedAt": "2023-04-28T18:08:32.773Z",
"createdAt": "2023-04-28T18:08:32.773Z"
}
}



Code of this application is at https://github.com/gitsangramdesai/typescript-sequelize

2023/04/27

Lambda function vs traditional function

In JavaScript, there are several differences between traditional functions
and lambda functions (also known as arrow functions):

1)arguments binding:
Arguments objects are not available in arrow functions, but are available
in regular functions.
Example1:

let myFunc = {
showArgs(){
console.log(arguments);
}
};
myFunc.showArgs(1, 2, 3, 4);

Output:
1,2,3,4

Example2:
let myFunc = {
showArgs : ()=> {
console.log(arguments);
}
};
myFunc.showArgs(1, 2, 3, 4);
Output:arguments is not defined

2)Arrow functions cannot be called with new:

ES6 distinguishes between functions that are callable and functions that are
constructible.

If a function is constructible, it can be called with new, i.e. new User().
If a function is callable, it can be called without new (i.e. normal function
call).

Regular functions created through function declarations / expressions are both
constructible and callable.

Example 3:
let x = function(){
console.log(arguments);
};

new x(1,2,3,4)

Output:
[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }

Example 4:
let x = ()=> {
console.log(arguments);
};
new x(1,2,3);

Output:x is not constructor

3) this binding:

Unlike regular functions, arrow functions don’t have their own this or
arguments binding.
Instead, those identifiers are resolved in the lexical scope

Unlike regular functions, arrow functions do not have their own this.
In the case of an arrow function, this refers to the values of this in
the environment the arrow function is defined in (i.e. "outside" the
arrow function) and that remains the same throughout the lifecycle of
the function and is always bound to the value of this in the closest
non-arrow parent function.

Example 5:
function createObject(){
console.log("Inside createObject:",this.foo)
return {
foo:42,
bar:function(){
console.log("Inside bar:",this.foo)
}
}
}

createObject.call({foo:21}).bar()

Output:
Inside createObject: 21
Inside bar: 42


Example :
function createObject() {
console.log("Inside createObject:", this.foo)
return {
foo: 42,
bar: () => {
console.log("Inside bar:", this.foo)
}
}
}

createObject.call({ foo: 21 }).bar()

Output:
Inside createObject: 21
Inside bar: 21

Promise.all ,Promise.any,Promise.race & Promise.allSettled in Node.js

 Promise.any:


Promise.any() is a method introduced in ES2021 (also known as ES12) that
takes an iterable
of Promises and returns a new Promise that is fulfilled
when any of the Promises in the iterable is fulfilled.

The resulting Promise is fulfilled with the value of the first Promise in
the iterable that
was fulfilled. If all of the Promises in the iterable
are rejected, then the resulting Promise is rejected with an AggregateError
that contains an
array of rejection reasons from all the Promises.

const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 300);
});

const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('bar'));
}, 200);
});

const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('baz');
}, 100);
});

Promise.any([promise1, promise2, promise3])
.then((value) => {
console.log(value); // Output: 'foo'
})
.catch((error) => {
console.log(error); // Output: AggregateError: All promises were rejected
});

Promise.all:

Promise.all() is a method introduced in ES6 (ECMAScript 2015) that takes an
iterable of Promises
and returns a new Promise that is fulfilled with an array of values when all
of the Promises
in the iterable are fulfilled.

If any of the Promises in the iterable are rejected, then the resulting
Promise is rejected
with the reason of the first Promise in the iterable that was rejected.

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(4);
}, 2000);
});
const promise3 = Promise.reject(new Error('Rejected'));

Promise.all([promise1, promise2])
.then((values) => {
console.log(values); // Output: [3, 4]
})
.catch((error) => {
console.log(error); // This will not be called
});

Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values); // This will not be called
})
.catch((error) => {
console.log(error); // Output: Error: Rejected
});

Promise.race:

Promise.race() is a method introduced in ES6 (ECMAScript 2015) that takes
an iterable of Promises and
returns a new Promise that is fulfilled or rejected as soon as any of the
Promises in the iterable
are fulfilled or rejected.

Unlike Promise.all(), Promise.race() does not wait for all the Promises in
the iterable to complete.
Instead, it returns as soon as the first Promise in the iterable is
fulfilled or rejected.

const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo');
}, 300);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('bar'));
}, 200);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('baz');
}, 100);
});
Promise.race([promise1, promise2, promise3])
.then((value) => {
console.log(value); // Output: 'baz'
})
.catch((error) => {
console.log(error); // Output: Error: bar
});

Promise.allSettled:
Promise.allSettled() is a method introduced in ES2020 (ECMAScript 2020)
that takes an iterable of Promises and
returns a new Promise that is fulfilled with an array of objects when
all of the Promises in the
iterable have settled (either fulfilled or rejected).


Each object in the array represents the outcome of each Promise in the
iterable, and has the following properties:

status: either "fulfilled" or "rejected".
value: the fulfillment value of the Promise if status is "fulfilled".
reason: the rejection reason of the Promise if status is "rejected".

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(4);
}, 2000);
});
const promise3 = Promise.reject(new Error('Rejected'));

Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results);
// Output:
// [
// { status: 'fulfilled', value: 3 },
// { status: 'fulfilled', value: 4 },
// { status: 'rejected', reason: Error: Rejected }
// ]
});

Promise.race vs Promise.any:
Promise.race() and Promise.any() are both methods for dealing with Promises
in JavaScript,
but they have some differences in behavior.

Promise.race() takes an iterable of Promises and returns a new Promise that
is
fulfilled or rejected as soon as any of the Promises in the iterable are
fulfilled or
rejected. This means that if any of the Promises in the iterable resolve
or reject first,
the resulting Promise will also resolve or reject with the same value or
reason.

Promise.any() also takes an iterable of Promises and returns a new Promise
that is
fulfilled as soon as any of the Promises in the iterable are fulfilled.
However, if all of the Promises in the iterable are rejected, the resulting
Promise
will be rejected with an AggregateError that contains an array of rejection
reasons from all of the Promises.


Node.js :Optimization of Application

Node.js is a fast and scalable JavaScript runtime environment that is
used for developing server-side applications.

Here are some tips to optimize Node.js:

Use the latest version:
Node.js is constantly being updated with new features and performance
improvements. Make sure you are using the latest version of Node.js to
take advantage of these improvements.

Use a process manager:
A process manager like PM2 can help you manage your Node.js application
processes, monitor their performance, and restart them if they crash.

Use a load balancer:
If your application receives a high volume of traffic, using a load balancer
like NGINX or HAProxy can help distribute the load across multiple instances
of your application.

Minimize dependencies:
Keep your dependencies to a minimum and make sure they are up to date.
This will help reduce the size of your application and improve its
performance.

Optimize your code:
Use profiling tools to identify performance bottlenecks in your code
and optimize it for better performance. You can use tools like Node.js's
built-in profiler or third-party tools like Clinic.js.

Use caching:
Use caching techniques to reduce the number of requests to your application's
database or API. This can significantly improve the performance of your
application.

Use gzip compression:
Enable gzip compression for your HTTP responses to reduce the amount of data
transferred between your application and clients, resulting in faster load
times.

Use a CDN:
If your application serves static assets like images, videos, or CSS files,
using a Content Delivery Network (CDN) can help improve their delivery
speed and reduce server load.

By following these tips, you can optimize the performance of your Node.js
application and improve its scalability and responsiveness.

Benefits of Node.js over other Programming Languages

 Node.js has several advantages over other programming languages, some of which include:

  1. Asynchronous programming: Node.js uses an event-driven, non-blocking I/O model that allows it to handle a large number of concurrent connections with minimal overhead. This makes it highly scalable and efficient compared to other languages that use a blocking I/O model.

  2. Cross-platform: Node.js is a cross-platform language, which means it can run on various operating systems such as Windows, Linux, and macOS. This makes it highly versatile and flexible for developers who need to deploy their applications on different platforms.

  3. Large and active community: Node.js has a large and active community of developers who contribute to its growth and development. This means that developers can easily find resources and support to help them with their projects.

  4. Easy to learn: Node.js is based on JavaScript, which is a popular and widely used language. This means that developers who already know JavaScript can quickly learn Node.js without having to learn a new language or framework.

  5. Large ecosystem of packages: Node.js has a large and growing ecosystem of packages and modules available through its package manager, npm. This makes it easy for developers to find and use third-party libraries and modules to build their applications.

  6. Fast development time: Node.js has a fast development time due to its simple and easy-to-use syntax. This means that developers can quickly develop and deploy applications, which is especially useful in today's fast-paced development environment.

Overall, Node.js offers several advantages over other programming languages, including asynchronous programming, cross-platform compatibility, a large and active community, ease of learning, a large ecosystem of packages, and fast development time.

2023/04/26

Read User Input in node.js

 var readline = require('readline')

var r1= readline.createInterface(process.stdin,process.stdout)
r1.question("what is your age",(age)=>{
console.log("Your AGe is " + age)
})


const readline = require('readline')
var r1= readline.createInterface(process.stdin,process.stdout)
r1.setPrompt("what is age?")
r1.prompt()
r1.on('line',(age)=>{
console.log(age)
})

print pyramid of number in node.js

 var n = 9;

var spaceSeperated = true
for (var i = 1; i <= n; i = i + 2) {
var noOfSpaces = (n - i) / 2
if (spaceSeperated) {
noOfSpaces = noOfSpaces * 2
}
var spaces = ' '.repeat(noOfSpaces)
process.stdout.write(spaces);
for (var j = 1; j <= i; j++) {
if (spaceSeperated) {
process.stdout.write(j.toString() + ' ');
}
else {
process.stdout.write(j.toString());
}
}
console.log("\n")
}

2023/04/25

Common HTTP status code and meaning

 HTTP (Hypertext Transfer Protocol) status codes are three-digit numbers returned by a

server in response to a client's request. The status codes provide information about the
request and response between the client and server. Here are some of the most commonly
used HTTP status codes and their meanings:

1xx - Informational

100 - Continue: The server has received the request headers and the client should proceed to send the request body.
101 - Switching Protocols: The server is switching protocols according to the request made by the client.
2xx - Success

200 - OK: The request has succeeded.
201 - Created: The request has been fulfilled, resulting in the creation of a new resource.
204 - No Content: The request has succeeded but there is no representation to return.
3xx - Redirection

300 - Multiple Choices: The requested resource has multiple choices, each with a different location.
301 - Moved Permanently: The requested resource has been permanently moved to a new URL.
302 - Found: The requested resource has been temporarily moved to a new URL.
304 - Not Modified: The requested resource has not been modified since the last time it was accessed.
4xx - Client Errors

400 - Bad Request: The request could not be understood or was missing required parameters.
401 - Unauthorized: Authentication failed or user does not have permissions for requested operation.
403 - Forbidden: Server understood the request, but is refusing to fulfill it.
404 - Not Found: The requested resource could not be found.
5xx - Server Errors

500 - Internal Server Error: The server encountered an unexpected condition that prevented it from fulfilling the request.
502 - Bad Gateway: The server, while acting as a gateway or proxy, received an invalid response from the upstream server.
503 - Service Unavailable: The server is currently unable to handle the request due to a temporary overload or maintenance of the server.

These are just a few of the most common HTTP status codes. There are many more status codes that exist, and each one
provides specific information about the response from the server.

Javascript:match vs matchAll

match():
match() is a method in JavaScript that returns an array of results matching a
string against a regular expression.Returned results depend a lot on using the
global(g) flag. If a g flag is used we will get all results but without
capturing groups.

Code:test1test2
const str = "ReguralExpresion RegExr";
const regex = /E(x)([a-z])/g;
const match = str.match(regex); //Array ["Exp", "Exr"]
console.log(match)

Output:
[ 'Exp', 'Exr' ]

On the other hand, if we don’t use the g flag we will get only the first
complete match but with related capturing groups.

Code:
const str = "ReguralExpresion RegExr";
const regex = /E(x)([a-z])/;
const match = str.match(regex); //Array ["Exp", "x", "p"]
console.log(match)
Output:
[
'Exp',
'x',
'p',
index: 7,
input: 'ReguralExpresion RegExr',
groups: undefined
]

matchAll():
matchAll() returns an iterator that returns all matched groups against a
regular expression, including capturing groups.

Code:
const str = "ReguralExpresion RegExr";
const regex = /E(x)([a-z])/g;
const match = str.matchAll(regex); //returns iterator
Array.from(match, (res) => console.log(res));

Output:
[
'Exp',
'x',
'p',
index: 7,
input: 'ReguralExpresion RegExr',
groups: undefined
]
[
'Exr',
'x',
'r',
index: 20,
input: 'ReguralExpresion RegExr',
groups: undefined
]

same code as above but with for-of loop;

Code:
const str = "ReguralExpresion RegExr";
const regex = /E(x)([a-z])/g;
const match = str.matchAll(regex); //returns iterator
for (const m of match) {
console.log(m);
}

Output:
[
'Exp',
'x',
'p',
index: 7,
input: 'ReguralExpresion RegExr',
groups: undefined
]
[
'Exr',
'x',
'r',
index: 20,
input: 'ReguralExpresion RegExr',
groups: undefined
]

One of the main reasons for using matchAll() over match() is the abilitiy to
access capture groups.

A regular expression for matchAll() needs to have a g flag, otherwise, an
error will be thrown.If there are no matches, match() method returns null but
if there is no match for matchAll() it will returns an empty iterable object.


What is each array element in output of matchall() stands for?

The iterator produces an array for each match, including the capturing groups
with a few extra properties like index, input and groups.Lets takes example of
first array element in above output.

Example:
[
'Exp',
'x',
'p',
index: 7,
input: 'ReguralExpresion RegExr',
groups: undefined
]

index: The index of the first result in the original string. In the above
example Exp starts at position 7 hence index has the value 7.
input: The complete string that matchAll() was run against. In the above
example, that was 'ReguralExpresion RegExr'.
groups: Contains the results of any named capturing groups specified in the
regular expression.

How to capitalize first letter of each word in sentence using regx



var str = "I love javascript Very much"

var x = str.replace(/\w+/g, (matched, index, original) => {
console.log(matched)
return matched.charAt(0).toUpperCase() + matched.substring(1).toLowerCase()
});


console.log(x)

or

var str = "I love javascript Very much"
var arr = str.match(/\w+/g);

var res = ""
for (var i = 0; i < arr.length; i++) {
if(i != arr.length-1){
res = res + arr[i].charAt(0).toUpperCase() + arr[i].substring(1).toLowerCase() + " "
}else{
res = res + arr[i].charAt(0).toUpperCase() + arr[i].substring(1).toLowerCase()
}
}

console.log("[" + res + "]")

or

var str = "I love javascript Very much"
var arr = str.match(/\w+/g);

var res = arr.reduce((s,t)=>{
return s+ t.charAt(0).toUpperCase() + t.substring(1).toLowerCase() + " "
},"")

res = res.trim()
console.log("[" + res + "]")


Uploading multiple files with multer


First install multer node package

then create upload.js as

var multer = require('multer')

var storage = multer.diskStorage({
destination: function (req, file, callback) {
if (file.fieldname == "profilePic") {
callback(null, './uploads/profilePic/');
} else if (file.fieldname == "resume") {
callback(null, './uploads/resume/');
} else {
callback(null, './uploads/other/');
}
},
filename: function (req, file, callback) {
callback(null, Date.now() + '_' + file.originalname);
}
});

const fileFilter = (req, file, cb) => {
if (file.fieldname == "profilePic") {
if ((file.mimetype).includes('jpeg') || (file.mimetype).includes('png') || (file.mimetype).includes('jpg')) {
cb(null, true);
} else {
cb(null, false);
}
}
if (file.fieldname == "resume") {
if ((file.mimetype).includes('doc') || (file.mimetype).includes('openxmlformats')) {
cb(null, true);
} else {
cb(null, false);
}
}
};

var upload = multer({ storage: storage, fileFilter: fileFilter, limits: { fileSize: 1 * 1024 * 1024 } })

module.exports = {
upload: upload
}

create user model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var uniqueValidator = require('mongoose-unique-validator');
const bcrypt = require("bcrypt");
var jwt = require('jsonwebtoken');
var secret = process.env.SECRET_KEY

require('../utils/database')

var UserSchema = new mongoose.Schema({
username: { type: String, lowercase: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true },
email: { type: String, lowercase: true, required: [true, "can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true },
firstName: String,
lastName: String,
password: String,
profilePic: String,
resume: String,
profilePics: [{
type: String
}]
}, {
timestamps: true
});

UserSchema.methods.setPassword = async function (password) {
this.password = await bcrypt.hash(password, bcrypt.genSaltSync(8))
return this;
};

UserSchema.methods.validPassword = async function (password) {
return await bcrypt.compare(password, this.password)
};

UserSchema.plugin(uniqueValidator, { message: 'is already taken.' });


UserSchema.statics.findByUserName = function (username, cb) {
return this.find({ username: username }, cb);
};

UserSchema.methods.generateJWT = function () {
var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);

return jwt.sign({
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
}, secret);
};

UserSchema.methods.toAuthJSON = function () {
return {
username: this.username,
email: this.email,
token: this.generateJWT(),
firstName: this.firstName,
lastName: this.lastName
};
};

var User = mongoose.model('User', UserSchema);

module.exports = {
"User": User,
"UserSchema": UserSchema
}

create routes/users.js

var express = require('express');
var router = express.Router();
var User = require('../models/User').User;
const { model } = require('mongoose')
var { upload } = require('../utils/upload')

//single input type file field
router.post('/signin', upload.single('profilePic'), async function (req, res, next) {
var user = new User({
username: req.body.username,
email: req.body.email,
firstName: req.body.firstName,
lastName: req.body.lastName,
profilePic: req.file.filename
});
var usernameTaken = await User.findByUserName(req.body.username)
if (usernameTaken.length == 0) {
console.log("Hashing password")
var newUser = await user.setPassword(req.body.password)
var result = await newUser.save()
res.json({ "msg": "saved", data: result })
} else {
res.json({ "msg": "username already taken" })
}
});

//two input type file fields
router.post('/signin/twofilefield', upload.fields([{ name: 'resume', maxCount: 1 }, { name: 'profilePic', maxCount: 10 }]), async function (req, res, next) {
//profilePic
var profilePics = []
req.files["profilePic"].forEach((fl) => {
profilePics.push(fl.filename)
})

//resume
var resume = req.files["resume"][0].filename

var user = new User({
username: req.body.username,
email: req.body.email,
firstName: req.body.firstName,
lastName: req.body.lastName,
profilePics: profilePics,
resume: resume
});

var usernameTaken = await User.findByUserName(req.body.username)
if (usernameTaken.length == 0) {
console.log("Hashing password")
var newUser = await user.setPassword(req.body.password)
var result = await newUser.save()
res.json({ "msg": "saved", data: result })
} else {
res.json({ "msg": "username already taken" })
}
});


//multiple files uploaded against single input type file
router.post('/signin/multiupload', upload.array('profilePic', 10), async function (req, res, next) {
var profilePics = []
req.files.forEach((fl) => {
profilePics.push(fl.filename)
})

var user = new User({
username: req.body.username,
email: req.body.email,
firstName: req.body.firstName,
lastName: req.body.lastName,
profilePic: profilePics[0],
profilePics: profilePics
});

var usernameTaken = await User.findByUserName(req.body.username)
if (usernameTaken.length == 0) {
console.log("Hashing password")
var newUser = await user.setPassword(req.body.password)
var result = await newUser.save()
res.json({ "msg": "saved", data: result })
} else {
res.json({ "msg": "username already taken" })
}


});
module.exports = router;





Complete code can be obtained at
https://github.com/gitsangramdesai/mongoose-multer-express