Displaying dynamic data from object - javascript

I'm trying to display the 'helpText' data on the front end depending on the type. I's it possible to pass a conditional statement (metricsType variable) and the [key] value into what I'm trying to return. The last 'p' below gives you an idea of what I'm trying to achieve.
The key values are binary_accuracy or rmse in this example (from json file).
Appreciate any help.
const getMetrics = (model, type) => {
const metricsType = type === 'REGRESSION' ? 'regression' : 'binary';
const metrics = {
binary: {
binary_accuracy: {
helpText: 'helptext 1',
},
},
regression: {
rmse: {
helpText: 'helptext 2',
},
},
};
return Object.entries(model.test)
.filter(([key]) => key !== 'loss')
.map(([key, value]) => (
<div>
<div>
<h4>{key}</h4>
<p>{metrics.binary.binary_accuracy.helpText}</p>
// output: helptext 1
<p>{metrics.regression.rmse.helpText}</p>
// output: helptext 2
<p>{metrics.{metricsType}.[key].helpText}</p>
// this does not work but an idea of what I'm trying to do. I've tried backticks, ${}, + but no luck.
</div>
</div>
));
};
--------
return (
{getMetrics(model, i.type)}
)

What you need is probably {metrics[metricsType][key].helpText} (hard to say without knowing what's inside model).

Related

How to get the value of the key present inside an object in Javascript

Below is my sample data from which I want to extract the string present inside ResponseVariations array's object : CriterionExpression
Articles":[
"ResponseVariations":[
"CriterionExpression":"User: internal AND Country: CA"
]
]
Code Snippet:
function getChannel(agent){
const channelInfo = agent.Articles;
channelInfo.forEach((ResponseVariations) => {
if(channelInfo.values(CriterionExpression)!=="DEFAULT_SELECTION")
var iterator = channelInfo.values();
console.log(iterator.next().value);
});
But the above criteria is not fitting well to extract information of those criteria in which the String is not DEFAULT_SELECTION.
Any suggestions how to traverse this array object's value ?
The below code worked in order to fetch the key:
const _dir1 = path.resolve(__dirname, `../`);
const _config1 = JSON.parse(fs.readFileSync(path.resolve(_dir, "./export.4862052732962492282_2.json"), "utf-8"));
const filteredArr = {};
_config1.Articles.forEach(el => {
if (el.ResponseVariations && el.ResponseVariations.length > 1 ) {
el.ResponseVariations && el.ResponseVariations.forEach((rv) => {
if(rv.CriterionExpression !== 'DEFAULT_SELECTION') {
console.log('not default', rv);
filteredArr[rv.CriterionExpression]= rv.Text;
project['data']['supportedChannels'].push(filteredArr);
}
})

Issues with geting results from filter inside filters

Guys i'm trying to filter some info from this array, a piece of it:
{
"entry": [
{
"ent_seq": 1000090,
"k_ele": [
{
"keb": "○"
},
{
"keb": "〇"
}
],
"r_ele": {
"reb": "まる"
},
"sense": [
{
"pos": "&n;",
"xref": "〇〇・まるまる・1",
"gloss": "symbol used as a placeholder (either because a number of other words could be used in that position, or because of censorship)"
},
{
"pos": "&n;",
"xref": "句点",
"gloss": [
"period",
"full stop"
]
},
{
"pos": "&n;",
"xref": "半濁点",
"gloss": [
"maru mark",
"semivoiced sound",
"p-sound"
]
}
]
},
Here we have the 'sense' item, where he can be an array or not, and inside of it the 'gloss' item, an array or not as well.
To do the main search, im doing this:
export const mainSearch = async (req, res) => {
var filterData2 = teste.entry.filter(x => {
if ('sense' in x && Array.isArray(x['sense'])) {
let result = x.sense.filter(sense_item => {
if (Array.isArray(x.sense['gloss'])) {
let result2 = sense_item.gloss.includes(req.params.id)
} else if (x.sense.gloss === req.params.id) return x
})
}
if(result) return x
}
)
if (filterData2) {
console.log(filterData2)
// res.json(filterData2)
}
Where i receive the search item from req.params.id, and i already tried dozens of things, im really stucked here, for the result right now i'm getting an empty array
The aim is if i get a true response for the search, to let the 'first filter' perceive it and go checking the rest.
For the 'k_ele' and 'r_ele' my code works fine too, a piece of it:
if ('k_ele' in x && Array.isArray(x['k_ele'])) {
let result = x.k_ele.some(el =>
el.keb.includes(req.params.id)
)
if (result) return x
} else
if ('k_ele' in x && x.k_ele.keb === req.params.id) return x
I'd suggest that you change your strategy. If the data is hard to filter and loop through, then it might be a good idea to change the data to something that is easier to work with.
In the end you'd want to check if the req.params.id is found in any of the gloss arrays or strings. Therefor it might be a good idea to collect all items in the gloss items into a single array and check if the queried value is found in any of the strings.
const data = [
"symbol used as a placeholder (either because a number of other words could be used in that position, or because of censorship)",
"period",
"full stop",
"maru mark",
"semivoiced sound",
"p-sound"
]
With the data like the example above, you'd only have to evaluate if the string you're looking for is present in the array.
const isFound = data.includes(value)
const teste={"entry":[{"ent_seq":1000090,"k_ele":[{"keb":"○"},{"keb":"〇"}],"r_ele":{"reb":"まる"},"sense":[{"pos":"&n;","xref":"〇〇・まるまる・1","gloss":"symbol used as a placeholder (either because a number of other words could be used in that position, or because of censorship)"},{"pos":"&n;","xref":"句点","gloss":["period","full stop"]},{"pos":"&n;","xref":"半濁点","gloss":["maru mark","semivoiced sound","p-sound"]}]}]};
// Example search request.
var req = {
params: {
id: 'full stop'
}
}
/**
* Check if the sense property is present and is an array.
* Then return an array of all sense objects.
*/
const senseEntries = teste.entry
.filter(entry => 'sense' in entry && Array.isArray(entry.sense))
.flatMap(({
sense
}) => sense)
/**
* Loop over the filtered sense objects and return
* either the gloss array or the gloss string inside of an array.
*/
const glossEntries = senseEntries
.flatMap(({
gloss
}) => Array.isArray(gloss) ? gloss : [gloss])
console.log(glossEntries);
/**
* Now all gloss items are collected in a single array and we can check if the id is found in any of the gloss strings.
*/
const isFound = glossEntries.includes(req.params.id)
console.log(`${req.params.id} in gloss values?`, isFound);
The person that posted an answer earlier gave me some clues, but he deleted it.
About the answer, the initial state of the logic was already too messy, and it was unable to return the true or false that the first 'filter' needed, that was the main problem.
So, i just started over focusing on the 'return' part and was there that things got better, anymore than that is just improvements to the code.
if ('sense' in x && !Array.isArray(x['sense'])) {
if (Array.isArray(x.sense['gloss'])) {
return x.sense.gloss.some(el => typeof(el) == 'string' && el.includes(req.params.id))
} else return typeof(x.sense.gloss) == 'string' && x.sense.gloss.includes(req.params.id)
} else if ('sense' in x && Array.isArray(x['sense'])) {
return x.sense.some((sense_item) => {
if (Array.isArray(sense_item['gloss'])) {
return sense_item.gloss.some(el => typeof(el) == 'string' && el.includes(req.params.id))
} else return typeof(sense_item.gloss) == 'string' && sense_item.gloss.includes(req.params.id)
})
}

Converting Async Response to Standard Javascript Object

Imagine your React app gets a response like this:
email_address
first_name
last_name
What's a best practice way to convert these fields to something more common in Javascript:
emailAddress
firstName
lastName
Also keeping mind that there could be nested structures.
I've typically done this immediately when the response is received.
My colleagues seem to think it's fine to keep the snake_case syntax persist through the app.
There may be some edge cases that fail, I could not find anything on github that would do the trick but if you have any errors then please let me know.
It is assuming you only pass object literals to it, maybe you can write some tests and tell me if anything fails:
const snakeToCamel = snakeCased => {
// Use a regular expression to find the underscores + the next letter
return snakeCased.replace(/(_\w)/g, function(match) {
// Convert to upper case and ignore the first char (=the underscore)
return match.toUpperCase().substr(1);
});
};
const toCamel = object => {
if (Array.isArray(object)) {
return object.map(toCamel);
}
if (typeof object === 'object' && object !== null) {
return Object.entries(object).reduce(
(result, [key, value]) => {
result[snakeToCamel(key)] = toCamel(value);
return result;
},
{}
);
}
return object;
};
console.log(
toCamel({
arra_of_things: [
{ thing_one: null },
{ two: { sub_item: 22 } },
],
sub_one: {
sub_two: {
sub_three: {
sub_four: {
sub_four_value: 22,
},
},
},
},
})
);

outputting key value pairs that aren't null in Key Value pairs in arrays JavaScript [duplicate]

This question already has answers here:
Semicolon at end of 'if' statement
(18 answers)
Closed 4 years ago.
So inside the folders array. I want to print out the 'name' of the folders that don't have null as their size.
let folders = [
{
name:'user_name',
size: 5455,
information: ' '
},
{
name:'untitled',
size: 545343,
information: 'no description'
},
{
name:'new_user',
size: null
}
];
So i've made this code in order to get the names of the folders that don't have null as their size but when I test it, it only prints out all the arrays. I can't quite figure out what I'm doing wrong.
folders.forEach((item) => {
let info = folders.filter((f) => {
if (f.size !== null);
return item.name
})
console.log(info)
});
To achieve this, consider using Array#filter() in combination with Array#map().
First, use filter() to isolate the folder items where the size is not null:
.filter(folder => folder.size !== null)
and then use map() to transform each folder item in the filtered result, to the name of that folder:
.map(folder => folder.name)
The complete example can be seen as:
let folders = [
{
name:'user_name',
size: 5455,
information: ' '
},
{
name:'untitled',
size: 545343,
information: 'no description'
},
{
name:'new_user',
size: null
}
];
let result = folders
.filter(folder => folder.size !== null)
.map(folder => folder.name)
console.log(result)
One problem is that if (f.size !== null); should not have a trailing semicolon - that will make the test meaningless, because no matter whether it's null or not, the semicolon will mean that the line that follows will be executed regardless. Another is that filter always returns the original item in the array, if the test passes - for what you're doing, you might use filter (to filter out null sizes) followed by map (to get to the names):
let folders = [
{
name:'user_name',
size: 5455,
information: ' '
},
{
name:'untitled',
size: 545343,
information: 'no description'
},
{
name:'new_user',
size: null
}
];
console.log(
folders
.filter(({ size }) => size !== null)
.map(({ name }) => name)
);
If you wanted to achieve it in a single iteration over the array, use reduce to filter and map at the same time:
let folders = [
{
name:'user_name',
size: 5455,
information: ' '
},
{
name:'untitled',
size: 545343,
information: 'no description'
},
{
name:'new_user',
size: null
}
];
console.log(
folders.reduce((a, { name, size }) => {
if (size !== null) a.push(name);
return a;
}, [])
);

How to access object properties of 'key' object reactJS

Would like to output this JSON data
I am struggling to find a way to output this data which I am pulling from Firebase, mostly in that I do not know how to select the objects within the 'date' object. Firebase generates these keys automatically: -LMgzJGM78f0BHbPf8cc.
I am not able to output the properties of the objects named as above^ I have tried using nested for(in) loops.
Here is the code I am using currently:
To pull the data from the database
componentDidMount() {
axios.get('./tasks.json')
.then(response => {
const fetchedTasks = [];
for (let date in response.data) {
fetchedTasks.push({
...response.data[date],
date: date,
});
for (let item in response.data[date]) {
fetchedTasks.push({
...response.data[date[item]],
id: item
})
}
}
this.setState((prevState, props) => {
return {
taskList: fetchedTasks,
loading: false
}
})
})
.catch(error => console.log(error));
}
Mapping the state to a JSX element, only outputs like props.name:
{this.state.taskList.map((array, index) => (
<CompleteTask
key={array.date}
taskName={array.date}
/>
) )
}
Here is an example the data as a JSON file, it is set to the state in my app:
{
"tasks" : {
"09182018" : {
"-LMgzJGM78f0BHbPf8cc" : {
"hours" : 0,
"end" : "2018-09-18T14:02:25.022Z",
"minutes" : 0,
"name" : "sadflkjdsalkf",
"seconds" : 2,
"start" : "2018-09-18T14:02:22.508Z"
},
"-LMgzaEYe0tcCjpxOuPU" : {
"hours" : 0,
"end" : "2018-09-18T14:03:38.635Z",
"minutes" : 0,
"name" : "safd",
"seconds" : 2,
"start" : "2018-09-18T14:03:36.353Z"
}
},
}
}
The properties of the key elements -LMgzaEYe0tcCjpxOuPU I am unsure of how to access, these data are created by another part in my app, should I move to a more shallow state to output the properties of 'hours','name', mintutes etc. or is there a way to access it as it is now?
Many thanks in advance.
Are you asking how to access properties with problematic names like -LMgzJGM78f0BHbPf8cc?
If so, instead of the object.property notation, you can access object properties by the property name using the square brackets syntax:
let obj = { color: 'blue' }
let prop = 'color'
console.log(obj.color);
console.log(obj['color']);
console.log(obj[prop]);
If not, please try to make more clear what your current problem is.
I'd suggest to transform the object received from the Firebase to array in this way:
const formattedTasks = [];
const tasks = Object.values(data.tasks);
tasks.forEach(task =>
Object.entries(task).forEach(([key, value]) =>
formattedTasks.push({ name: key, data: value })
)
);
So, you'll map through formattedTasks array.
Here's a working example: https://codesandbox.io/s/l348nnkv9q
Since the keys in those objects are unknown, it may be useful to use Object.keys(). Try something like this in your JSX:
Given:
const data = {
"tasks" : {
"09182018" : {
"-LMgzJGM78f0BHbPf8cc" : {
"name" : "Task One",
},
"-LMgzaEYe0tcCjpxOuPU" : {
"name" : "Task Two",
}
},
}
};
JSX:
<ul>
{Object.keys(data.tasks).map((date) => {
const dayTasks = tasks[date];
return Object.keys(dayTasks).map((key) => {
const task = dayTasks[key];
return (
<li>{task.name}</li>
)
})
})}
</ul>
<div>
{
Object.entries(slot).map(([key, value]) =>
<div>
{console.log("key", key)}
<span>{key}</span>
<div>
{value.map(g => (
<div>{console.log("g", g.eTime)}
<span>{g.eTime}</span>
</div>
))}
</div>
</div>
)
}
</div>

Categories

Resources