Node.js Sequelize: multiple condition on 'where' - sql

How do i query a table with multiple conditions? This give me no error but, only run the first condition!
exports.findAllLimit = (req, res) => {
const titulo = req.query.titulo ;
var condition = titulo ? { titulo : { [Op.iLike]: `%${titulo }%` } } : null;
var condition2 = {stock: { [Op.ne]: 0}};
Produtos.findAll({
where: condition , condition2,
include: [Categorias],
order: [
['id', 'ASC']
],
limit: 9
})
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Ocorreu um erro a retirar os dados do backend!."
});
});
};

You create here an object with property condition2 and it's value.
You need to merge these 2 conditions, and assign them on where.
so you can use:
where: Object.assign({}, condition , condition2),
OR:
where: {...condition, ...condition2}

you can do like this for multiple condition .
const titulo = req.query.titulo ;
var condition = titulo
? {
titulo: {
[Op.iLike]: `%${titulo}%`,
},
}
: null;
var condition2 = {
stock: {
[Op.ne]: 0,
},
};
let where = [];
where.push(condition);
where.push(condition2);
Produtos.findAll({
where,
});

Related

multiple select data in object format

I have a multiple select field where I'll be selecting multiple values, but when I am sending that data to the backend it should show in the following format:
"data":
[
{
"vehicle_id": "VEH1",
},
{
"vehicle_id": "VEH2",
},
]
but when I am selecting multiple values from drop down I am getting data in an array format:
"data":[
{
"vehicle_id":["VEH1","VEH2"]
}
]
How can I send data in the format which I have added in the beginning? .
Code:
const getSelectedVehices = (selectedvehicles: any[]) => {
const vehicles: Array<string> = [];
const items = new Map<string, string>();
vehicleListData.forEach((item) => {
items.set(item.vehicleName, item.vehicleAliasId);
});
selectedvehicles.forEach((item) => {
vehicle.push(items.get(item) || '');
});
return vehicles;
};
const prepareSelectedVehiclesServices = (electedvehicles: any[]) => {
const vehicles: Array<string> = [];
const items = new Map<string, string>();
vehicleListData.forEach((item) => {
items.set(item.vehicleName, item.vehicleAliasId);
});
vehicles.forEach((item) => {
if (items.has(item)) {
vehicles.push(items.get(item) || '');
}
});
return vehicles;
};
<MultiSelect
items={pickerOptions.vehicleServices}
onSelectedItemsChange={(Ids: any[]) => {
const selectedVehiclesServices = getSelectedVehicles(Ids);
formikData.setFieldValue(`vehicles`, [
{
vehicleAliasId: selectedVehiclesServices,
},
]);
}}
selectedItems={{
selectedItemIdentifiers: prepareSelectedVehiclesServices(
formikData.values.services || initialServiceValues.services,
),
}}
></MultiSelect>
the above is the code which I have added.
Just project the array into your new format with .map(). Something like this:
let myData = { "data":[
{
"vehicle_id":["VEH1","VEH2"]
}
]};
let myNewData = { "data": myData.data[0].vehicle_id.map(d => ({
"vehicle_id": d
}))};
console.log(myNewData);

How do I resolve a callback error with 'callback' is an instance of Object)?

TypeError: callback is not a function. (In 'callback(data)',
'callback' is an instance of Object)
The code here works just fine when I write it like this:
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
// { categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
When i uncomment that other line, it breaks and gives me this error.
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
{ categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
Here is the relevant snippet from listingsAPI (below) if it helps but this code works fine when there is only one object. Is there a specific way to make this work with two objects like above?
if (categoryId) {
return (
listingsRef
.where('categoryID', '==', categoryId)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
if (categoryId2) {
return (
listingsRef
.where('categoryID2', '==', categoryId2)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
You can combine your queries via this way if you want to have it optional:
let query = listingsRef.where('isApproved', '==', isApproved)
if (categoryId) {
query = query.where('categoryID', '==', categoryId)
}
if (categoryId2) {
query = query.where('categoryID2', '==', categoryId2)
}
query.onSnapshot...

How to sanitize inputs in nodejs to prevent sql injection?

i have this sanitize function
sanitizeXSS: string => {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/',
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
And this sanitize function is being used here
addOrUpdateAddress : function (request, resolve)
{
const customerKey = sanitizeXSS(decrypt_key(request.customer_key));
const lat = sanitizeXSS(decrypt_key(request.lat));
const lng = sanitizeXSS(decrypt_key(request.lng));
const line1 = sanitizeXSS(decrypt_key(request.line1));
const line2 = sanitizeXSS(decrypt_key(request.line2));
const city = sanitizeXSS(decrypt_key(request.city));
const pincode = sanitizeXSS(decrypt_key(request.pincode));
const state = sanitizeXSS(decrypt_key(request.state));
const contact = sanitizeXSS(decrypt_key(request.contact));
const landmark = request.landmark?sanitizeXSS(decrypt_key(request.landmark)):null;
let req=request;
if(req.name && req.email)
{
updateUser(req,function(err,result)
{
console.log(err);
console.log(result);
});
}
let addressId = (!req.address_id || req.address_id == null || req.address_id == '')
? -1 : req.address_id;
console.log(addressId);
async.auto({
serviceability : function (cb)
{
searchServiceArea(req,function(err,result)
{
if(err)
{
resolve(null, {'errorMessage':'Address selected not serviceble'}, 203, 'error');
}
else
{
if(!result.hub_id)
{
resolve(null, {'errorMessage':'Address selected not serviceble'}, 203, 'error');
}
if(addressId == -1)
{
let s=mysql.write('customer_address').insert({customer_key: customerKey,line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss"),created_at:moment().format("YYYY-MM-DD HH:mm:ss")}).then(function(res)
{
if(res.length > 0)
{
cb(null,{address_id:res[0],customer_key: customerKey,line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss"),created_at:moment().format("YYYY-MM-DD HH:mm:ss"),'hub_id':result.hub_id})
}
else
{
cb(true,{'errorMessage':'Unable to add address try again'})
}
});
}
else
{
let s=mysql.write('customer_address').update({line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss")}).where({customer_key:customerKey, address_id:addressId}).then(function(res)
{
console.log(res)
if(res == 1)
{
cb(null,{address_id:addressId,customer_key: customerKey,line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss"),created_at:moment().format("YYYY-MM-DD HH:mm:ss"),'hub_id':result.hub_id})
}
else
{
cb(true,{'errorMessage':'Unable to update address try again'})
}
},
},
);
}
So while inserting the address I'm identifying sql injection. I checked everywhere the possible solutions i was not able to solve it. Please do check the sql query also which i have mentioned.
How to solve this?
That would be a lot of help. Thanks in advance
I'd just use a standard library that already provides sanitization, like node-mysql.
https://github.com/mysqljs/mysql#escaping-query-values
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'example.org',
user : 'bob',
password : 'secret'
});
const post = {title: 'Hello MySQL', 'content': '...'};
connection.query(
'insert into posts (title, content, updated_at, created_at) values (?, ?, ?, ?);',
[
connection.escape(post.title),
connection.escape(post.content),
connection.escape(new Date()),
connection.escape(new Date())
]
).then((err, res, fields) => {
//do stuff
})

Vue js - not all the data showing after store dispatch

The select box not showing sometimes the first color and sometimes not showing the first color.
How can i make it to show all the item in the select box?
I'm not getting for some reason all the promises
You can see the issue in the picture
Please help me to fix this issue i'm new to vue js
My code:
data() {
return {
propertiesTree: []
}
}
getPropertyGroups(objectId: number): void {
if (this.$data.currentObjectId === objectId)
return;
let component: any = this;
this.$data.currentObjectId = objectId;
component.showLoader();
this.$store.dispatch('properties/getPropertyGroups', objectId)
.then(({ data, status }: { data: string | Array<propertiesInterfaces.PropertyGroupDto>, status: number }) => {
// console.log(data, "data");
// console.log(status, "status")
if (status === 500) {
this.$message({
message: data as string,
type: "error"
});
}
else {
let anyData = data as any;
anyData.map(item => {
item.properties.map(prop => {
if(prop.type.toString() === 'dictionary'){
prop.dictionaryList = [];
prop.color = '';
this.getWholeDictionaryList(prop.dictionaryId.value, prop)
}
});
});
}
component.hideLoader();
});
},
getWholeDictionaryList(dictionaryId: number, prop: any){
this.$store.dispatch('dictionaries/getWholeDictionaryList', dictionaryId).then(
({ data, status }: { data: Array<any> |string , status: number }) => {
if (status === 500) {
this.$message({
message: data as string,
type: "error"
});
} else {
const arrData = data as Array<any>;
arrData.map((item,index) => {
prop.dictionaryList = [];
prop.dictionaryList = data;
this.getDictionaryItemColor(item.id.value, data, index, prop);
});
}
});
},
getDictionaryItemColor(dictionaryItemId:number, dictionaryList: Array<any>, index:number, current){
this.$store.dispatch('patterns/getDictionaryItemColor', dictionaryItemId).then((data: any, status: number) => {
if (status === 500) {
this.$message({
message: data as string,
type: "error"
});
} else{
debugger
if(current.dictionaryItemId.value === data.data.sceneObjectId)
current.color = data.data.colorString;
dictionaryList[index].color = data.data.colorString ? data.data.colorString: '#FFFFFF';
}
});
},
Html code of the select box
<el-select v-model="data.color" placeholder="Select">
<el-option
v-for="item in data.dictionaryList"
:key="item.name"
:label="item.color"
:value="item.color">
</el-option>
</el-select>
I did return to dispatch
let dispatch = this.getWholeDictionaryList(prop.dictionaryId.value, prop)
let promiseArr = [];
promiseArr.push(dispatch);
after the map closing tag i did
Promise.all(promisArr).then( () => {
debugger
this.$data.propertiesTree = anyData;
});
And I've got it solved

How to join two collections in a json store?

I am working on IBM Worklight. I need to access data from two collections. Is there any solution for joining the 2 collections and get the required fields ?
JSONSTORE does not have the ability to combine collections.
However the follow blog post details one way to achieve this: https://mobilefirstplatform.ibmcloud.com/blog/2015/02/24/working-jsonstore-collections-join/
Create a collection:
var OrdersCollection = {
orders: {
searchFields: {
order_id: 'integer',
order_date: 'string'
},
additionalSearchFields: {
customer_id: 'integer'
}
}
};
var CustomerCollection = {
customers: {
searchFields: {
customer_name : 'string',
contact_name : 'string',
country : 'string'
},
additionalSearchFields : {
customer_id : 'integer'
}
}
};
Add data using additional search fields:
var data = [
{order_id : 462, order_date : '1-1-2000'},
{order_id: 608, order_date : '2-2-2001'},
{order_id: 898, order_date : '3-3-2002'}
];
var counter = 0;
var q = async.queue(function (task, callback) {
setTimeout(function () {
WL.JSONStore.get('orders').add(task.data, {additionalSearchFields: {customer_id: task.customer_id}});
callback(++counter);
},0);
},1);
for(var i = 0; i < data.length; i++){
q.push({data : data[i], customer_id: i+1}, function(counter){
console.log("Added Order Doc " + counter);
});
}
q.drain = function(){
setTimeout(function() {
console.log("Finished adding order documents");
WL.JSONStore.get("orders").findAll({filter : ["customer_id", "order_id", "order_date"]})
.then(function (res) {
ordersCollectionData = res;
document.getElementById("orders").innerHTML = JSON.stringify(res, null, "\t");
})
.fail(function (err) {
console.log("There was a problem at " + JSON.stringify(err));
});
},0);
};
Find the documents to merge:
WL.JSONStore.get('orders').findAll({filter : ['customer_id', 'order_id', 'order_date']})
.then(function (res) {
ordersCollectionData = res;
});
Merge
var shared_index = 'customer_id';
var mergedCollection = [];
mergedCollection =_.merge(customerCollectionData, ordersCollectionData, function(a, b){
if(_.isObject(a) && (a[shared_index] == b[shared_index])) {
return _.merge({}, a, b);
}
});