Sequelize multiple delete on multiple columns - javascript

I need to delete rows based on query of multiple columns, here is my code:
var destroyQuery = testArr.map(function(mc){
return {
id: mc.id,
text: mc.text
}
});
db.testModel.destroy({ where: destroyQuery }).then(function(dResponse){});
For deleting one record it works fine:
db.testModel.destroy({ where: {id: '123', text: 'abc'} }).then(function(dResponse){});
How can i delete multiple rows by querying multiple columns. Any help is appreciated.
Thanks

For your argument "mc" in function, you should use an array like given example below:
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(function(obj) {
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map check this article. might be it solve your purpose.

I used this option, is fast and simple
var destroyQuery = testArr.map(function(mc){
return {
id: mc.id,
text: mc.text
}
});
db.testModel.destroy({
where:{
[Op.or]: destroyQuery
}
}).then(function(dResponse){});

Related

Javascript Array Push and Display

I am doing a Laravel project with editable inline with select option however I want I manage to query the brands and I want to display the array after I push it in the source. Please help
var brand = [];
data_brand.forEach(function(element) {
var branddetails = {value: element.id, text: element.brand_name};
brand.push(branddetails);
});
$(function(){
$('#brand').editable({
value: 2,
source: [
//I want to output like this {value: 1, text: 'Active'},
brand.values() // this code does not work
]
});
});
This should work:
source: brand.map(item => item)
or simply:
source: brand
brand is an array and you since source also expecting the array, You can try like this
source: [...brand]
In order to display the array elements, use loop.
Example-
let branddetails = [{value: 1, text: "something" }];
branddetails.forEach(brand => console.log(brand));
-- Edit --
Instead of creating array and then getting the pushed element, you can directly add the element itself in the source array.
let branddetails;
data_brand.forEach(function (element) {
branddetails = { value: element.id, text: element.brand_name };
});
$(function () {
$('#brand').editable({
value: 2,
source: [
branddetails
]
});
});

Compare between two arrays

While I was thinking in someway to compare between two arrays, accidentally for the first time something like this happens with me.. something worked with me for the first time without showing me any errors!
This is a very simplified visualization for an application I'm working on currently.
I have two arrays, one called options, the other is called correct.
so the options are options of some question, the chances are the chances of this question.
in this example two of the options are correct answers..
so what I have to do is to compare between this two arrays to check if it returns true (later) or if it's returning false (not included in the code).
could you please explain for me how this actually worked?
const options = ['facebook', 'twitter', 'tango', 'skype'];
const correct = ['twitter', 'skype'];
const trueIndexes = [];
options.forEach((cur, index) => {
correct.forEach((cur1, index1) => {
if (cur === cur1) {
trueIndexes.push(index);
}
});
});
console.log(trueIndexes);
There are nested forEach loops for each array, and during each inner loop there is a conditional test to ascertain if one element exists in the other. If so, the index of where the matching item exists in the other array is pushed to the new trueIndexes array.
Another way to write this is:
const options = ['facebook', 'twitter', 'tango', 'skype']
const correct = ['twitter', 'skype']
const trueIndices = correct.reduce((_trueIndices, correctItem) => {
let correctItemIndex = options.indexOf(correctItem)
if(correctItemIndex !== -1) _trueIndices.push(correctItemIndex)
return _trueIndices
}, [])
console.log(trueIndices)
or
const options = ['facebook', 'twitter', 'tango', 'skype']
const correct = ['twitter', 'skype']
const trueIndices = []
correct.forEach((correctItem) => {
let correctItemIndex = options.indexOf(correctItem)
if(correctItem !== -1) trueIndices.push(correctItem)
})
console.log(trueIndices)
Both of these alternate solutions should be faster.
Your code goes through each option and compares it to both correct values.
If they match the index of the option is added to the true indexes list.
So the comparisons are like follows:
'facebook' = 'twitter'? no
'facebook' = 'skype'? no
'twitter' = 'twitter'? YES -> add index to list
'twitter' = 'skype'? no
'tango' = 'twitter'? no
'tango' = 'skype'? no
'skype' = 'twitter'? no
'skype' = 'skype'? YES -> add index to list
As explained by others, you just iterate over all the combinations of these 2 arrays and collect the indexes where an option is in both arrays(in other words, if an option is true)
I just wanted to add that you should perhaps change your data structure so that options are stored with the questions...and correct answers are indicated by a flag so they don't need to be looked up.
For example:
const questions = [
{
id: 'social_1',
question: 'Which of these are popular social media sites?',
answers: [
{id: 'fb', label: 'Facebook', correct: true},
{id: 'skype', label: 'Skype', correct: false},
{id: 'twitter', label: 'Twitter', correct: true},
{id: 'yt', label: 'YouTube', correct: false},
]
}, {
id: 'cars_1',
question: 'Which of these are car brands?',
answers: [
{id: 'tesla', label: 'Tesla', correct: true},
{id: 'bmw', label: 'BMW', correct: true},
{id: 'twitter', label: 'Twitter', correct: false},
{id: 'yt', label: 'YouTube', correct: false},
]
}
];
https://jsfiddle.net/rainerpl/L438qjms/26/

knockout Mapping for array of objects, for certain properties using 'observe'

I would like to make a deep copy of the below array. And the result should observe only the count property.
data = [{
id: 1,
code: 'ABC',
count: ko.observable(0)
},{
id: 2,
code: 'JKL',
count: ko.observable(5)
},{
id: 3,
code: 'QWE',
count: ko.observable(1)
}]
I tried ko.mapping.fromJS(ko.mapping.toJS(data)); but id and code was also converted to observables.
Currently I am using the below code to get the expected result.
var obj = ko.mapping.toJS(data);
var result = [];
obj.forEach(function(o){
var obs = ko.mapping.fromJS(o, {
'observe': "count"
});
result.push(obs);
});
// result will give the expected result
Here I have used forEach to loop each object in the data array. Is there a way to avoid the forEach loop ? or How to observe only the count property in array of object.
You can avoid the forEach as well as observe only count like this:
var result = ko.mapping.fromJS(data, {observe: 'count'});
console.log(result());
Edit:
According to the docs, we don't even need to mention ko.observable in our data. It should simply pick that up based on our 'observe' parameter. So maybe you might want to modify your data like this:
var data = [{
id: 1,
code: 'ABC',
count: 0
}, {
id: 2,
code: 'JKL',
count: 5
}, {
id: 3,
code: 'QWE',
count: 1
}];
And then, using forEach,
var result = [];
data.forEach(function(o){
result.push(ko.mapping.fromJS(o, {observe:'count'}));
});
console.log(result);
It's up to you, which method you would prefer to use.

How to prevent lodash mapKeys from reordering my array?

I'm using lodash mapKeys to take my array of objects and convert it to a mapped object using the id property. That's simple enough, but the problem is that it's sorting the new object by id.
For example if I had three objects in my array:
let myArray = [
{
id: 3,
name: 'Number Three'
},
{
id: 1,
name: 'Number One'
},
{
id: 2,
name: 'Number Two'
}
];
Then I map the keys by id:
_.mapKeys(myArray, 'id')
It returns the following:
{
1: {
id: 1,
name: 'Number One'
},
2: {
id: 2,
name: 'Number Two'
},
3: {
id: 3,
name: 'Number Three'
}
}
My server returns the array in a specific order, so I would like the objects to remain the same, so that when I loop over the object properties, they are in the correct order.
Is that possible with this method? If not, is there a possible alternative to achieve the results?
Use a Map because each item has a custom key (like objects), but the order of insertion will be the order of iteration (like arrays):
const myArray = [
{
id: 3,
name: 'Number Three'
},
{
id: 1,
name: 'Number One'
},
{
id: 2,
name: 'Number Two'
}
];
const map = myArray.reduce((map, item) => map.set(item.id, item), new Map());
map.forEach((item) => console.log(item));
As pointed out in the comments, looping over an object doesn't guarantee order. If you want an ordered list, you need an array.
However, you could apply the iterator pattern. In this pattern, it's up to you to decide what “next” element is. So, you could have a set with the objects (in order to get them in constant time) and an array to store the order. To iterate, you'd use the iterator.
This code could be used as example.
Hope it helps.
let myArray = [{
id: 3,
name: 'Number Three'
}, {
id: 1,
name: 'Number One'
}, {
id: 2,
name: 'Number Two'
}];
let myIterator = ((arr) => {
let mySet = _.mapKeys(arr, 'id'),
index = 0,
myOrder = _.map(arr, _.property('id'));
return {
getObjById: (id) => mySet[id],
next: () => mySet[myOrder[index++]],
hasNext: () => index < myOrder.length
};
})(myArray);
// Access elements by id in constant time.
console.log(myIterator.getObjById(1));
// Preserve the order that you got from your server.
while (myIterator.hasNext()) {
console.log(myIterator.next());
}
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
Like mentioned in the comments, the best would be to keep the object references both in an array to keep the order and in a hash to ease updating.
Backbone's collection (source) works like this. It keeps objects in an array (models), but automatically updates a hash (_byId) when adding and removing models (objects) or when a model's id changes.
Here's a simple implementation of the concept. You could make your own implementation or check for a collection lib.
// a little setup
var array = [];
var hash = {};
var addObject = function addObject(obj) {
hash[obj.id] = obj;
array.push(obj);
}
// Create/insert the objects once
addObject({ id: 3, name: 'Number Three' });
addObject({ id: 1, name: 'Number One' });
addObject({ id: 2, name: 'Number Two' });
// Easy access by id
console.log("by id with hash", hash['1']);
// updating is persistent with the object in the array
hash['1'].name += " test";
// keeps the original ordering
for (var i = 0; i < 3; ++i) {
console.log("iterating", i, array[i]);
}

Filter response object based on an array of whitelisted ids

How to Filter a response object based on an array of whitelisted ids?
I've a working version but i don't like the nested forEach here and i wonder if there is a way to improve it?!
function WhitelistCtrl($scope) {
var visible = [];
var whitelist = [123, 456]; // items to be visible
var response = [{
id: 123,
name: 'my object #1'
}, {
id: 456,
name: 'my object #2'
}, {
id: 789,
name: 'my object #3'
}];
angular.forEach(whitelist, function (id) {
angular.forEach(response, function (item) {
if (id === item.id) {
visible.push(item);
}
});
});
}
Here is a JSFiddle to play with: http://jsfiddle.net/gearsdigital/rv6vq2L7/
I'm not much familiar with Anglar ForEeach but you can achive this using native javascript filter like bellow
visible = response.filter(function(item){
return (whitelist.indexOf(item.id) > -1);
})
DEMO
NOTE:- IE8 doesn't supports .filter.

Categories