Check if an user exist in my database with Node and MySQL [duplicate] - mysql

I need to check if entry with specific ID exists in the database using Sequelize in Node.js
function isIdUnique (id) {
db.Profile.count({ where: { id: id } })
.then(count => {
if (count != 0) {
return false;
}
return true;
});
}
I call this function in an if statement but the result is always undefined
if(isIdUnique(id)){...}

I don't prefer using count to check for record existence. Suppose you have similarity for hundred in million records why to count them all if you want just to get boolean value, true if exists false if not?
findOne will get the job done at the first value when there's matching.
const isIdUnique = id =>
db.Profile.findOne({ where: { id} })
.then(token => token !== null)
.then(isUnique => isUnique);

Update: see the answer which suggests using findOne() below. I personally prefer; this answer though describes an alternative approach.
You are not returning from the isIdUnique function:
function isIdUnique (id) {
return db.Profile.count({ where: { id: id } })
.then(count => {
if (count != 0) {
return false;
}
return true;
});
}
isIdUnique(id).then(isUnique => {
if (isUnique) {
// ...
}
});

You can count and find.
Project
.findAndCountAll({
where: {
title: {
[Op.like]: 'foo%'
}
},
offset: 10,
limit: 2
})
.then(result => {
console.log(result.count);
console.log(result.rows);
});
Doc link, v5 Beta Release

I found the answer by #alecxe to be unreliable in some instances, so I tweaked the logic:
function isIdUnique (id, done) {
db.Profile.count({ where: { id: id } })
.then(count => {
return (count > 0) ? true : false
});
}

As Sequelize is designed around promises anyway, alecxe's answer probably makes most sense, but for the sake of offering an alternative, you can also pass in a callback:
function isIdUnique (id, done) {
db.Profile.count({ where: { id: id } })
.then(count => {
done(count == 0);
});
}
}
isIdUnique(id, function(isUnique) {
if (isUnique) {
// stuff
}
});

Extending #Jalal's answer, if you're very conscious about performance implications while maintaining a simple Sequelize structure and you do not need the row data, I suggest you only request one column from the database. Why waste bandwidth and time asking the database to return all columns when you won't even use them?
const isIdUnique = id =>
db.Profile.findOne({ where: { id }, attributes: ['id'] })
.then(token => token !== null)
.then(isUnique => isUnique);
The attributes field tells Sequelize to only request the id column from the database and not sending the whole row's content.
Again this may seem a bit excessive but at scale and if you have many columns that hold a lot of data, this could make a giant difference in performance.

Try the below solution. I tried it and it works well.
const isIdUnique = async (id, model) => {
return await model.count({ where: { id: id } });
};
const checkExistId = await isIdUnique(idUser, User);
console.log("checkExistId: ", checkExistId);

Related

"Property 'then' does not exist on type 'void'." when using spinner.show().then()

From the docomuntation of ngx-Spinner said in FEAUTERS: "show()/hide() methods return promise",
but in my Project in intellij:
this.spinner.show() returns void.
ane therefore when im trying to do this:
onCheckOut() {
this.spinner.show().then(p => {
this.cartService.CheckoutFromCart(1);
});
}
im getting the : ERROR in src/app/components/checkout/checkout.component.ts:33:25 - error TS2339: Property 'then' does not exist on type 'void'.
33 this.spinner.show().then(p => {
how i make it work?
Maybe the documentation is wrong. When I look at the code, it does not return a promise:
show(name: string = PRIMARY_SPINNER, spinner?: Spinner) {
setTimeout(() => {
const showPromise = new Promise((resolve, _reject) => {
if (spinner && Object.keys(spinner).length) {
spinner['name'] = name;
this.spinnerObservable.next(new NgxSpinner({ ...spinner, show: true }));
resolve(true);
} else {
this.spinnerObservable.next(new NgxSpinner({ name, show: true }));
resolve(true);
}
});
return showPromise;
}, 10);
}
Not sure if this was done on purpose or not, but you could raise an issue on Github.
The only way to achieve your solution would be to use the getSpinner method of the service:
const spinnerName = "my-spinner";
this.spinner.show(spinnerName);
this.spinner.getSpinner(spinnerName)
.pipe(
first(({show}) => !!show)
)
.subscribe(() => {
this.cartService.CheckoutFromCart(1);
}
);

How to create a random number that unused in node.js and mysql

I try to create a random number with following code
let randomnumber = (Math.random().toString().slice(-8))
And I will check if the mysql table has this random number, if doesn't, this number will be inserted into the table, if do, run the above code again, and check again. like this
await mysqlModel.checkNumberExit([randomnumber])
.then(async(results) => {
if (results.length === 0) {
//doesn't exist, do something
} else {
//exist, repeat until the random number doesn't exist
}
Here is my question, how can I do this function efficiently, this way I am using is very low efficiency, any ideas?
You can use a function to generate and check:
function getRandomNumber() {
let randomnumber = Math.floor(Math.random(1000,9999)*100000000);
mysqlModel.find({"fieldName":randomnumber})
.then(res => {
if(!res) {
//doesn't exist, do something
}else{
getRandomNumber();
}
}).catch(err => {
//err
});
}
call the function using:
getRandomNumber()

knex two mysql query synchronize using promise

Promise.all(sendData.franchisee.map(row => {
return knex('designer.settings').select('value').where({setting_key : 'PRICING_TIER'})
.then(pricing_tier => {
row.pricing_tier = pricing_tier[0].value;
knex('designer.pricing_tier').select('tier_title').where({id : row.pricing_tier})
.then(tier_title =>{
row.tier_title = tier_title[0].tier_title;
return row;
})
});
})).then(response => {
cb(sendData);
});
Hear it two query in promise 'designer.settings' and 'designer.pricing_tier'.
when execute 'designer.settings' i got that result in row after execute 'designer.pricing_tier' but that output not get in row. row.tier_title = tier_title[0].tier_title not in final sendData.
How sync both query in one promise?
Not sure if the query actually does exact same thing, but this merely demonstrates the basic idea how to do the above query correctly with knex.
Effectively the same thing with joining the pricing_tier to prevent need for 2 separate queries.
Promise.all(
sendData.franchisee.map(row => {
return knex('pricing_tier')
.withSchema('designer') // <-- selecting schema correctly in knex
// this join could have been done as a subquery in select too...
.join('settings', 'settings.setting_key', knex.raw('?', ['PRICING_TIER']))
.select('settings.value', 'pricing_tier.tier_title')
.where('pricing_tier.id', row.pricing_tier)
.then(rows => {
row.pricing_tier = rows[0].value;
row.tier_title = rows[0].tier_title;
return row;
});
})
).then(response => {
cb(sendData); // <--- generally bad idea to mix promises and callbacks
});
Resulting SQL is like this:
select
`settings`.`value`,
`pricing_tier`.`tier_title`
from `designer`.`pricing_tier`
inner join `designer`.`settings` on `settings`.`setting_key` = 'PRICING_TIER'
where `pricing_tier`.`id` = 3219
You should wrap both queries into a promise which resolves only when both query have finished the job like this:
Promise.all(sendData.franchisee.map(row => {
return new Promise((resolve) => {
knex('designer.settings').select('value').where({setting_key : 'PRICING_TIER'})
.then(pricing_tier => {
row.pricing_tier = pricing_tier[0].value;
knex('designer.pricing_tier').select('tier_title').where({id : row.pricing_tier})
.then(tier_title =>{
row.tier_title = tier_title[0].tier_title;
resolve(row);
})
});
});
})).then(response => {
cb(sendData);
});

mongodb + nodejs to find and return specific fields in documents

I'm trying to extract specific document fields from a mongodb collection (v 3.0.8 at MongoLab). The returned documents must fall within a date range. My goal is to extract specific fields from these documents. My nodejs code,
var query = {}, operator1 = {}, operator2 = {}, operator3 = {} ;
operator1.$gte = +startDate;
operator2.$lte = +endDate;
operator3.$ne = 'move';
query['xid'] = 1; // Problem here?
query['date'] = Object.assign(operator1, operator2);
query['type'] = operator3;
console.log(query);
MongoClient.connect(connection, function(err, db) {
if(err){
res.send(err);
} else {
db.collection('jbone')
.find(query)
.toArray(function(err, result){
console.log(err);
res.json(result);
});
};
});
If I opt to return all fields in the date range, the query works fine. If I select only field xid I get no results. My query object looks sensible according to the docs. console.log(err) gives:
{ xid: 1,
date: { '$gte': 20160101, '$lte': 20160107 },
type: { '$ne': 'move' } }
null
null is the err.
Can anyone help me understand what I'm doing wrong?
Or point me to another similar SO questions with an answer?
Thanks
To select the specific field could be done as below
.find(
{date: { '$gte': 20160101, '$lte': 20160107 }, type: { '$ne': 'move' }},
{ xid: 1} )
Sample codes as following.
query['date'] = Object.assign(operator1, operator2);
query['type'] = operator3;
db.collection('jbone')
.find(query, {xid: 1})
.toArray(function(err, result){
console.log(err);
res.json(result);
});

nodejs parse mysql row to object

I'm a little newbie in node.js + mysql + object oriented.
Following question here I would like the 'Content' object to use the values returned by a mysql query. What I'm doing now I find it is really redundant and possibly stupid as rows[0] itself is the object I want to use. Any better way for doing this? Or different approach if this is wrong also appreciated.
(I'm using binary uuid keys that must be hex-stringifyed again to send as resource response)
content.js:
function Content() {
this.id = '';
this.name = '';
this.domain = '';
}
Content.prototype.validate = function(path, queryParams) {
...
return true;
};
Content.prototype.whatever = function(apiVersion, params, callback) {
...
return callback(null, newParams);
};
mysql.js:
MySQLDb.SELECT_CONTENT_ID = "SELECT id, name, domain FROM content WHERE id = UNHEX(?)";
MySQLDb.prototype.findContentByID = function(id, callback) {
this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ],
function(err, rows, fields) {
var content = new Content();
if (rows.length > 0) {
var i = 0;
for (var key in rows[0]) {
if (rows[0].hasOwnProperty(key) && content.hasOwnProperty(key)) {
// BINARY(16) --> HEX string
if (fields[i].columnType === 254) {
content[key] = rows[0][key].toString('hex').toUpperCase();
} else {
content[key] = rows[0][key];
}
} else {
console.log('Column ' + key + ' out of sync on table "content"');
}
i += 1;
}
}
callback(err, content);
});
};
contentRes.js:
contentRes.GETWhatever = function(req, res) {
db.findContentByID(req.params.id, function onContent(err, content) {
if (err || !content.validate(req.path, req.query)) {
return res.send({});
}
content.whatever(req.query.apiVersion, req.query.d,
function onWhateverdone(err, params) {
if (err) {
return res.send({});
}
return res.send(params);
});
});
};
I think a lot of people would say you are doing it generally the right way even though it admittedly feels redundant.
It might feel a little cleaner if you refactored your code such that you could call the Content() constructor with an optional object, in this case rows[0] although if you were keeping it clean you wouldn't have access to the fields so you would take a different approach to the data type conversion - either by selecting the HEX representation in query or simply having your Content() know it needs to convert the id property.
Keeping it fairly simple (by which I mean ignoring making the constructor a bit more intelligent as well as any error detection or handling), you would have:
function Content(baseObj) {
this.id = (baseObj && baseObj.id) ? baseObj.id.toString('hex').toUpperCase() : '';
this.name = (baseObj && baseObj.name) ? baseObj.name : '';
this.domain = (baseObj && baseObj.domain) ? baseObj.domain : '';
}
Then you could do something like this:
MySQLDb.prototype.findContentByID = function(id, callback) {
this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ],
function(err, rows, fields) {
if (err) return callback(err,null);
return callback(err, new Content(rows[0]));
});
You 'could' also grab the rows[0] object directly, HEX the UUID more or less in situ and modify the __proto__ of the object, or under Harmony/ES6 use the setPrototypeOf() method.
MySQLDb.prototype.findContentByID = function(id, callback) {
this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ],
function(err, rows, fields) {
if (err) return callback(err,null);
var content = rows[0];
content.id = content.id.toString('hex').toUpperCase();
content.__proto__ = Content.prototype;
return callback(err, content);
});
Note, I said you 'could' do this. Reasonable people can differ on whether you 'should' do this. __proto__ is deprecated (although it works just fine in Node from what I have seen). If you take this general approach, I would probably suggest using setPrototypeOf(), and install a polyfill until you are otherwise running with ES6.
Just trying to give you a couple of other more terse ways to do this, given that I think the redundancy/verbosity of the first version is what you didn't like. Hope it helps.