ReferenceError: name is not defined - node.js

I have a code in Controller
const getLocalDatabaseResule = async (searchURL, reqBody) => {
commonCode(reqBody);
console.log(name);
});
function commonCode(reqBody) {
var name = reqBody.name;
var phone= reqBody.phone;
var email = reqBody.email;
}
Any idea how to add common function in controller

You need to return the body from commonCode
const getLocalDatabaseResule = async (searchURL, reqBody) => {
const {name,phone,email} = commonCode(reqBody);
console.log(name);
};
function commonCode(reqBody) {
const name = reqBody.name;
const phone= reqBody.phone;
const email = reqBody.email;
return {name,phone,email}
}
getLocalDatabaseResule("searchURL", {name:"User",phone:"111", email:"mail#mail.com"})

Also this is possible
const getLocalDatabaseResule = async (searchURL, reqBody) => {
var x = commonCode(reqBody);
console.log(x.name);
});
function commonCode(reqBody) {
this.name = reqBody.name;
this.phone= reqBody.phone;
this.email = reqBody.email;
}

Related

MongoError: Document must be a valid JavaScript object

I have a problem where MongoDB says that my object is not a valid JavaScript Object, Even though it is! This has been staying for days!
Basically, this is an account system that uses MongoDB's client, and the ObjectId for the ID.
I want to be able to fix the MongoError that says object (sent to updateOne, not filter) is not a valid JavaScript object.
Here is the code:
const { MongoClient, ObjectId } = require("mongodb");
const fs = require("node:fs");
const uri = "mongodb://127.0.0.1:27017";
if (!fs.existsSync("./db")) {fs.mkdirSync("./db")};
const client = new MongoClient(uri,{ useUnifiedTopology: true });
async function conn() {
await client.connect();
}
conn();
const database = client.db("login");
const accs = database.collection("accounts");
const myfil = {
_id: new ObjectId('63b6441832087ccc7e3edea2')
};
const users = accs.findOne(myfil);
const path = require("node:path");
const bcrypt = require('bcrypt');
const env = process.env;
var saltRounds = 10;
const AddSet = class AddSet {
constructor(user,pass) {
console.log(pass);
this.set = {[user]:pass};
this.set = Object.keys(this.set).reduce((acc, key) => {
acc[key.toString()] = this.set[key];
return acc;
}, {});
console.log(this.set);
return this.set;
}
}
const Account = class Account {
constructor(user,password) {
conn();
if (!users[user]) {
conn();
accs.updateOne(myfil,bcrypt.hash(password, saltRounds, function(err, hash)
{
try {
var a = ""+user;
return new AddSet(a.toString(),hash);
} catch(err) {
console.error("bcrypt",err);
}
}));
this.assetDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/assets");
this.metaDir = this.assetDir + '/meta';
this.starterDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/starters");
this.videoDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/videos");
var fs = require('fs');
if (!fs.existsSync(this.assetDir)) fs.mkdirSync(this.assetDir, { recursive: true });
if (!fs.existsSync(this.starterDir)) fs.mkdirSync(this.assetDir, { recursive: true });
if (!fs.existsSync(this.videoDir)) fs.mkdirSync(this.assetDir, { recursive: true });
}
}
getAssetDir() {
return this.assetDir;
}
getStarterDir() {
return this.starterDir;
}
getVideoDir() {
return this.videoDir;
}
getMetaDir() {
return this.metaDir;
}
checkSession(pswd) {
conn();
bcrypt.compare(pswd, users[this.user], function(err, result) {
if (result) return true;
else return false;
});
}
}
module.exports = { Account, users };
I tried fixing it, making the keys strings, removing the $set, and it did not work.

How to return data in an async function in node.js? My code return [object Promise] but I want the response.length

I want the array length, but the function returns [object Promise]. I send a correct email and I just need know if it's already in collection.
const res = require('express/lib/response');
async function emailUnique(email){
var query = { email: email };
const response = await dbo.collection('users').find(query).toArray();
const tot = response.length;
return tot;
}
const emailValidate = function (email) {
if (email.indexOf('#') === -1 || email.indexOf('.') < 0) {
message = 'Invalid entries. Try again.';
}else{
let quantos = emailUnique(email);
message = quantos;
}
return message;
};
module.exports = emailValidate;
Thanks, Its a simplified answer:
emailValidate.mod.js
const res = require('express/lib/response');
function emailValidate(email) {
return new Promise((resolve) => { // return a promise
var query = { email: email };
dbo.collection('users').find(query).toArray((_err, result) => {
resolve(result.length); //the returned value
});
});
}
module.exports = emailValidate;
user.js
const mod_emailValidate = require('./emailValidate.mod');
exports.getUsers = (req, res) => {
const { name } = req.body;
const { email } = req.body;
const { password } = req.body;
async function run() { // make an async function
let data = await mod_emailValidate(email); //call the function with await
console.log(`Retornou: ${data}`);
}
run();
res.status(400).send({ message: 'Fired' });
};

how to clear global var between tests in nodejs?

I have 2 tests which each one them pass but when i run them together the second test fails.
I have this global var (CURR_GUID) which i want to clear between the tests but i am not sure how to do that.
Since it is not cleared between the tests , its value is still "1111111" and not null.
Any idea?
Class W
"use strict";
var CURR_GUID = null;
class W {
constructor() {
console.log("W ctor")
}
async getDataFromDb() {
if (CURR_GUID) {
return CURR_GUID;
} else {
this.db = require("./Connection").getDb();
console.log("W getDataFromDb")
let res = null;
res = await this.db.one("SELECT guid FROM table", ["NONE"]);
return res.guid;
}
}
async saveGuid(guid) {
this.db = require("./Connection").getDb();
await this.db.none("update table set guid=$1", [guid]);
CURR_GUID = guid;
console.log("currr is" + CURR_GUID);
}
}
module.exports = W;
Class X
"use strict";
const wDao = new (require("../db/W"))();
class X {
async getGuid() {
console.log("X getGuid")
let guid = await wDao.getDataFromDb();
console.log("got guid " + guid);
await wDao.saveGuid(guid);
return guid;
}
}
module.exports = X;
Test.spec.js
const chai = require("chai");
const expect = chai.expect;
const X = require("../src/service/X");
const Connection = require("../src/db/Connection");
const sinon = require("sinon");
describe("component_test", function () {
afterEach(function () {
this.dbStub.restore();
});
it("X_component_test", async function () {
var db = {
one: async () => {
return {
guid: '1111111',
created_on: "123"
}
},
none: async () => {
}
};
this.dbStub = sinon.stub(Connection, "getDb").returns(db);
var dao = new X();
var guid = await dao.getGuid();
expect(guid).to.equal('1111111');
});
it("X_component_test_2", async function () {
var db = {
one: async () => {
return {
guid: '222222',
created_on: "123"
}
},
none: async () => {
}
};
this.dbStub = sinon.stub(Connection, "getDb").returns(db);
var dao = new X();
var guid = await dao.getGuid();
expect(guid).to.equal('222222');
});
});
While it should be possible to achieve the desired result by deleting W and X modules from require.cache in afterEach hook, it might be better to modify the source code a bit so that it can be tested without cache manipulations.
Class W
Turn CURR_GUID variable into an instance property.
"use strict";
class W {
constructor() {
console.log("W ctor");
this.CURR_GUID = null;
}
async getDataFromDb() {
if (this.CURR_GUID) {
return this.CURR_GUID;
} else {
this.db = require("./Connection").getDb();
console.log("W getDataFromDb")
let res = null;
res = await this.db.one("SELECT guid FROM table", ["NONE"]);
return res.guid;
}
}
async saveGuid(guid) {
this.db = require("./Connection").getDb();
await this.db.none("update table set guid=$1", [guid]);
this.CURR_GUID = guid;
console.log("currr is" + this.CURR_GUID);
}
}
module.exports = W;
Class X
Turn wDao from variable into an instance property
"use strict";
const WDao = require("../db/W");
class X {
constructor() {
this.wDao = new WDao();
}
async getGuid() {
console.log("X getGuid")
let guid = await this.wDao.getDataFromDb();
console.log("got guid " + guid);
await this.wDao.saveGuid(guid);
return guid;
}
}
module.exports = X;
In this way every test should work with fresh instances of W and X that do not depend on the closure state.

Getting document not a function

I am attempting to retrieve the boolean child (notificationsOn) of an object stored as a Firestore document to see if the rest of a function should be executed.
The overall function works to completion without this portion, but adding the portion from let threadDoc to the if statement presents a "threadDoc.get is not a function" error. I think my syntax is wrong but I don't know how, as a similar function works in a later part of the function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendDMNotification =functions.firestore.document('/dm_threads/{thread_id}/messages/{message_id}').onCreate((snapshot, context) => {
const newMessage = snapshot.data();
const senderName = newMessage.authorName;
const senderID = newMessage.authorUID;
const messageText = newMessage.message;
const recipientID = newMessage.recipientUID;
var notificationsOn = null;
let deviceTokenQuery = admin.firestore().collection(`/users/${recipientID}/device_tokens/`);
var idsToBeSorted = [senderID, recipientID];
idsToBeSorted.sort();
var threadID = idsToBeSorted[0] + idsToBeSorted[1];
console.log(recipientID);
console.log(threadID);
let threadDoc = admin.firestore().document(`users/${recipientID}/threads/${threadID}/`);
return threadDoc.get().then(doc => {
let notificationsOn = doc.data.notificationsOn;
console.log(notificationsOn);
if (notificationsOn !== false){
return deviceTokenQuery.get().then(querySnapshot => {
let tokenShapshot = querySnapshot.docs;
const notificationPromises = tokenShapshot.map(doc => {
let token_id = doc.data().tokenID;
const payload = {
data: {
title: senderName,
body: messageText,
senderID: senderID,
senderName: senderName
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
console.log("Notification sent: ", response);
})
.catch(error => {
console.log("Error sending message: ", error);
});
});
return Promise.all(notificationPromises);
});
}
return;
});
});
admin.firestore().document() was supposed to be admin.firestore().collection(...).doc(...)
This fixed my problem
I think you meant to say admin.firestore() instead of functions.firestore.

Why isn't sinon replacing the actual function call?

My function is:
const PhoneNumber = require('awesome-phonenumber');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const { twiml } = require('twilio');
exports.incoming = (requestBody) => {
const MessagingResponse = twiml.MessagingResponse;
const VoiceResponse = twiml.VoiceResponse;
const pn = new PhoneNumber(requestBody.Body, 'US');
return global.db.Conference.create({})
.then((dbCreate) => {
conferenceId = dbCreate.id;
// Call originator
return twilio.calls.create({
to: requestBody.From,
from: requestBody.To,
url: `${process.env.API_URL}/calls/conference?id=${conferenceId}`
});
})
My test is:
const _ = require('lodash');
const sinon = require('sinon');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const { twiml } = require('twilio');
const SmsController = require('../../../controllers/sms');
const twilioIncomingSmsReq = require('../../mocks/twilioIncomingSmsReq');
describe.only('Sms Controller', () => {
let messagingResponseMessageStub;
let conferenceCreateStub;
beforeEach(() => {
messagingResponseMessageStub = sinon.stub(twiml.MessagingResponse.prototype, 'message').returns(true);
conferenceCreateStub = sinon.stub(global.db.Conference, 'create').resolves({ id: 1 });
return;
});
afterEach(() => {
messagingResponseMessageStub.restore();
conferenceCreateStub.restore();
return;
});
it.only('should call the originator and recipient', () => {
let requestBody = _.clone(twilioIncomingSmsReq);
console.log(twilio.calls);
let twilioDialStub = sinon.stub(twilio.calls, 'create').resolves(true);
console.log(twilio.calls);
return SmsController.incoming(requestBody)
.then(() => {
sinon.assert.calledWith(twilioDialStub, {
to: requestBody.From,
from: requestBody.To,
url: `${process.env.API_URL}/calls?id=1`
});
sinon.assert.calledWith(twilioDialStub, {
to: '+number',
from: requestBody.From,
url: `${process.env.API_URL}/calls?id=1`
});
twilioDialStub.restore();
return;
});
});
});
But in my code, the actual twilion.calls.create function is called. Not the stub. What am I doing wrong?
twilio refer to different objects in these modules. require('twilio') is factory function. It's expected to create a new object even when it's called with same arguments, require('twilio')(...) !== require('twilio')(...).
Consider exporting twilio instance, at least for testing purposes:
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID,
...
exports.twilio = twilio;

Resources