I'm trying to figure out how do I pass in an argument to a named callback function?
For example I have
var result = this.data;
var groupFilter = $("#groupSelect");
var functionFilter = $("#functionSelect");
var skillFilter = $("#skillSelect");
var uniqSkils = _(result).map('skill').uniq().map(populateDropdown(skillFilter));
var uniqFunctions = _(result).map('function').uniq().map(populateDropdown(functionFilter));
var uniqgroups = _(result).map('group').uniq().map(populateDropdown(groupFilter));
function populateDropdown(element) {
element.append($('<option>', {
value: item,
text: item
}))
}
Essentially the result contains dropdown values for three elements. I've created 3 arrays, I've then called uniq for obvious reasons, then I want to go through each array, each item and add it to the correct elements.
But I can't figure out how to pass in the element when using a named callback
You could have your populateDropdown return a closure that is bound to a particular element:
function populateDropdown(element) {
return function(item) {
element.append($('<option>', {
value: item,
text: item
}));
}
}
Related
Is there a way to directly map each element in an array into a separate function and return the result of each function into a separate variable for that element?
For example, I have this code:
arry = ["22-03-1995", 80.5, 1.83];
born = process_date(arry[0]); // call specific function for 1st element
weight = process_weight(arry[1]); // call specific function for 2nd element
height = process_height(array[2]); // call specific function for 3rd element
...
function process_date(d) { ... }
function process_weight(w) { ... }
function process_height(h) { ... }
or such an alternative method to achieve the same in a better shorter form.
if there's only one array you want to map then you probably want something like this:
const [born, weight, height] = [
process_date(arry[0]),
process_weight(arry[1]),
process_height(array[2])
]
if there are multiple arrays then that needs its own handling, you can create a function that takes the input array and returns the mapped array:
function mapArray(arr) {
return [
process_date(arr[0]),
process_weight(arr[1]),
process_height(arr[2])
]
}
arry.forEach(arr => {
const [born, weight, height] = mapArray(arr);
// do stuff with the variables here...
})
Check out this. Might help you somehow.
You can destruct your each arrays element and assign them to a new variable. Aswel you can pass array to function as arguments.
https://javascript.info/destructuring-assignment
You could put your functions into an object. Then put your values into an array of objects, so that you can have metadata to tell the value what function it should call.
Example
const valueObjects = [{
type: "date",
value: "22-03-1995"
}, {
type: "weight",
value: 80.5
}]
const calculations = {
date: function process_date(d) {...},
weight: function process_weight(w) {...}
};
valueObjects.forEach(valueObject => {
const processType = calculations[valueObject.type];
processType(valueObject.value);
})
Hope this can help you
arry = ["22-03-1995", 80.5, 1.83];
arrayFunc = [function process_date(d) { ... }, function process_weight(w) { ... }, function process_height(h) { ... } ]
array.forEach(myFunction);
let results = []
function myFunction(item, index) {
results << arrayFunc[index](item)
}
let born, weight, height;
[born, weight, height] = results;
console.log(born);
console.log(weight);
console.log(height);
I'm trying to get either options or, ideally, dynamicTable passed from initializeTable to the applyTableFilters function and I'm having problems getting the expected values. I'm using List.js to make a table dynamic and I need to pass or recreate the dynamicTable object so I can go ahead and use it to filter the table.
Here is the function that creates the List.js object from the HTML table:
function initializeTable(options) { // initializes table to be dynamic using List.js functions
var dynamicTable = new List("table-content", options);
dynamicTable.on("updated", function (list) { // writes a message to the user if no results are found
if (list.matchingItems.length == 0) {
document.getElementById("no-results").style.display = "block";
}
else {
document.getElementById("no-results").style.display = "none";
}
});
console.log(dynamicTable);
console.log(options);
console.log(arguments.length);
applyTableFilters.bind();
}
I've tried different methods to pass the variables to the function below. I tried .call, applyTableFilters(args), and .apply, but the problem is that I do not want the function to execute from inside here, only when the click event from the button goes off (not shown in these functions).
This is the function I want to pass the object to and proceed to make the filter functions using it:
function applyTableFilters(dynamicTable) {
var form = document.getElementById("filter-form");
//console.log(options);
//var dynamicTable = new List("table-content", options);
console.log(dynamicTable);
var filters = form.querySelectorAll('input[type="checkbox"]:checked');
dynamicTable.filter(function (item) {
console.log(item);
console.log(item._values);
if (item.values().id == 2) {
return true;
}
else {
return false;
}
//var filterStrings = [];
//console.log(filters);
//for (var i = 0; i < filters.length; i++) {
// var filterVal = filters[i].value;
// var filterString = "(" + item.values().column == filterVal + ")"; // filterVal.contains(item.values().column) ||
// filterStrings.push(filterString);
// console.log(filterVal);
// console.log(filterString);
//}
//console.log(filterStrings);
//var filterString = filterStrings.join(" && ");
//console.log(filterString);
//return filterString;
});
}
I've used:
applyTableFilters.bind(this, dynamicTable/options);
applyTableFilters.bind(null, dynamicTable/options);
applyTableFilters.bind(dynamicTable/options);
Switching between the two since I don't need both passed if one ends up working, etc. I always get a mouse event passed in and that's not even the right type of object I'm looking for. How can I get the right object passed? Also all the values in the first function are not empty and are populated as expected so it's not the original variables being undefined or null. Thanks in advance.
From your initializeTable function return a function that wraps the applyTableFilters function with the arguments you want.
Then assign the returned function to a var to be executed later.
function initializeTable(options) {
var dynamicTable = new List("table-content", options);
// other stuff
return function () {
applyTableFilters(dynamicTable)
}
}
// other stuff
var applyTableFiltersPrep = initializeTable(options)
// later, when you want to execute...
applyTableFiltersPrep()
JSFiddle example
I am trying to reduce an array inside of an object. I am getting back
push is not a function
I have started my array as empty and created a add function to pass in as the first argument.
function add(a,b) {
return a +b;
}
var navBarArray = [];
var listArray = [];
var mapping = {
".navbar": navBarArray,
".list-group": listArray
};
I tried this approach on the mapping object but it creates errors
var mapping = {
".navbar": Math.round(navBarArray.reduce(add,0) ),
".list-group": listArray
};
However, I get push is not a function back in my console.
Below is my function that passes values to the array. I can create a variable inside the function and reduce it there. However, that limits access to my variable and will bloat my function as I continue.
Object.keys(mapping).forEach(function(selector) {
$(selector).hover(function(evt) {
console.log('mapping',mapping);
console.log('selector',selector);
enteredTime = new Date();
}, function() {
var ctime = new Date();
var time = (ctime.getTime() - enteredTime.getTime())/1000;
mapping[selector].push(time);
// *********** this works but not where I need it to*******
var reduce = Math.round(navBarArray.reduce(add,0) );
console.log(reduce);
});
})
Change your mapping object so it has separate places for the array and total:
var mapping = {
".navbar": {
total: 0,
times: []
},
".list-group": {
total: 0,
times: []
}
}
Then you do mapping[selector].times.push(time), and put the total with:
mapping[selector].total = mapping[selector].times.reduce(add, 0);
So here's what I'm trying todo:
Note: These objects are just an example of what I'm trying todo, they are not the actual objects I'm working with.
var object = {
header: "Header",
selectorObject: selector = new Selector(), //Property has Object value
footer: "Footer"
}
function Selector() {
var index = 0;
this.rotateLeft = function() {
index++;
return index;
}
this.rotateRight = function() {
index--;
return index;
}
}
I want to know if it's possible to give an object property value of an already defined object?
If this is possible, how do I access the object once its been assigned to the property?
I know that this is possible in another form:
var object = {
header: "Header",
selectorObject: {
//Properties and functions
},
footer: "Footer"
}
However, my selectorObject will be used more than once, so it would be a shame to duplicate code for every object I use it in.
With the code above, you can just hand the selectorObject to a new instance of whatever new object you need, the instance would be the same:
object.selectorObject.rotateLeft()
> 1
object.selectorObject.rotateLeft()
> 2
var obj2 = { selectorObject: object.selectorObject };
obj2.selectorObject.rotateLeft()
> 3
I am stuck with the following situation. I have a select statement which uses a function in the current scope me. How do I go about putting me into the select function?
var me = this;
var results = Enumerable
.from(jsonData)
.select('x,i=>{abbr:me.transform(x), name:x}')
.toArray(); //me.transform(x) will hit error
'me' is an instance of a dynamically generated object, and me.transform(x) uses other dependencies in 'me' to work as well. That means I cannot make 'me.transform()' global function.
EDIT
var me = this;
var results = Enumerable
.from(jsonData)
.select(function(x,i){
return {abbr:me.transform(x), name:x};
}).toArray();
Actually, this modification will work, however, I would like to find out the how to make the shortcut syntax work.
What you could do is project your objects to a composite object containing both the item in the collection and the object you want to introduce into the query.
You can use this Capture function to capture the variables:
function Capture(bindings, name) {
var benumerable = Enumerable.From(bindings),
itemname = name || 'Item';
return function (e) {
return e.Select(function (item) {
return benumerable.Concat(Enumerable.Return({ Key: itemname, Value: item }))
.ToObject("$.Key", "$.Value");
});
};
}
Use it in a Let binding.
var query = Enumerable.From(data)
.Let(Capture({ Me: me }))
.Select("{ abbr: $.Me.transform($.Item), name: $.Item }")
.ToArray();
My bad. Is this what you mean?
var me = this;
var results = Enumerable
.from(jsonData)
.select('x,i=>{abbr:' + me.transform(x) + ', name:x}')
.toArray(); //me.transform(x) will hit error