Node js TypeError: Cannot read property 'nick' of undefined - sql

The Issiue
Issue is basically if i try to combine query+variable or put it in "fake pdo" style, it does not work.
Code
if(page == "profile"){
var user = "Failed to load.";
con.query('SELECT * FROM users WHERE id = '+con.escape(parseInt(userIDRequested)), function (err, result, fields) {
//console.log(result);
user= result[0].nick;
io.emit('userinfo', { nick: user});
});
}
app.get("/user/:start", function(req, res){
page = "profile";
var user_id = req.params['start'];
pageid = user_id;
if(didshitgetupdated == false){
useridRequested = pageid;
didshitgetupdated = true;
}
res.writeHeader(200, {"Content-Type": "text/html"});
let btlib = btNetLib(res);
btlib.btSend(navbar);
btlib.btSendFile("profile/index.html");
finishConnection(res);
})
but for some reason i get this:
TypeError: Cannot read property 'nick' of undefined
at Query.<anonymous> (D:\bricktalenode\bricktale.js:36:29)
at Query.<anonymous> (D:\bricktalenode\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (D:\bricktalenode\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (D:\bricktalenode\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (D:\bricktalenode\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
at Query.EofPacket (D:\bricktalenode\node_modules\mysql\lib\protocol\sequences\Query.js:133:8)
at Protocol._parsePacket (D:\bricktalenode\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (D:\bricktalenode\node_modules\mysql\lib\protocol\Parser.js:433:10)
at Parser.write (D:\bricktalenode\node_modules\mysql\lib\protocol\Parser.js:43:10)
at Protocol.write (D:\bricktalenode\node_modules\mysql\lib\protocol\Protocol.js:38:16)
Things i tried
making a if condition to check it
(did not helped)
connecting database using another thing
i used same query(changed variable for php though) in php to access, query is ok, so issue on my node.js code then.
waiting for some time ( did not helped)
parse int
nothing really helped that i done
but for some reason i get stuff correctly using console.log(result);
but i cant fetch them using the code.
The results
[ RowDataPacket {
nick: '[MODERATED 5]',
id: 5,
password: 'fdaf40dc5531c0acf82911892f552f0a',
banned: 0,
coins: 0,
registerdate: 2021-05-10T02:55:45.000Z,
status: 'BETA STATUS',
rank: 'Player',
rep: 1,
token: 'token',
lastonline: '2021-05-10 03:05:08',
lastdaily: 2021-05-19T07:04:34.000Z } ]
but i cannot access it

app.get("/user", function(req, res){
page = "profile";
res.writeHeader(200, {"Content-Type": "text/html"});
let btlib = btNetLib(res);
btlib.btSend(navbar);
btlib.btSendFile("profile/index.html");
var sql = 'SELECT * FROM users WHERE id = ?';
con.query(sql, req.query.id, function (err, result) {
if (err) throw err;
setInterval(() => {
var bricklet;
bricklet = result[0].nick;
console.log(bricklet);
io.emit('userinfo', { nick: bricklet});
},150);
});
finishConnection(res);
})
moving stuff inside of my app.get solved it.

Related

How can I refresh datatable in Wire using refreshApex

#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({error,data}){
this.dataToRefresh = data;
if (data) {
this.contacts = this.dataToRefresh.recordList;
this.ContactsRecords = this.dataToRefresh.cList;
this.contactsSize = " Case Contacts (" + this.contacts.length + ")";
}else{
//
}
};
relateContacts() {
this.showSpinner = true;
this.showtable=false;
relateContacts({contacts: this.selected, recordId: this.recordId})
.then(data => {
this.showSpinner=false;
this.showtable=true;
this.showSuccessMessage();
refreshApex(this.dataToRefresh);
//location.reload();
this.isShowModal = false;
})
.catch(error => {
console.log(error);
this.showSpinner=false;
const evt = new ShowToastEvent({
title: 'Application Error',
message: error.body.message,
variant: 'error',
mode: 'sticky'
});
this.dispatchEvent(evt);
this.showSpinner = false;
});
}
For this code, I tried refreshApex with all possible ways. but I'm not sure the miss here. I've Checked all the blogs but everywhere, the solution is mentioned.
Tried refreshApex like below :
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts({data}){
this.dataToRefresh = data;
But this also does not work
Ah that is a fun one ! Your issue is using destructuring in wiredContacts as the parameter.
(The {data} or {data,error} normally works as a parameter to the function being called back, except if you have to do refresh) Try this instead.
#wire(_getContacts,{recordId:'$recordId'}) wiredContacts(value){
this.dataToRefresh = value;
const {data, error} = value;
//Rest of you code now with data and error
}
Then in your other method you can do:
method(){
refreshApex(this.dataToRefresh);
}
Salesforce does show doing this in their example code, but it’s easy to miss and experience the fun you have been having with this.
https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.apex_result_caching
See the last example on their page.

Express - get request - How inject data in my response along the process?

I'm trying to add data to my "data" returned in express. Here my snippet, I'm trying to add currentPage and count variables:
app.get("/blog/page/:pageTargeted", (req,res) => {
var rangeScoped = (req.params.pageTargeted * 8);
Posts.find().sort({ date: -1}).skip(rangeScoped).limit(8).exec(function (err, data) {
data.currentPage= req.params.pageTargeted || 1 ;
data.count = Posts.estimatedDocumentCount();
if (err) return console.error(err);
console.log(data);
res.status(200).send(data)
})
});
I have also tried:
currentPage= req.params.pageTargeted || 1 ;
count = Posts.estimatedDocumentCount();
if (err) return console.error(err);
console.log(data);
res.status(200).send(data currentPage, count)
It doesn't works, currentPage and count aren't add in the res.send toward the browser. I have just the data corresponding to the database get's request. So what it going wrong ? I just can't figure out it. Because to me I have well injected the data into the object so, it should works. If anybody has an hint, would be great.
If I am right data is an array and you can't create a new key in array like that. Try sending an Object instead.
app.get("/blog/page/:pageTargeted", (req,res) => {
var rangeScoped = (req.params.pageTargeted * 8);
Posts.find().sort({ date: -1}).skip(rangeScoped).limit(8).exec(function (err, data) {
if (err) return console.error(err);
console.log(data);
res.status(200).json({data: data, currentPage: req.params.pageTargeted || 1, count: Posts.estimatedDocumentCount()})
})
});

sinon stub is not working

I'm quiet new into testing and I don't seem to succeed to succesfully stub a function. I'm trying to stub the connection to the database, but it keep's contacting it, instead of using the result from the stub:
Here's the function:
var self = module.exports = {
VerifyAuthentication: function (data){
var deferred = q.defer()
if(typeof(data.email)=='undefined'){
deferred.reject({data:{},errorcode:"",errormessage:"param 'email' is mandatory in input object"})
}else{
if(typeof(data.password)=='undefined'){
deferred.reject({data:{},errorcode:"",errormessage:"param 'password' is mandatory in input object"})
}else{
var SqlString = "select id, mail, password, origin from tbl_user where mail = ?"
var param = [data.email]
self.ExecuteSingleQuery(SqlString, param).then(function(results){
if(results.length > 0)
{
if (results[0].password == data.password)
{
deferred.resolve({data:{"sessionId":results[0].id},errorcode:"",errormessage:""})
}else{
deferred.reject({data:{},errorcode:"",errormessage:"bad password"})
}
}else{
deferred.reject({data:{},errorcode:"",errormessage:"unknown user"})
}
})
}
}
return deferred.promise
},
ExecuteSingleQuery: function (queryString, parameters){
var deferred = q.defer()
var connection = connect()
connection.query(queryString, parameters, function (error, results, fields){
if(error){ deferred.reject(error)};
deferred.resolve(results)
});
return deferred.promise
},
And here's the test:
var dbconnection = require('../lib/dbConnection.js')
describe("VerifyAuthentication", function(){
it("_Returns DbResult object when user name and password match", function(){
var expectedResult = {data:{"sessionKey":"b12ac0a5-967e-40f3-8c4d-aac0f98328b2"},errorcode:"",errormessage:""}
stub = sinon.stub(dbconnection, 'ExecuteSingleQuery').returns(Promise.resolve(expectedResult))
return dbconnection.VerifyAuthentication({email:"correct#adres.com",password:"gtffr"}).then((result)=>{
expect(result.data.sessionId).to.not.be.undefined
expect(result.errorcode).to.not.be.undefined
expect(result.errormessage).to.not.be.undefined
stub.restore()
})
})
})
I always got an error 'unknown user', which is normal, because the user is indeed not in the database. However, I want to stub the 'ExecuteSingleQuery' function, avoiding it to connect to DB.
I have fixed a couple of issues in your code and posting the corrected files below.
dbConnection.js
var self = module.exports = {
VerifyAuthentication: function (data) {
var deferred = q.defer();
if (typeof (data.email) == 'undefined') {
deferred.reject({
data: {},
errorcode: '',
errormessage: "param 'email' is mandatory in input object"
});
} else {
if (typeof (data.password) == 'undefined') {
deferred.reject({
data: {},
errorcode: '',
errormessage: "param 'password' is mandatory in input object"
});
} else {
var SqlString = 'select id, mail, password, origin from tbl_user where mail = ?';
var param = [data.email];
self.ExecuteSingleQuery(SqlString, param).then(function (results) {
if (results.length > 0) {
if (results[0].password === data.password) {
deferred.resolve({
data: {
'sessionId': results[0].id
},
errorcode: '',
errormessage: ''
});
} else {
deferred.reject({
data: {},
errorcode: '',
errormessage: 'bad password'
});
}
} else {
deferred.reject({
data: {},
errorcode: '',
errormessage: 'unknown user'
});
}
});
}
}
return deferred.promise;
},
ExecuteSingleQuery: function (queryString, parameters) {
var deferred = q.defer();
var connection = connect();
connection.query(queryString, parameters, function (error, results, fields) {
if (error) {
deferred.reject(error);
}
deferred.resolve(results);
});
return deferred.promise;
}
};
dbConnection.test.js
describe('VerifyAuthentication', function () {
it('Returns DbResult object when user name and password match', function () {
var expectedResult = [{
id: '123',
password: 'gtffr'
}];
const stub = sinon.stub(dbconnection, 'ExecuteSingleQuery').resolves(expectedResult);
return dbconnection.VerifyAuthentication({
email: 'correct#adres.com',
password: 'gtffr'
}).then((result) => {
expect(result.data.sessionId).to.not.be.undefined;
expect(result.errorcode).to.not.be.undefined;
expect(result.errormessage).to.not.be.undefined;
stub.restore();
});
});
});
I am outlining the problematic parts below:
The expectedResult variable had a wrong type of value. In the
self.ExecuteSingleQuery() implementation you check for an array with length > 0. The fixed result returned by the stub, was an object instead of an array and this is why it returned the unknown user exception
The array should contain an object with { id: 'xxx', password: 'gtffr' } attributes. Password is validated against the one used by the dbconnection.VerifyAuthentication({email:"correct#adres.com",password:"gtffr"}) call
Finally, I have changed the stub statement to resolve instead of return as shown here const stub = sinon.stub(dbconnection, 'ExecuteSingleQuery').resolves(expectedResult); - this is the preferred method of resolving a promise

Running a stored procedure with NodeJS and MSSQL package error

Im trying to get the MSSQL nodejs package to return the results of a stored procedure from Microsoft SQL server using the code below. However the error I get is...
[TypeError: Cannot read property 'type' of undefined]
I'm not sure I have done the inputs correctly as I couldn't find an example with more than one input anywhere online.
Any ideas?
exports.executeSqlStoredProd = function (callback) {
var conn = new sqlDb.Connection(settings.dbConfig)
conn.connect().then(function () {
var req = new sqlDb.Request(conn);
req.input('ProductEntryID', req.Int, 3299);
req.input('LoginEntryID', req.Int, 4);
req.input('TempLoginEntryId', req.Int, -1);
req.input('AddToWishList', req.Bit, 0);
req.input('WebPortalId', req.Int, 0);
req.execute('J_ViewAProduct').then(function(err, recordsets) {
console.log(recordsets);
callback(recordsets)
})}).catch(function(err){
console.log(err);
callback(null, err);
});
}
I did the request sucessfully using the package "Seriate" but would prefer to use mssql. The code that worked for "Seriate" is below.
exports.getVAP = function(req, resp, pid) {
sql.execute({
procedure: "J_ViewAProduct",
params: {
ProductEntryID: {
type: sql.INT,
val: pid
},
LoginEntryID: {
type: sql.Int,
val: 4
},
TempLoginEntryId: {
type: sql.Int,
val: -1
},
AddToWishList: {
type: sql.Bit,
val: 0
},
WebPortalId: {
type: sql.Int,
val: 0
}
}
}).then(function(results){
console.log(results)
httpMsgs.sendJSON(req, resp, results)
//httpMsgs.sendJSON(req, resp, results[0])
resp.end();
}), function(err){
httpMsgs.show500(req, resp, err)
}
};
I think the line's
req.input('ProductEntryID', req.Int, 3299);
req.input('LoginEntryID', req.Int, 4);
req.input('TempLoginEntryId', req.Int, -1);
req.input('AddToWishList', req.Bit, 0);
req.input('WebPortalId', req.Int, 0);
which has req.input thats wrong it seems.
Please try this code
var sql = require('mssql');
var config = {
user: 'sa',
password: '---',
server: 'localhost', // You can use 'localhost\\instance' to connect to named instance
database: 'Test'
}
var getCities = function() {
var conn = new sql.Connection(config);
conn.connect().then(function(conn) {
var request = new sql.Request(conn);
request.input('City', sql.VarChar(30), 'Cbe');
request.input('NameNew', sql.VarChar(30), 'Cbe');
request.execute('spTest').then(function(err, recordsets, returnValue, affected) {
console.dir(recordsets);
console.dir(err);
}).catch(function(err) {
console.log(err);
});
});
}
getCities();
I tried this myself and its giving the results.
I don't know if this would be helpful or not but this is how I did
let executeQuery = async (value, country) => {
try {
let pool = await sql.connect(dbConfig);
let results = await pool.request()
.input('input_parameter', sql.Int, value)
.input('Country', sql.VarChar(50), country)
// .output('output_parameter', sql.VarChar(50))
.execute('procedure_name')
console.dir(results);
} catch (err) {
res.json({
"error": true,
"message": "Error executing query"
})
}
}
executeQuery(value, country);
I've used async and await method to make it more readable.

Angular http testing

I have a fairly simple controller that gets a simple json list of objects ...
function ProductGroupsCtrl($scope, $http, $routeParams, sharedService, popupService) {
$scope.list = null;
$scope.selectedItem = null;
$scope.selectedItemJsonString = '';
$scope.selectItem = function (item) {
$scope.selectedItem = item;
$scope.selectedItemJsonString = JSON.stringify(item);
//alert(JSON.stringify(item));
};
$scope.closePopup = function () {
$scope.selectedItem = null;
$scope.selectedItemJsonString = '';
};
// sharedService.prepForBroadcast($routeParams.anotherVar);
$http({
method: 'GET',
url: '/ProductGroup'
}).success(function (data) {
$scope.list = data;
}).
error(function (data) {
$scope.message = 'There was an error with the data request.';
});
}
I then try to mock the request in the test class:
var scope, ctrl, $httpBackend, sharedServiceMock = {}, popupServiceMock = {};
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
$httsypBackend.expectGET('/ProductGroup').
respond([{
ProductGroupID: 5,
MenuTitle: "Promotional Products",
AlternativeText: "Coming soon - a collection of environmentally friendly Promotional Products",
OrdinalPosition: 5,
Active: false
}]);
scope = $rootScope.$new();
ctrl = $controller(ProductGroupsCtrl, {
$scope: scope,
$http: $httpBackend,
sharedService: sharedServiceMock,
popupService: popupServiceMock
});}));
However I receive an error in the testacular window object undefined. What have I done wrong here?
Found the answer. If I remove the error callback function from the $http.get method then it works, i.e. remove the following ...
error(function (data) {
$scope.message = 'There was an error with the data request.';
}
I have to say Angular sure is a steep learning curve for someone who is not a day to day JavaScript programmer (although I seem to be doing more and more). Thanks for the help anyway KatieK :-)