Reputation: 3550
In the snippet below, before return(res)
, I log it, and it's not undefined
but somehow, it's being returned as undefined
.
What am I doing wrong?
filterData = (inputData, searchedKey) => {
inputData.forEach((data, index) => {
if(data){
if(data.hasOwnProperty(searchedKey)){
const res = data[searchedKey]
console.log(res) /// logs the results
return(res) /// returns undefined
}
var dataToProcess = [];
var fieldKeys = Object.keys(data)
fieldKeys = fieldKeys.filter((field, index) => !field.includes("#"))
fieldKeys.forEach((key, index) => {
dataToProcess.push(data[key]);
})
this.filterData(dataToProcess, searchedKey)
}
})
}
console.log(this.filterData([{"#name": "foo", "#type": "bar"}], "#type"))
Upvotes: 1
Views: 77
Reputation: 350272
Some issues:
forEach
does not return anything else than undefined
, so returning a value in its callback function does not do anything useful.if (data)
is not good enough to make sure data
is an object. For instance, it would also be true for a non-zero number. Use Object(data) === data
instead.filter
method returns an array. So it would be in line with that.Here is how you could make it work:
var filterData = (inputData, searchedKey) => {
inputData = inputData.filter( data => Object(data) === data );
return !inputData.length ? [] :
inputData.filter( data => data.hasOwnProperty(searchedKey) )
.map( data => data[searchedKey] )
// Add the results from recursion:
.concat(filterData([].concat(...
inputData.map( data =>
Object.keys(data)
.filter( key => !key.startsWith("#") )
.map( key => data[key] )
)
), searchedKey));
};
var data = [{
"#name": "foo",
"#title": "mr",
"deeper": [{
"#nope": "bad",
"deepest": [{
"nothing_here": null,
"#type": "deeper bar",
}]
}, {
"#type": "bar",
}]
}];
console.log(filterData(data, "#type"));
If you need only the first match, then use this variant:
var filterData = (inputData, searchedKey) => {
inputData = inputData.filter( data => Object(data) === data );
var res = inputData.find( data => data.hasOwnProperty(searchedKey) );
return res !== undefined ? res[searchedKey] :
// Try in nested objects:
filterData([].concat(...
inputData.map( data =>
Object.keys(data)
.filter( key => !key.startsWith("#") )
.map( key => data[key] )
)
), searchedKey);
};
var data = [{
"#name": "foo",
"#title": "mr",
"deeper": [{
"#nope": "bad",
"deepest": [{
"nothing_here": null,
"#type": "deeper bar",
}]
}, {
"#type": "bar",
}]
}];
console.log(filterData(data, "#type"));
Upvotes: 1
Reputation: 7285
Is this what you want to achieve?
filterData = (inputData, searchedKey) => {
return inputData.map((data, index) => {
if(data){
if(data.hasOwnProperty(searchedKey)){
const res = data[searchedKey]
console.log(res) /// logs the results
return(res) /// returns undefined
}
var dataToProcess = [];
var fieldKeys = Object.keys(data)
fieldKeys = fieldKeys.filter((field, index) => !field.includes("#"))
fieldKeys.forEach((key, index) => {
dataToProcess.push(data[key]);
})
this.filterData(dataToProcess, searchedKey)
}
})
}
console.log(this.filterData([{"#name": "foo", "#type": "bar"}], "#type"))
Use Array#map()
, it's pretty useful in many cases.
Upvotes: 0