Delete and EDIT API's using expressJS - node.js

I created DELETE API and in the callback function I have written .remove function to delete a product if the id I have given is present. But when I am giving incorrect input, the result is receiving some object which shouldn't be the case. As there is no data with the Id i have given it should be null or undefined.
Can someone help on this?
Route URL-
http://localhost:3000/api/v1/products/:productId/delete
Code -
let deleteProduct = (req, res) => {
if (check.isEmpty(req.params.productId)) {
console.log('productId should be passed')
let apiResponse = response.generate(true, 'productId is missing', 403, null)
res.send(apiResponse)
} else {
productModel.remove({ 'productId': req.params.productId }, (err, result) => {
if (err) {
console.log('Error Occured.')
logger.error(`Error Occured : ${err}`, 'Database', 10)
let apiResponse = response.generate(true, 'Error Occured.', 500, null)
res.send(apiResponse)
} else if (check.isEmpty(result)) {
console.log('Product Not Found.')
let apiResponse = response.generate(true, 'Product Not Found.', 404, null)
res.send(apiResponse)
} else {
console.log('Product Deletion Success')
let apiResponse = response.generate(false, 'Product Deleted Successfully', 200, result)
res.send(apiResponse)
}
})
}
}
let isEmpty = (value) => {
if (value === null || value === undefined || trim(value) === '' || value.length === 0) {
return true;
} else {
return false;
}
}
When I give incorrect productId, Ideally it should give 'Product Not found' but the output is coming as Product Deleted Successfully.

The result will contain an object no matter if it was successful or not, it will never be empty in this case. Please read the documentation here.
check.isEmpty(result) will always be false.

Related

Why my user controller can't get userid property which i have provided in my USERS Schema?

Issue 1: Why my user controller can't get userid property which i have provided in my USERS Schema? i have given a property userid in my Schema which will be a number, but when i am checking my mongobd to see that is userid is coming or not than that userid property is not even showing in my mongobd..
Issue 2: Why my Schema is replicating 3 times whenever i sign up in my app? the Schema is replicating 3 times but every 3 times the mongobd user_id gets change i think its a bug (Note: here the user_id which i am talking about is a user_id which is created by my controller response and in the above issue which i am talking about is a userid that i want to give to my user which will be much smaller and it will be a property)
Mongobd look like this
_id
63613eb2685aa82252cb121b
name
"ecawecawecawce"
phoneNumber
"ewcwaecawecwaecawec"
profileImage
"https://www.pngitem.com/pimgs/m/146-1468479_my-profile-icon-blank-prof…"
selectedCountry
Object
name
"India"
dialCode
"+91"
isoCode
"IN"
flag
"https://cdn.kcak11.com/CountryFlags/countries/in.svg"
__v
0
My Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Users = new Schema({
name: String,
phoneNumber: String,
userid: Number, // Ealier it was a string
profileImage: {
type: String,
default: 'https://www.pngitem.com/pimgs/m/146-1468479_my-profile-icon-blank-profile-picture-circle-hd.png'
},
about: String,
selectedCountry: {
type: Object
}
})
module.exports = mongoose.model("users", Users)
user.controller.js:
const user_module = require('./user.modules');
class user_controller extends user_module {
static create_user = async (req, res) =>{
try {
console.log("controller response",req.body)
let response = await this.save_user_details(req)
let message = 'Success';
res.send({
sucess: true,
message: message,
data: response
})
} catch (error) {
let status_code = error.status.code != undefined ? error.status_code: 500;
let type = error.type != undefined ? err.type: 'Bad Request';
let message = err.custom_msg != undefined ? error.custom_msg: "Something went wrong"
res.status(status_code).send({
sucess: false,
error:type,
message: message
})
}
}
static get_users = async (req, res) =>{
try {
console.log("controller response",req.body)
let response = await this.retrieve_user(req)
let message = 'Success';
res.send({
sucess: true,
message: message,
data: response
})
} catch (error) {
let status_code = error.status.code != undefined ? error.status_code: 500;
let type = error.type != undefined ? err.type: 'Bad Request';
let message = err.custom_msg != undefined ? error.custom_msg: "Something went wrong"
res.status(status_code).send({
sucess: false,
error:type,
message: message
})
}
}
static otp_verify = async (req, res) =>{
try {
console.log("controller response",req.body)
let response = await this.verify_user(req)
if(response.status){
res.send({
success: true,
message: response.message,
data: response.user
})
}else{
res.status(400).send({
success: false,
error: false,
message: response.message
})
}
} catch (error) {
let status_code = error.status_code != undefined ? error.status_code: 500;
let type = error.type != undefined ? err.type: 'Bad Request';
let message = error.custom_msg != undefined ? error.custom_msg: "Something went wrong"
res.status(status_code).send({
sucess: false,
error:type,
message:message
})
res.end();
}
}
}
module.exports = user_controller
user.modules.js:
const models = require('../models');
class user_module {
static save_user_details = async (req) => {
try {
console.log("req body", req.body)
const { profileImage } = req.body
let set_data = req.body
if (!!profileImage) {
set_data.profileImage = profileImage
}
return await models.users.create(set_data)
} catch (error) {
throw error
}
}
static retrieve_user = async (req) => {
try {
let {limit, pagination} = req.query
let query = {}
let projection ={__v: 0}
let options = {
lean: true,
sort: {_id: -1},
skip: !Number(pagination) ? 0: Number(pagination) * !Number(limit) ? 10: Number(limit),
limit: !Number(limit) ? 10: Number(limit)
}
let users = await models.users.find(query, projection, options)
let count = await models.users.count(query)
return {users, count}
} catch (error) {
throw error
}
}
static verify_user = async (req) => {
try {
console.log("req body", req.body)
const { otp, user_id } = req.body
if(otp == '123456'){
let user = await models.users.findById(user_id)
return {user: user, status: true, message: 'success'}
}else{
return {user: null, status: false, message: 'Otp Invalid'}
}
} catch (error) {
throw error
}
}
}
module.exports = user_module
You are not getting the Id because you are trying to get it by user_id, however, It's userid in your model.
Either you have to go with userid OR you have to go with User._id to get your _id which MongoDB creates for every new entry

use async - await with socket.io nodejs

I'm developing a web application using nodejs socket.io and angular 9. In my backend code I have written sockets in socket.connect.service.
Follows is a socket I'm using
socket.on('request-to-sit-on-the-table', async function (data, callback) { //Previously Register
let table = persistence.getTable(tableToken);
if (typeof table === 'undefined') {
let errMsg = 'This table does not exists or already closed.'
callback(prepareResponse({}, errMsg, new Error(errMsg)));
return;
}
//TODO: Get the displayName from the token.
let guest = await guestUserService.getGuestUserByPlayerToken(JSON.parse(data.userToken));***//Here is the issue***
// let displayName = 'DisplayName-' + guest;
let displayName = 'DisplayName-' + Math.random();
//TODO: Check whether the seat is available
// If the new screen name is not an empty string
let isPlayerInCurrentTable = persistence.isPlayerInCurrentTable(tableToken, userToken);
if (displayName && !isPlayerInCurrentTable) {
var nameExists = false;
let currentPlayersTokenArr = persistence.getTableObjectPlayersToken(table)
for (var token in currentPlayersTokenArr) {
let gamePlayer = persistence.getPlayerPlayer(currentPlayersTokenArr[token])
if (typeof gamePlayer !== "undefined" && gamePlayer.public.name === displayName) {
nameExists = true;
break;
}
}
if (!nameExists) {
//Emit event to inform the admin for requesting to sit on the table.
let ownerToken = persistence.getTableObjectOwnerToken(table);
let ownerSocket = persistence.getPlayerSocket(ownerToken);
ownerSocket.emit('requested-to-sit', {
seat: data.seat,
secondaryUserToken: userToken,
displayName,
numberOfChips: envConfig.defaultNumberOfChips
});
callback(prepareResponse({userToken}, 'Player connected successfully.'));
} else {
callback(prepareResponse({}, 'This name is already taken'));
}
} else {
callback(prepareResponse({}, 'This user has already joined to a game. Try clear caching'));
}
});
In my code I'm getting data from another code in guest.user.service. But I get undefined to the value of "guest"
Follows are the methods I have used in guest.user.service
exports.findById = (id) => {
return new Promise(function(resolve, reject) {
guestUserModel.findById(id, (err, data) =>{
if(err){
reject(err);
} else {
resolve(data);
}
});
});
};
exports.getGuestUserByPlayerToken = (playerToken) => {
var player = playerService.findOne({ token: playerToken })
.then(function (data) {
return self.findById(data.guestUser._id.toString());
})
.then(function (guestUser) {
return guestUser.displayName;
})
.catch(function (err) {
throw new Error(err);
})
};
Although I get my displayName for the return value It is not passed to the "guest" in my socket.Is there any syntax issue to get data as I'm using promises.please help
exports.getGuestUserByPlayerToken = async playerToken => {
try {
let player = await playerService.findOne({token:playerToken});
return playerService.findById(player.guestUser._id)
} catch(error) {
console.log(error);
return null;
}
};
This is just handle error on awaited promise not returned one. You need to handle that in caller side.

Nodejs REST API function throws error "Callback is not a function"

I am writing a node app's REST API using Sqlite3. The app will have accounts, and the user should be able to create and update one. My code for creating and fetching accounts works as intended, but my update function throws the error: "TypeError: callback is not a function"
The backend is split in two files; db.js – where I set up the database and create the base function for get/post/put/delete, and app.js – where I call the function from db and perform validation checks.
when i run the function in postman, i get error code 500. in vscode, the terminal reads:
Project/rbrneck/rbrneck-backend/db.js:124
callback([], updatedAccount)
^
TypeError: callback is not a function
at Statement.db.run
code:
//in db.js
exports.updateAccountById = (id, updatedAccount, callback) => {
const query = 'UPDATE accounts SET username = ?, password = ? WHERE id = ?'
const values = [
id,
updatedAccount.username,
updatedAccount.password
]
db.run(query, values, (error) => {
if(error) {
if(error.message == "SQLITE_CONSTRAINT: UNIQUE constraint failed: accounts.username") { //username taken
callback(['usernameTaken'])
} else {
callback(['databaseError'])
}
} else {
//const accountUpdated = (this.changes == 1)
callback([], updatedAccount) //HERE IS THE CALLBACK THE ERROR IS REFERRING TO
}
})
}
// in app.js:
app.put('/accounts/:id', (req, res, next) => {
const id = req.params.id
const updatedAccount = req.body
//errors and validation
//type of input
if(typeof(updatedAccount.username) !== 'string' && typeof(updatedAccount.password) !== 'string') {
res.status(422).json({
message: 'Unprocessable Entry'
}).end()
return
}
//does the account exist?
db.getAccountById(id, (errors, oldAccount) => {
if(errors.length > 0) {
res.status(500).json({
message: 'Internal Server Error'
}).end()
return
} else if (!oldAccount) {
res.status(404).end()
return
}
})
//validation:
const validationErrors = []
if(updatedAccount.username.length < USERNAME_MIN_LENGTH) {
validationErrors.push('Username too short')
} else if (updatedAccount.username.length > USERNAME_MAX_LENGTH) {
validationErrors.push('Username too long')
}
if(updatedAccount.password.length < PASSWORD_MIN_LENGTH) {
validationErrors.push('Password too short')
} else if (updatedAccount.password.length > PASSWORD_MAX_LENGTH) {
validationErrors.push('Password too long')
}
if(validationErrors.length > 0) {
res.status(400).json(validationErrors).end()
return
}
db.updateAccountById(updatedAccount, (errors, userId) => {
if(errors.length == 0) {
res.setHeader('Location', '/accounts/' + userId)
res.status(201).end()
} else if (errors.includes('usernameTaken')) {
res.status(400).json(errors).end()
} else {
res.status(500).end()
}
})
})

Cannot read property 'metadata' of null Nodejs

This is my error:
TypeError: Cannot read property 'metadata' of null
at gfs.files.findOne (M:\FinalProject\Commerce\routes\index.js:187:13)
at result (M:\FinalProject\Commerce\node_modules\mongodb\lib\utils.js:414:17)
This is my code :
router.get('/:filename', (req,res) => {
const img = req.params.filename; // Filename
gfs.files.findOne({filename: img}, (req,file) =>{
if(file.metadata.brand=="Mango"){
const brand = "Mango";
displayOne(brand);
}
else if(file.metadata.brand=="Cocotail")
{
const brand = "Cocotail";
displayOne(brand);
}
else if(file.metadata.brand==null)
{
console.log("Null");
}
function displayOne(brand)
{
gfs.files.find({'metadata.brand': brand }).toArray((err,files)=>{
if(!file || file.length ===0)
{
return res.status(404).json({
err: 'No files exist'
});
}
if(file.contentType === 'image/jpeg' || file.contentType === 'image/png')
{
file.isImage = true;
}
else
{
res.status(404).json({
err: 'Not an image'
});
file.isImage = false;
}
res.render('singleproduct',{
file:file,
relatedProduct:files, // Related Products
isSearch:0
});
});
}
});
});
Please give me any ideas about this error. i couldn't find out what is the major reason for this error. I searched on google but there are no appropriate solutions for that.____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Thank you
Did you console what you get just above
(file.metadata.brand=="Mango")
in file? seems you don't get any data from
gfs.files.findOne({filename: img}
try this:
if(file && file.metadata.brand=="Mango"){
const brand = "Mango";
displayOne(brand);
}
else if(file && file.metadata.brand=="Cocotail")
{
const brand = "Cocotail";
displayOne(brand);
}
else if(file && file.metadata.brand==null)
{
console.log("Null");
}
else{
console.log("didinot find value")
}

custom validation query always fires - express validator

I am trying to implement validation using express validator that should only kick in if the field actually has some input. If it is empty it should just be ignored. The first part of the validation if the field is to check to check it meets the regex requirements and the second check is to see if the value exists in the database. Lower case versions of the same username with capital letters are not allowed ie: Shirley and shirley are seen as the same thing.
body('username')
.trim()
.custom((value, { req }) => {
var regex = /^[a-zA-Z0-9]{5,20}$/;
if (value != '' && !value.match(regex)) {
throw new Error('Username does not meet required criteria.');
}
return true;
})
.custom((value, { req }) => {
if (value !== '') {
return User.findOne({ username: new RegExp(`^${value}$`, 'i') })
.then(userDoc => {
if (userDoc) {
return Promise.reject('Username unavailable');
}
return true;
});
}
}),
If I leave the username field empty I still get a validation error telling me 'username unavailable'
Managed to get it working like this
.custom(value => {
if (value !== '') {
return User.findOne({ username: new RegExp(`^${value}$`, 'i') })
.then(userDoc => {
if (userDoc) {
return Promise.reject('Username not available');
} else {
return true;
}
})
} else {
return true;
}
})

Resources