connection.queryRaw is not a function error in NodeJs WebAPI call - node.js

I am new to Nodejs. I am developing WebAPI by using NodeJs and MSSQl as database.My api is giving proper response in case of POST endpoint If it is called while server is listening through Dev environment command [npm run start]. But, If I Deploy my API on Windows IIS , it is giving the mentioned error. My reference API endpoint code is as below :
router.post('/',async (req,res,next)=>{
// console.log('Enter products creation')
const Product = Array.from(req.body) // req.body
// console.log('New Product details passed on',Product)
const createProd = require('../CreateProduct')
const response = await createProd(Product)
res.status(404).json({
message : response.retStatus
})
})
CreateProduct function called in above code is as below :
const sql = require("mssql/msnodesqlv8");
const dataAccess = require("../DataAccess");
const fn_CreateProd = async function (product) {
let errmsg = "";
let objBlankTableStru = {};
let connPool = null;
// console.log('Going to connect with Connstr:',global.config)
await sql
.connect(global.config)
.then((pool) => {
global.connPool = pool;
productsStru = pool.request().query("DECLARE #tblProds tvp_products select * from #tblProds");
return productsStru;
})
.then(productsStru=>{
objBlankTableStru.products = productsStru
productsOhStru = global.connPool.request().query("DECLARE #tblprodsOh tvp_product_oh select * from #tblprodsOh");
return productsOhStru
})
.then((productsOhStru) => {
objBlankTableStru.products_oh = productsOhStru
let objTvpArr = [
{
uploadTableStru: objBlankTableStru,
},
{
tableName : "products",
tvpName: "tvp_products",
tvpPara: "tblProds"
},
{
tableName : "products_oh",
tvpName: "tvp_product_oh",
tvpPara: "tblProdsOh",
}
];
newResult = dataAccess.getPostResult(
objTvpArr,
"sp3s_ins_products_tvp",
product
);
console.log("New Result of Execute Final procedure", newResult);
return newResult;
})
.then((result) => {
// console.log("Result of proc", result);
if (!result.recordset[0].errmsg)
errmsg = "New Products Inserted successfully";
else errmsg = result.recordset[0].errmsg;
})
.catch((err) => {
console.log("Enter catch of Posting prod", err.message);
errmsg = err.message;
if (errmsg == "") {
errmsg = "Unknown error from Server... ";
}
})
.finally((resp) => {
sql.close();
});
return { retStatus: errmsg };
};
module.exports = fn_CreateProd;
GetPost() function is as below :
const getPostResult = (
tvpNamesArr,
procName,
sourceData,
sourceDataFormat,
singleTableData
) => {
let arrtvpNamesPara = [];
let prdTable = null;
let newSrcData = [];
// console.log("Source Data :", sourceData);
let uploadTable = tvpNamesArr[0];
for (i = 1; i <= tvpNamesArr.length - 1; i++) {
let tvpName = tvpNamesArr[i].tvpName;
let tvpNamePara = tvpNamesArr[i].tvpPara;
let TableName = tvpNamesArr[i].tableName;
let srcTable = uploadTable.uploadTableStru[TableName];
srcTable = srcTable.recordset.toTable(tvpName);
let newsrcTable = Array.from(srcTable.columns);
newsrcTable = newsrcTable.map((i) => {
i.name = i.name.toUpperCase();
return i;
});
if (!singleTableData) {
switch (sourceDataFormat) {
case 1:
newSrcData = sourceData.filter((obj) => {
return obj.tablename.toUpperCase() === TableName.toUpperCase();
});
break;
case 2:
newSrcData = getObjectDatabyKey(sourceData, TableName);
break;
default:
newSrcData = getTableDatabyKey(sourceData, TableName);
break;
}
} else {
newSrcData = sourceData;
}
// console.log(`Filtered Source data for Table:${TableName}`, newSrcData);
prdTable = generateTable(
newsrcTable,
newSrcData,
tvpName,
sourceDataFormat
);
arrtvpNamesPara.push({ name: tvpNamePara, value: prdTable });
}
const newResult = execute(procName, arrtvpNamesPara);
return newResult;
};

Finally, I have found the solution to this.. it is very strange and shocking and surprising that If I using Morgan Middleware in app.js and have used it by syntax : app.use(morgan('dev')) , then it is the culprit command..I just removed dev from this command after which problem got resolved..But I found no help regarding this issue over Google anywhere..I really fear that what type of challenges I am going to face in future development if these kind of silly error come without giving any hint..I would be highly obliged If anyone could make me understand this kind of silly errors..

Related

Why latest updated sha is coming when using github api in switch case

I am doing file update operations using GitHub API. For example, let's say I am having a file called App.js and i am updating first line. While updating I will pass the sha.
When i am trying to update another line in the same file, the new updated sha is not coming, the older sha is coming. I am not doing all these steps manually, I have written code for all these operations. Let me paste the code for understanding,
var cosmos = [
{
"_id":"63773144c3160f782c087e35",
"nfrid":"637328ebf5c4b2558b064809",
"nfrname":"azuread",
"fileName":"index.js",
"isImport":true,
"isConst":false,
"isComponent":false,
"isNewFile":false,
"isPackage":false,
"landmark":null,
"isAfter":null,
"fileContent":"import { MsalProvider } from '#azure/msal-react';import { msalConfig } from './authConfig';import {PublicClientApplication } from '#azure/msal-browser';",
"filePath":"src/index.js",
"isIndexHtml":false,
"projecttypeid":"6372366d1b568e00d8af2e44",
"projecttypetitle":"PWA React",
"isReplace":false
},
{
"_id":"637731a2c3160f782c087e37",
"nfrid":"637328ebf5c4b2558b064809",
"nfrname":"azuread",
"fileName":"index.js",
"isImport":false,
"isConst":false,
"isComponent":true,
"isNewFile":false,
"isPackage":false,
"landmark":"<App />",
"isAfter":null,
"fileContent":"<MsalProvider instance={msalInstance}><App /></MsalProvider>",
"filePath":"src/index.js",
"isIndexHtml":false,
"projecttypeid":"6372366d1b568e00d8af2e44",
"projecttypetitle":"PWA React",
"isReplace":true,
}
];
for (let i = 0; i < cosmos.length; i++) {
switch (true) {
case cosmos[i].isImport:
const statusImport = common.updateImport(cosmos[i]);
console.log(statusImport);
break;
case cosmos[i].isConst:
const statusConst = common.updateConst(cosmos[i]);
console.log(statusConst);
break;
case cosmos[i].isPackage:
const statusPackage = common.updatePackage(cosmos[i]);
console.log(statusPackage);
break;
case cosmos[i].isIndexHtml:
const statusIndexHtml = common.updateIndexHTML(cosmos[i]);
console.log(statusIndexHtml);
break;
case cosmos[i].isNewFile:
const statusNewFile = common.addNewFile(cosmos[i]);
console.log(statusNewFile);
break;
case cosmos[i].isComponent:
const statusComponent = common.updateComponent(cosmos[i]);
console.log(statusComponent);
break;
default:
console.log("Nothing to add/update");
break;
}
}
I will be updating both these things in index.js file only. But the first thing is getting updated properly, when the second thing comes, it shows error like "src/index.js does not match with sha-id". I checked , that sha id is not the updated one, it changes after first update happens and i am getting that error . i will also paste my code logic which i wrote for updating files.
async function updateImport(cosmos) {
let temp = cosmos.filePath;
let newSha = "";
let newContent = "";
let decodedContent = "";
const octokit = new Octokit({
auth: "ghp_auth-token"
});
try {
return await new Promise(async (resolve, reject) => {
const response = await octokit.request(
`GET /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`
);
newSha = response.data.sha;
decodedContent = atob(response.data.content);
if (cosmos.isImport === true) {
newContent = cosmos.fileContent + decodedContent;
}
let encodedContent = Buffer.from(newContent).toString("base64");
const update = await octokit.request(
`PUT /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`,
{
message: "Updating import statements",
content: encodedContent,
sha: newSha
}
);
console.log(update.status);
resolve("success");
});
} catch (error) {
console.log(error);
}
}
async function updateComponent(cosmos) {
let temp = cosmos.filePath;
let newSha = "";
let newContent = "";
let decodedContent = "";
const octokit = new Octokit({
auth: "ghp_auth token"
});
try {
return await new Promise(async (resolve, reject) => {
const response = await octokit.request(
`GET /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`
);
newSha = response.data.sha;
decodedContent = atob(response.data.content);
if (cosmos.isComponent === true) {
if (cosmos.isAfter === false) {
newContent = decodedContent.replace(
cosmos.landmark,
cosmos.fileContent + cosmos.landmark
);
} else if(cosmos.isAfter === true) {
newContent = decodedContent.replace(
cosmos.landmark,
cosmos.landmark + cosmos.fileContent
);
}
else if (cosmos.isReplace === true) {
newContent = decodedContent.replace(
cosmos.landmark,
cosmos.fileContent
);
}
}
// var formattedContent = prettier.format(newContent,{ semi: false, parser: "mdx" });
let encodedMDContent = Buffer.from(newContent).toString("base64");
const update = await octokit.request(
`PUT /repos/JaspreetAhden24/TestingGitHubIO/contents/${temp}`,
{
message: "Updating components",
content: encodedMDContent,
sha: newSha
}
);
console.log(update.status);
resolve("success");
});
} catch (error) {
console.log(error);
}
}
i need to know why the latest updated sha id is not coming when the second update is happening.
I need to know if the problem is with switch case or the new updated sha will not come in the second update function.

Getting Error [Cannot read properties of undefined (reading 'generatetypeinfo')] in Node JS API post method

I am new to Restful API development using NodeJS and SQL Server. I am trying to do a simple [post] operation where I am passing an array of objects to the API endpoint and then calling a SQL Server procedure with a table valued parameter. I am getting the below error
Cannot read properties of undefined (reading 'generateTypeInfo')
I was really shocked to see that there is not a single help topic found over Google regarding this error. I do not want to learn ASP.NET Core for this because JavaScript has an easy learning curve. Am I doing a mistake by developing a Rest API by using the combination of NodeJS and SQL Server? Below is my Related .JS file called in Post endpoint
const sql = require("mssql/msnodesqlv8");
const dataAccess = require("../DataAccess");
const fn_CreateProd = async function (product) {
let errmsg = "";
let connPool = null;
await sql
.connect(global.config)
.then((pool) => {
global.connPool = pool;
result = pool.request().query("select * from products where 1=2");
return result;
})
.then((retResult) => {
const srcTable = retResult.recordset.toTable("tvp_products");
let newsrcTable = Array.from(srcTable.columns);
console.log('Source table b4 mapping',srcTable)
newsrcTable = newsrcTable.map((i) => {
i.name = i.name.toUpperCase();
return i;
});
console.log('Source table after convert array with mapping',newsrcTable)
const prdTable = dataAccess.generateTable(
newsrcTable,
product,
"tvp_products"
);
console.log("Prepared TVp data", prdTable);
const newResult = dataAccess.execute(`sp3s_ins_products_tvp`, [
{ name: "tblprods", value: prdTable },
]);
console.log("Result of Execute Final procedure", newResult);
return newResult;
})
.then(result => {
console.log("Result of proc", result);
if (!result.errmsg) errmsg = "Products Inserted successfully";
else errmsg = result.errmsg;
})
.catch((err) => {
console.log("Enter catch of Posting prod", err.message);
errmsg = err.message;
})
.finally((resp) => {
sql.close();
});
return { retStatus: errmsg };
};
module.exports = fn_CreateProd;
and Content of Generatetable function are as below :
const generateTable = (columns, entities,tvpName) => {
const table = new mssql.Table(tvpName);
// const testobj = {type : [sql.numeric],name : 'Sanjay'}
// console.log('Columns testobj',testobj.type)
columns.forEach(column => {
// console.log('COlumn data for COlumn :',column)
if (column && typeof column === 'object' && column.name && column.type) {
let colOptions = {}
if (column.type==mssql.Numeric)
{
colOptions.scale=column.scale
colOptions.precision=column.precision
}
else
if (column.type==mssql.VarChar || column.type==mssql.Char )
{
colOptions.length = column.length
}
// console.log (`Column name type for column :${column.name} -${colType}-Actual :${column['type']}`)
if (column.hasOwnProperty('options')) {
table.columns.add(column.name.toUpperCase(), colType,column.options);
} else {
table.columns.add(column.name.toUpperCase(),colOptions)
}
}
});
console.log('Generated table',table)
const newEntities = entities.map(obj=>keystoUppercase(obj))
// console.log('New entities after uppercase',newEntities)
newEntities.forEach(entity => {
table.rows.add(...columns.map(i =>
entity[i.name]));
});
return table;
};
I have found the solution now. Actually, if you can see the code of generateTable function, I was adding the columns into the table but not mentioning the data type of the columns due to which this error was coming. I have added one more property [type] in the [colOptions] object being passed to columns.add command in the function [Generatetable]. Thanks a lot anyway to you for quick replies by Dale. K.

Cannot use “undefined” as a Firestore value

I am trying to retrieve data from my Firestore database using node.js, I want to collect a field from one Firestore query and pass the value into another Firestore query but I keep getting this error in my logs, the first Firestore query successfully retrieves data, but my problem is passing a value to the second query
Error: Value for argument "value" is not a valid query constraint. Cannot use "undefined" as a Firestore value. If you want to ignore undefined values, enable `ignoreUndefinedProperties`. at Object.validateUserInput (/workspace/node_modules/#google-cloud/firestore/build/src/serializer.js:271:19) at validateQueryValue (/workspace/node_modules/#google-cloud/firestore/build/src/reference.js:2048:18) at CollectionReference.where (/workspace/node_modules/#google-cloud/firestore/build/src/reference.js:988:9) at step2 (/workspace/index.js:74:43) at /workspace/index.js:65:17 at QuerySnapshot.forEach (/workspace/node_modules/#google-cloud/firestore/build/src/reference.js:748:22) at updateBets (/workspace/index.js:60:22) at processTicksAndRejections (internal/process/task_queues.js:97:5)
here is my code
async function updateBets() {
var marketRef = db.collection('matches');
var snapshot = await marketRef.where('matchStatus', '==', 'FINISHED').get();
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
console.log('I found documents');
snapshot.forEach(doc => {
step2();
async function step2() {
var marketRef2 = db.collection('markets');
var snapshot2 = await marketRef2.where('marketId', '==', doc.data().matchId).get();
console.log(doc2.id, '=>', doc2.data());
snapshot2.forEach(doc2 => {
console.log(doc2.id, '=>', doc2.data());
if (doc2.data().marketTitleId == 'FULL_TIME_RESULT') {
var a = doc.data().homeTeamScore;
var b = doc.data().awayTeamScore;
var winnerIndex;
if (a > b) {
winnerIndex = 0;
var resultIndex = ['WINNER', 'LOSER', 'LOSER'];
var docName = `${doc.data().matchId}` + '000' + '1';
var sfRef = db.collection('markets').doc(docName);
batch5.update(sfRef, {
results: resultIndex
});
} else if (a == b) {
winnerIndex = 1;
var docName = `${doc.data().matchId}` + '000' + '1';
var resultIndex = ['LOSER', 'WINNER', 'LOSER'];
var sfRef = db.collection('markets').doc(docName);
batch5.update(sfRef, {
results: resultIndex
});
} else if (a < b) {
winnerIndex = 2;
var docName = `${doc.data().matchId}` + '000' + '1';
var resultIndex = ['LOSER', 'LOSER', 'WINNER'];
var sfRef = db.collection('markets').doc(docName);
batch5.update(sfRef, {
results: resultIndex
});
}
}
})
}
});
batch5.commit().then(() => {
console.log("im done with results");
}).catch((err) => {
console.log('Mac! there was an error with results: ', err);
});
}
You could try:
const data = doc.data();
const matchId = data.matchId;
and then put matchId into query.
Also log the "matchId" variable to see the value.

Complex query on more than one child in cloud functions

Here is the structure of my firebase database:
/UserData
/DeviceMgmt
/Counters
/NumberOfAll:
/NumberOfSelected
/TotalDownloaded
...
/Devices
/pushId1
/uid
/signOutTime
/toSelect=true (optional)
/downloaded
/lastDownload
/pushId2
/pushId3
...
And this is my cloud function:
exports.markDevicesForDownload = functions.database.ref('/UserData/DeviceMgmt/Counters/NumberOfSelected').onUpdate( (change) => {
const changeRef = change.after.ref;
const deviceMgmtRef = changeRef.parent.parent; // /UserData/DeviceMgmt
if (change.after.val() === 0 ) { //NumberOfSelected gets 0 value
return deviceMgmtRef.once('value')
.then((snap) => {
const devicesRef = snap.child('Devices').ref;
var average;
var numberOfAllDevices;
var totalDownloaded;
numberOfAllDevices = snap.child('Counters/NumberOfAll').val();
totalDownloaded = snap.child('Counters/TotalDownloaded').val();
average = Math.round(totalDownloaded/numberOfAllDevices);
return devicesRef
.orderByChild('signOutTime')
.equalTo(0)
.once('value',(devices) => {
return devices.ref
.orderByChild('downloaded')
.endAt(average)
.once('value',(devices) => {
devices.forEach((device) => {
device.child('toSelect').ref.set(true);
});
});
});
});
} else {
return false;
}
});
The function triggers when the counter NumberOfSelected = 0;
This happens when under any of device pushId there is no child toSelect. Then the query on downloaded child makes all devices with downloaded less than average set toSelect=true.
I wanted to limit the devices only to those which have signOutTime equal 0.
Somehow that query does not work and all devices are considered.
What I did wrong???
I would push all async tasks into a promise array and then return them all when all tasks complete:
exports.markDevicesForDownload = functions.database.ref('/UserData/DeviceMgmt/Counters/NumberOfSelected').onUpdate((change) => {
const changeRef = change.after.ref;
const deviceMgmtRef = changeRef.parent.parent; // /UserData/DeviceMgmt
if (change.after.val() === 0) { //NumberOfSelected gets 0 value
return deviceMgmtRef.once('value')
.then((snap) => {
const promises = [];
const devicesRef = snap.child('Devices').ref;
var average;
var numberOfAllDevices;
var totalDownloaded;
numberOfAllDevices = snap.child('Counters/NumberOfAll').val();
totalDownloaded = snap.child('Counters/TotalDownloaded').val();
average = Math.round(totalDownloaded / numberOfAllDevices);
const dR = devicesRef
.orderByChild('signOutTime')
.equalTo(0)
.once('value', (devices) => {
const dW = devices.ref
.orderByChild('downloaded')
.endAt(average)
.once('value', (devices) => {
devices.forEach((device) => {
if (device.child("signOutTime").val() === 0){
promises.push(device.child('toSelect').ref.set(true));
}
});
});
promises.push(dW);
});
promises.push(dR);
return Promise.all(promises);
});
} else {
return false;
}
});

SYSTEM_ERROR: system encountered unexpected error. Function killed. Cloud functions

When I looked through logs from Firebase cloud functions, I noticed that some functions have an error in logs with a description of "SYSTEM_ERROR: system encountered unexpected error. Function killed.", Until yesterday, this behavior was not, here is one of these functions. How can I fix it?
const functions = require('firebase-functions');
const admin = require('firebase-admin');
module.exports = functions.database.ref('/cards/{cardID}/interestedUsers').onWrite(event => {
const cardID = event.params.cardID;
console.log("interestedUsers", event.data.val(), cardID);
var currentInterestedUsers = [];
currentInterestedUsers = event.data.val();
var previousInterestedUsers = [];
previousInterestedUsers = event.data.previous.val();
if (event.data.previous.val() && currentInterestedUsers) {
var isNewPendingRequest = false;
if (currentInterestedUsers.length < previousInterestedUsers.length) {
currentInterestedUsers.forEach((interestedUser, index) => {
const interestedUserVal = interestedUser.val();
const isApproved = interestedUser["isApproved"];
console.log("result", interestedUser.val(), interestedUserVal);
if (isApproved == false) {
isNewPendingRequest = true;
}
});
}
if (isNewPendingRequest == false) {
const cardRef = admin.database().ref("cards").child(cardID);
const setupIsNewPendingRequestPromise = cardRef.update({
"isNewPendingRequest": false
});
return Promise.all([setupIsNewPendingRequestPromise]);
};
return console.log("interestedUsers deleting");
};
if (event.data.val() == null) {
console.log("event.data.val() == null");
const cardRef = admin.database().ref("cards").child(cardID);
// check card
const cardCheckPromise = cardRef.once("value", function(cardCheckPromiseSnap, error){
if (error) {
return console.log("cardCheckPromise", error);
};
if (cardCheckPromiseSnap.val()) {
const checkCardID = cardCheckPromiseSnap.val()["id"];
if (checkCardID) {
console.log("checkCardID", checkCardID);
const setupIsNewPendingRequestPromise = cardRef.update({
"isNewPendingRequest": false
});
return Promise.all([setupIsNewPendingRequestPromise]);
} else {
return console.log("checkCardID == null");
}
} else {
return console.log("cardCheckPromiseSnap.val() == null");
};
});
return Promise.all([cardCheckPromise]).catch(function(cardCheckPromiseError){
console.log("cardCheckPromise error", cardCheckPromiseError.message, cardCheckPromiseError.messageId)
});
}
return console.log("just update or adding a new interested user");
});
You can try re-deploying your app.
Likely a GCF outage. There was one today and yesterday. These errors were being thrown during the outage.
Solution
Take a break and wait for the cloud to heal. Contact GCP Support if you've purchased support.

Resources