I have an array of objects and I want to extract the value when key is passes in 'filter' filter. Below is the controller code snippet I have tried, but the type of response I get is undefined. Please help me in finding where am I going wrong.
var states = [{"HIMACHAL PRADESH":"HP"},{"JAMMU AND KASHMIR":"JK"},{"JHARKHAND":"JH"},{"KARNATAKA":"KA"},{"KERALA":"KL"},{"MADHYA PRADESH":"MP"},{"MAHARASHTRA":"MH"},{"ORISSA":"OR"}]
var str = "ORISSA";
var abbr = $filter('filter')(states, {key: str}, true).value;
console.log ("ABBR:"+abbr);
P.S. I have injected $filter in the controller
Use Object.keys and find
var matchedState = states.find( s => Object.keys( s )[0] == str );
var abbr = matchedState ? matchedState[str] : ""
Demo
var states = [{
"HIMACHAL PRADESH": "HP"
}, {
"JAMMU AND KASHMIR": "JK"
}, {
"JHARKHAND": "JH"
}, {
"KARNATAKA": "KA"
}, {
"KERALA": "KL"
}, {
"MADHYA PRADESH": "MP"
}, {
"MAHARASHTRA": "MH"
}, {
"ORISSA": "OR"
}]
var str = "ORISSA";
var matchedState = states.find(s => Object.keys(s)[0] == str);
var abbr = matchedState ? matchedState[str] : ""
console.log(abbr);
Related
Say I have the array below
var someStuff = [
"start", { one: "one"},
"setSomething", "foobar",
"someBool", true
];
How can I transform it to be as below
var someStuff = [
MainFunc.start({one: "one"}),
MainFunc.setClientId('foobar'),
MainFunc.someBool(true)
];
Assuming you want an array containing results from a number of function calls, this is how you can get that. You need to iterate over the array, get each function from the MainFunc object and then call that each time.
I included handling for a non-existing function being called, which happened to be in your example (perhaps not intentional).
var MainFunc = {
start : function(x) { return "start called with " + x.toString(); },
setClientId : function(x) { return "setClientId called with " + x.toString(); },
someBool : function(x) { return "someBool called with " + x.toString(); }
}
var someStuff = [
"start", { one: "one" },
"setSomething", "foobar",
"setClientId", "foobar",
"someBool", true
];
var result = Process(someStuff);
function Process(arr) {
var result = [];
for (var i = 0; i < arr.length; i += 2) {
let fnToCall = MainFunc[arr[i]];
let fnResult = fnToCall ? fnToCall(arr[i + 1]) : "(unknown: '" + arr[i] + "')";
result.push(fnResult);
}
return result;
}
console.log(result);
Try it like this (You need to use arrow functions because otherwise the function would get called straigh away):
var someStuff = [
"start", { one: "one"},
"setSomething", "foobar",
"someBool", true
];
let output = []
for(let i=0, j=0; i<someStuff.length; i+=2, j++) {
let functionName = someStuff[i];
let functionArgs = someStuff[i+1];
output[j] = () => MainFunc[functionName](functionArgs);
}
console.log(output);
I think you might want to do this
function mainFunc() {
this.start = function(obj) { console.log("start",obj) };
this.setSomething = function(obj) { console.log("set",obj) };
this.someBool = function(obj) { console.log("bool",obj) };
}
var someStuff = {
"start": { "one":"one"},
"setSomething": "foobar",
"someBool": true
};
var mf = new mainFunc();
for (var a in someStuff) {
mf[a](someStuff[a])
}
For better readability, define an array of objects with action and its parameter.
const mainFunc = {
start: (param) => console.log('start', param),
setSomething: (param) => console.log('SetSomething', param),
someBool: (param) => console.log('someBool', param)
}
var someStuff = [
{ action: "start", param: { one: "one"} },
{ action: "setSomething", param: "foobar" },
{ action: "someBool", param: true }
];
someStuff.forEach(stuff => {
if (typeof mainFunc[stuff.action] === 'function') {
mainFunc[stuff.action](stuff.param);
}
});
I have the following object array:
var data = {};
data.type = {
"types": [{
"testA": {
"testVar": "abc",
"testContent": "contentA"
}
}, {
"testB": {
"testVar": "def",
"testContent": "contentB"
}
}]
};
What I'm trying to do is find the value of testContent based on finding the object it belongs by searching it's parent and sibling:
/* within the data, find content where parent is testA and sibling testVar is "abc" */
var findSet = data.type.types.find(function(entry) {
return entry['testA'].testVar === "abc";
});
console.log(findSet['testA'].testContent); /* returns string "contentA" as expected */
This works fine for first object but fails to find next object, giving error:
Cannot read property 'testVar' of undefined
var findSet = data.type.types.find(function(entry) {
return entry['testB'].testVar === "def"; /* Cannot read property 'testVar' of undefined */
});
console.log(findSet['testB'].testContent);
How else could I find what's needed?
Here's a fiddle to test the output
var data = {};
data.type = {
"types": [{
"testA": {
"testVar": "abc",
"testContent": "contentA"
}
}, {
"testB": {
"testVar": "def",
"testContent": "contentB"
}
}]
};
var findSet = data.type.types.find(function(entry) {
return entry['testA'] && entry['testA'].testVar === "abc";
});
console.log(findSet['testA'].testContent);
var findSet = data.type.types.find(function(entry) {
return entry['testB'] && entry['testB'].testVar === "def"; /* Cannot read property 'testVar' of undefined */
});
console.log(findSet['testB'].testContent);
just check if your entry exist before testing his attribute.
I am not very good with my javascript but recently needed to work with a library to output an aggregated table. Was using fin-hypergrid.
There was a part where I need to insert a sum function (rollups.sum(11) in this example)to an object so that it can compute an aggregated value in a table like so:
aggregates = {Value: rollups.sum(11)}
I would like to change this value to return 2 decimal places and tried:
rollups.sum(11).toFixed(2)
However, it gives the error : "rollups.sum(...).toFixed is not a function"
If I try something like:
parseFloat(rollups.sum(11)).toFixed(2)
it throws the error: "can't assign to properties of (new String("NaN")): not an object"
so it has to be a function object.
May I know if there is a way to alter the function rollups.sum(11) to return a function object with 2 decimal places?
(side info: rollups.sum(11) comes from a module which gives:
sum: function(columnIndex) {
return sum.bind(this, columnIndex);
}
)
Sorry I could not post sample output here due to data confidentiality issues.
However, here is the code from the example I follow. I basically need to change rollups.whatever to give decimal places. The "11" in sum(11) here refers to a "column index".
window.onload = function() {
var Hypergrid = fin.Hypergrid;
var drillDown = Hypergrid.drillDown;
var TreeView = Hypergrid.TreeView;
var GroupView = Hypergrid.GroupView;
var AggView = Hypergrid.AggregationsView;
// List of properties to show as checkboxes in this demo's "dashboard"
var toggleProps = [{
label: 'Grouping',
ctrls: [
{ name: 'treeview', checked: false, setter: toggleTreeview },
{ name: 'aggregates', checked: false, setter: toggleAggregates },
{ name: 'grouping', checked: false, setter: toggleGrouping}
]
}
];
function derivedPeopleSchema(columns) {
// create a hierarchical schema organized by alias
var factory = new Hypergrid.ColumnSchemaFactory(columns);
factory.organize(/^(one|two|three|four|five|six|seven|eight)/i, { key: 'alias' });
var columnSchema = factory.lookup('last_name');
if (columnSchema) {
columnSchema.defaultOp = 'IN';
}
//factory.lookup('birthState').opMenu = ['>', '<'];
return factory.schema;
}
var customSchema = [
{ name: 'last_name', type: 'number', opMenu: ['=', '<', '>'], opMustBeInMenu: true },
{ name: 'total_number_of_pets_owned', type: 'number' },
{ name: 'height', type: 'number' },
'birthDate',
'birthState',
'employed',
{ name: 'income', type: 'number' },
{ name: 'travel', type: 'number' }
];
var peopleSchema = customSchema; // or try setting to derivedPeopleSchema
var gridOptions = {
data: people1,
schema: peopleSchema,
margin: { bottom: '17px' }
},
grid = window.g = new Hypergrid('div#json-example', gridOptions),
behavior = window.b = grid.behavior,
dataModel = window.m = behavior.dataModel,
idx = behavior.columnEnum;
console.log('Fields:'); console.dir(behavior.dataModel.getFields());
console.log('Headers:'); console.dir(behavior.dataModel.getHeaders());
console.log('Indexes:'); console.dir(idx);
var treeView, dataset;
function setData(data, options) {
options = options || {};
if (data === people1 || data === people2) {
options.schema = peopleSchema;
}
dataset = data;
behavior.setData(data, options);
idx = behavior.columnEnum;
}
// Preset a default dialog options object. Used by call to toggleDialog('ColumnPicker') from features/ColumnPicker.js and by toggleDialog() defined herein.
grid.setDialogOptions({
//container: document.getElementById('dialog-container'),
settings: false
});
// add a column filter subexpression containing a single condition purely for demo purposes
if (false) { // eslint-disable-line no-constant-condition
grid.getGlobalFilter().columnFilters.add({
children: [{
column: 'total_number_of_pets_owned',
operator: '=',
operand: '3'
}],
type: 'columnFilter'
});
}
window.vent = false;
//functions for showing the grouping/rollup capabilities
var rollups = window.fin.Hypergrid.analytics.util.aggregations,
aggregates = {
totalPets: rollups.sum(2),
averagePets: rollups.avg(2),
maxPets: rollups.max(2),
minPets: rollups.min(2),
firstPet: rollups.first(2),
lastPet: rollups.last(2),
stdDevPets: rollups.stddev(2)
},
groups = [idx.BIRTH_STATE, idx.LAST_NAME, idx.FIRST_NAME];
var aggView, aggViewOn = false, doAggregates = false;
function toggleAggregates() {
if (!aggView){
aggView = new AggView(grid, {});
aggView.setPipeline({ includeSorter: true, includeFilter: true });
}
if (this.checked) {
grid.setAggregateGroups(aggregates, groups);
aggViewOn = true;
} else {
grid.setAggregateGroups([], []);
aggViewOn = false;
}
}
function toggleTreeview() {
if (this.checked) {
treeView = new TreeView(grid, { treeColumn: 'State' });
treeView.setPipeline({ includeSorter: true, includeFilter: true });
treeView.setRelation(true, true);
} else {
treeView.setRelation(false);
treeView = undefined;
delete dataModel.pipeline; // restore original (shared) pipeline
behavior.setData(); // reset with original pipeline
}
}
var groupView, groupViewOn = false;
function toggleGrouping(){
if (!groupView){
groupView = new GroupView(grid, {});
groupView.setPipeline({ includeSorter: true, includeFilter: true });
}
if (this.checked){
grid.setGroups(groups);
groupViewOn = true;
} else {
grid.setGroups([]);
groupViewOn = false;
}
}
you may try:
(rollups.sum(11)).toFixed(2)
enclosing number in parentheses seems to make browser bypass the limit that identifier cannot start immediately after numeric literal
edited #2:
//all formatting and rendering per cell can be overridden in here
dataModel.getCell = function(config, rendererName) {
if(aggViewOn)
{
if(config.columnName == "total_pets")
{
if(typeof(config.value) == 'number')
{
config.value = config.value.toFixed(2);
}
else if(config.value && config.value.length == 3 && typeof(config.value[1]) == 'number')
{
config.value = config.value[1].toFixed(2);
}
}
}
return grid.cellRenderers.get(rendererName);
};
Consider this as my json data.
I want to filter the "gridValues" in the data using value "LAN". I have used Ext js filter method. It doesn't return the filter data.
var tableData = [
{
"TABLE_TITLE": "Details",
"tableColumns": {
"COLUMNNAME_0": "Interface",
"COLUMNNAME_1": "Conversation",
"COLUMNNAME_2": "Data Flow(KB)"
},
"gridValues": [
{
"COLUMVal_0": "LAN",
"COLUMVal_1": "192.168.9.113 to 61.16.173.233",
"COLUMVal_2": "1132.7"
},
{
"COLUMVal_0": "TATA",
"COLUMVal_1": "192.168.8.67 to 111.221.115.98",
"COLUMVal_2": "619.72"
},
{
"COLUMVal_0": "CITI",
"COLUMVal_1": "192.168.8.60 to 23.6.112.201",
"COLUMVal_2": "619.2"
}
]
}
];
I used the following code for filtering data:
var arry =[];
var fliterarry =[];
var i,u;
for (i=0;i<tableData.length;i++) {
arry.push(tableData[i].gridValues);
}
var arryFtr = arry.filter(function(e){
for (u=0;u<e.length;u++) {
if(e[u].COLUMVal_0 === 'TATA'){
tableData[u].gridValues.push(e[u]);
}
return e[u].COLUMVal_0 == 'TATA';
}
return fliterarry
});
I guess you want to filter data with COLUMVal_0 equals "TATA" , right ?
Try following codes in your function :
var filterArray = [];
for ( tdKey in tableData ) {
for ( gvKey in tableData[tdKey].gridValues ) {
if ( tableData[tdKey].gridValues[gvKey].COLUMVal_0 == "TATA" ) {
filterArray.push(tableData[tdKey].gridValues[gvKey]);
}
}
}
return fliterarry;
This is my first question on here. Doesn't appear to be asked elsewhere, but then again I'm not sure exactly how to phrase my question.
How can I transform an array that looks like this:
var message = {
pay_key: '12345',
'transaction[0].sender_id': 'abc',
'transaction[0].is_primary_receiver': 'false',
'transaction[0].id': 'def',
'transaction[1].sender_id': 'xyz',
'transaction[1].is_primary_receiver': 'false',
'transaction[1].id': 'tuv',
};
into something like this:
{
pay_key : '12345',
transaction : [
{
sender_id : 'abc',
is_primary_receiver : 'false',
id : 'def'
},
{
sender_id : 'xyz',
is_primary_receiver : 'false',
id : 'tuv'
}
]
}
I have no control over the format of the first object as it comes from an external service. I am trying to insert the message object into a MongoDB collection, but when I try to do an insert as-is, I get an error. So I'm trying to put it into the correct form.
Should I be using Underscore for this? I've played around with _.each but can't get it to work.
my take..
var message = {
pay_key: '12345',
'transaction[0].sender_id': 'abc',
'transaction[0].is_primary_receiver': 'false',
'transaction[0].id': 'def',
'transaction[1].sender_id': 'xyz',
'transaction[1].is_primary_receiver': 'false',
'transaction[1].id': 'tuv',
};
message.transaction=[];
for (var p in message) {
var m = p.match(/^transaction\[(\d+)\]\.(.*)/);
if (m&&m[1]&&m[2]) {
message.transaction[m[1]]=message.transaction[m[1]]||{};
message.transaction[m[1]][m[2]]=message[p];
delete message[p];
}
}
Here's a generic function I just whipped up
function makeObject(message) {
var retObj = {},
makePath = function (p, pos) {
if (/\[\d+\]$/.test(p)) {
var q = p.split(/[\[\]]/),
r = q[0],
s = q[1];
if (!pos[r]) {
pos[r] = [];
}
return pos[r][s] = pos[r][s] || {};
}
return pos[p] = pos[p] || {};
};
for(var k in message) {
if (message.hasOwnProperty(k)) {
if (k.indexOf('.') < 0) {
retObj[k] = message[k];
}
else {
var path = k.split('.'),
pos = retObj,
last = path.pop();
path.forEach(function(p) {
pos = makePath(p, pos);
});
pos[last] = message[k];
}
}
}
return retObj;
}
It works as required, but I'm sure there's some better code to do it
Had a similar response, so adding it anyway:
Object.keys(message).forEach(function(key) {
var keySplit = key.split( /\[|\]\./g )
if ( keySplit.length != 1 ) {
if ( !message.hasOwnProperty(keySplit[0]) )
message[keySplit[0]] = [];
message[keySplit[0]][keySplit[1]] = message[keySplit[0]][keySplit[1]]||{};
message[keySplit[0]][keySplit[1]][keySplit[2]] = message[key];
delete message[key];
}
});