How to access object properties of 'key' object reactJS - javascript

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>

Related

Add dynamic key to set state, react

I have this state
this.state = {
dropdown1: false,
dropdown2: false,
dropdown3: false
}
I want to access to these dropdowns in state using this.setState but the number after 'dropdown' comes from API
onMaca = (ev) => {
this.setState({
dropdown + ev: true
})
}
So I want the key to be dynamic 'dropdown1' for example.
Thanks for your answers
you can access the object property like this object['property name']
onMaca = (ev) => {
this.state['dropdown' + ev]= true;
this.setState({
...this.state
})
}
https://codezup.com/add-dynamic-key-to-object-property-in-javascript/
You can use any of these to set key dynamically. I will try to update the answer with an example in a while for setState.
The state is a JS object, so you can get its keys as usual, like so:
const stateKeys = this.state.keys()
Now you have an array: [ "dropdown1", "dropdown1", "dropdown1" ]
One way to use it would be:
const keysMap = statekeys.map(( item, i ) => return {
key: item,
idx: i,
number: item.replace( /dropdown/, '' )
}
keysMap will look like so: [ { key: 'dropdown1', idx: 0, number "1" }, { key: 'dropdown1', idx: 1, number "2" }, { key: 'dropdown1', idx: 2, number "3" } ]
You can query keysMap for a given dropDownNumber like so:
let k = keysMap.find( kmap => kmap.key = dropDownNumber )
To set the dropdown's state:
this.setState({ k: <whatever> })

Not able to update the array of objects where there is another array inside the same object

"departureList": [
{
"fixDiscount":5.0,
"endDate":"2021-08-25",
"seatLeft":20,
"addOn":[
{
"unit":1,
"price":33.0,
"name":"addone 1",
"addonId":"5e826530-33c1-4300-ac0d-5ca85b2b2dbc"
}
],
"totalPeople":1,
"cartId":"ebc40f12-8963-49c8-b624-173a4f1d0d39",
"departureCartId":"84005195-e09a-46df-99a6-3d92a42c3b8f",
}
]
I have array of objects inside departurelist. Inside that i have another array of objects names addOn. I can change departure list data and update
like :
export const departureDatasChange = (departureData) => {
async (dispatch, getState) => {
const { getCartData } = getState().cart;
let departureList = getCartData.departureList;
departureList = departureList.map((item) => {
return item.departureCartId === departureData.departureCartId
? departureData
: item;
});
but I am not able to change the addon data and map to the same departure list object.
I don’t care what you wanna reach.
My guess is you want to add item.addon to departureData.addOn.
return item.departureCartId === departureData.departureCartId
? {…departureData, addOn: item.addOn}
: item;
});

Displaying dynamic data from object

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).

Converting an array of objects into a matrix in JavaScript?

I have an array of objects like this:
"result": [
{
"UserGroupName": "TestCronGroup2",
"CourseTitle": "Test Publish Course 1",
"ComplianceStatus": false
},
{
"UserGroupName": "TestCronGroup2",
"CourseTitle": "test456",
"ComplianceStatus": null
},
{
"UserGroupName": "TestCronGroup2",
"CourseTitle": "retest456",
"ComplianceStatus": null
},
{
"UserGroupName": "TestCronGroup1",
"CourseTitle": "Test Publish Course 1",
"ComplianceStatus": false
},
And I want it to convert it in a matrix form like this:
Compliance Report Matrix
This is my code so far. I am unable to link the values in matrix properly:
showItems = (columns: any) => {
var columnsArr = new Array();
columnsArr = [
{
title: "Course",
field: "CourseTitle",
},
];
Object.keys(this.props.complianceReport).forEach((key, index) => {
var columnsObj = {
title: this.props.complianceReport[key].UserGroupName,
};
columnsArr.push(columnsObj);
});
return (
<div>
<ReportsTable
columns={columnsArr}
tableData={this.props.complianceReport}
/>
</div>
);
};
What I am able to achieve so far:
My Matrix so far
I am new to react and javascript so any kind of help will be appreciated. Thanks!
There are few things you should start to prepare data for react-table output. First thing is to create array of all the columns (course and unique usergroups) and second array of the unique courses.
// prep columns (usergroups unique)
// use Set to aviod duplicates
let userGroups = new Set();
result.forEach(item => userGroups.add(item.UserGroupName));
let columns = Array.from(userGroups)
.sort()
.map(item => {
return {
Header: item,
accessor: item
};
});
// add column: Courses in front
columns.unshift({ Header: "Courses", accessor: "courses" });
// prep courses (unique)
let courseTitles = new Set();
result.forEach(item => courseTitles.add(item.CourseTitle));
const courseTitlesItems = Array.from(courseTitles).sort();
When you have both of these you can iterate through all the courses and check if it is available for specific usergroup.
// prep data
let data = courseTitlesItems.map(courseItem => {
return {
...columns.reduce(
(o, column) =>
Object.assign(o, {
[column.accessor]: testCourse(result, courseItem, column)
}),
{}
),
courses: courseItem
};
});
Use this function to test for data.
function testCourse(result, courseItem, column) {
const foundItem = result.find(
resultItem =>
resultItem.CourseTitle === courseItem &&
resultItem.UserGroupName === column.accessor
);
return foundItem === undefined || foundItem.ComplianceStatus === null
? "-"
: foundItem.ComplianceStatus === false
? "No"
: "Yes";
}
Demo and the playground I used to solve your quiz. Hope you will find it useful!
https://codesandbox.io/s/react-table-vr0ky?file=/src/App.js

React setstate nested object issue

I am not able to solve this setState second night and I'm already desperate. I have heavily nested object which I'm trying to update. In case I have multiple elements in todaysMenu and I'm trying to update state for second element whole array gets "stored" in first element of todaysMenu.
onChangeAnyValue(values, itemIndex) {
const key = Object.keys(values.x)[0];
const provideDate = values.date;
this.setState(prevState => ({
data: prevState.data.map(day => day.date === provideDate ? {
...day,
todaysMenu: [{
...day.todaysMenu,
[itemIndex]: {
...day.todaysMenu[itemIndex],
dish: {
...day.todaysMenu[itemIndex].dish,
[key]: values.x[key]
}
}
}]
} : day)
}));
}
In case I remove square brackets its stored as just objects.
Thank you for your time!
You'll want to change:
todaysMenu: [{
...day.todaysMenu,
[itemIndex]: {
...day.todaysMenu[itemIndex],
dish: {
...day.todaysMenu[itemIndex].dish,
[key]: values.x[key]
}
}
}]
...to:
todaysMenu: day.todaysMenu.map((item, index) =>
index === itemIndex
? { ...item, dish: { ...item.dish, [key]: values.x[key] } }
: item
)
What you currently have is creating an Array with one object instead of converting an Array to a modified Array.

Categories

Resources