How to map the following to react state as expected result - reactjs

Json data as follows
const data=
{
"id":1,
"title":"Test title",
"results":[
{
"rowId":1,
"records":[
{
"attribute":"Id",
"value":"id1"
},
{
"attribute":"title",
"value":"Perform data"
}
]
},
{
"rowId":2,
"records":[
{
"attribute":"Id",
"value":"id2"
},
{
"attribute":"title",
"value":"Test data"
}
]
}
]
}
Expected:
0:Id: "id1",
title:"Perform data"
1:Id: "id2",
title:"Test data"

Map the data results to new objects accessing the records array to be reduced to an object with correct mapped keys.
data.results.map(({ records }) =>
records.reduce(
(obj, { attribute, value }) => ({
...obj,
[attribute]: value
}),
{}
)
);
const data = {
id: 1,
title: "Test title",
results: [
{
rowId: 1,
records: [
{
attribute: "Id",
value: "id1"
},
{
attribute: "title",
value: "Perform data"
}
]
},
{
rowId: 2,
records: [
{
attribute: "Id",
value: "id2"
},
{
attribute: "title",
value: "Test data"
}
]
}
]
};
const result = data.results.map(({ records }) =>
records.reduce(
(obj, { attribute, value }) => ({
...obj,
[attribute]: value
}),
{}
)
);
console.log(result);

Related

REACT: Updating nested state

I have two sets of data. Both are saved in a states.I want to update the rowsData inside the data1 state based on the values in data2 state. The "row" value in the data2 object refers to the "id" of rowsData in the data1 state and columns in the data2 refers to any data beside id in the rowsData object in data1. I want to pick "row" and "column" from data2 and cahnge the respective data inside rowsData in data1.
let tableData = {
columnsDef: [
{ title: "id",field: "id",className: "header-style" },
{ title: "First_name", field: "First_name", className: "header-style" },
{ title: "Last_name", field: "Last_name", className: "header-style" },
{ title: "Email", field: "Email", className: "header-style" },
],
rowsData:[
{ id: "1", First_name: "Donald", Last_name: "OConnell", Email: "DOCONNEL" },
{ id: "2", First_name: "Douglas", Last_name: "Grant", Email: "DGRANT" },
{ id: "3", First_name: "Jennifer", Last_name: "Whalen", Email: "JWHALEN" },
{ id: "4", First_name: "Michael", Last_name: "Hartstein", Email: "MHARTSTE" },
{ id: "5", First_name: "Pat", Last_name: "Fay", Email: "PFAY" },
{ id: "6", First_name: "Susan", Last_name: "Mavris", Email: "SMAVRIS" },
{ id: "7", First_name: "Hermann", Last_name: "Baer", Email: "HBAER" }
],
file: [
{ file: { path: "dummy_data_3 .csv"}}
],
}
let updatedTableData = [
{ "row": 2, "column": "Email", "oldValue": "DGRANT", "newValue": "DGRANT UPDATED" },
{ "row": 6, "column": "First_name", "oldValue": "Susan", "newValue": "SUSAN UPDATED" },
{ "row": 4, "column": "Last_name", "oldValue": "Hartstein", "newValue": "Hartstein UPDATED" }
]
const [data1, setData1] = useState(tableData)
const [data2, setData2] = useState(updatedTableData)
Here is the codesandbox link for the issue.
https://codesandbox.io/s/reverent-firefly-r87huj?file=/src/App.js
You can follow these steps for updating data1 from handleAppyChanges function:
Create a copy of rowsData:
const td = [...data1.rowsData];
Iterate over data2 and find related item, then update its related column:
data2.forEach((item) => {
let row = data1.rowsData.find((r) => r.id === item.row);
if (row) {
let index = data1.rowsData.findIndex((v) => v === row);
row[item.column] = item.newValue;
td[index] = row;
}
});
Update table data via state:
const newData = {
file: data1.file,
rowsData: td,
columnDef: data1.columnsDef
};
setData1(newData);
Here's the full function:
const handleAppyChanges = () => {
const td = [...data1.rowsData];
data2.forEach((item) => {
let row = data1.rowsData.find((r) => r.id === item.row);
if (row) {
let index = data1.rowsData.findIndex((v) => v === row);
row[item.column] = item.newValue;
td[index] = row;
}
});
const newData = {
file: data1.file,
rowsData: td,
columnDef: data1.columnsDef
};
setData1(newData);
console.log("Updated Data 1: ", td);
};
You can access the full code via codesandbox:
Apply into onChange and check it.
const handleAppyChanges = () => {
data2.map((item) => {
data1.rowsData.map((data) => {
//match both id and row
if (data.id == item.row) {
//check column is there or not
let column = data.hasOwnProperty(item.column);
if (column) {
//if yes then change the value
data[item.column] = item.newValue;
}
}
});
});
setData1({ ...data1 });
};

Why can't I push in <option> when I get the 'response.data'?

Why can't I push in my <option> when I get the response.data?
type State = {
companyManagerMap: null | Map<string, string[]>
}
useEffect(() => {
AdminListManager()
.then((response) => {
const { data } = response.data
console.log( { data });
setState((s) => ({
...s,
companyManagerMap: new Map(
Object.keys(data).map((key) => [key, data[key]])
),
}))
})
.catch(showUnexpectedError)
}, [showUnexpectedError])
data format
{"total":2,"data":[{"id":1,"name":"newspeed","contains_fields":[{"id":1,"name":"Official"}]},{"id":2,"name":"YAMAHA","contains_fields":[{"id":3,"name":"US"}]}]}
You are using your .map and Object.keys wrong
Look here at where you iterate over your Object keys properly :)
const data = {
total: 2,
data: [
{ id: 1, name: 'newspeed', contains_fields: [{ id: 1, name: 'Official' }] },
{ id: 2, name: 'YAMAHA', contains_fields: [{ id: 3, name: 'US' }] },
],
};
//now iterate over it properly
data.data.map((item) => {
Object.keys(item).map((key) => {
console.log(item[key]);
});
});
console.log will return this output
1
newspeed
[ { id: 1, name: 'Official' } ]
2
YAMAHA
[ { id: 3, name: 'US' } ]
I'm guessing you want to add the new data from your res.data to a state
So you can do something like this:
const fetchData = async () => {
try {
const res = await AdminListManager()
//do data manipulation over objects and set new state
} catch (error) {
showUnexpectedError()
}
}
useEffect(()=> {
fetchData()
}, [showUnexpectedError])

Adding object in Array in nested object with setState

I'd like to know how to add an object in datasets,
I'm trying to add an object in array with using setState,
but It doesn't work at all .
my code is like this :
const [DataContext, setDataContext] = useState([
{
labels: defaultLabels,
datasets: [
{
label: "dataSetting",
data: defaultDatas,
backgroundColor: defaultBackgroundColor,
},
],
},
{
labels: defaultLabels,
datasets: [
{
label: "dataSetting",
data: defaultDatas,
backgroundColor: defaultBackgroundColor,
},
],
},
{
labels: defaultLabels,
datasets: [
{
label: "dataSetting",
data: defaultDatas,
backgroundColor: defaultBackgroundColor,
},
],
},
const addAxis = index => {
let addAxis = [...DataContext];
addAxis[index].datasets.push({ label: "", data: "", background: "" });
setDataContext(addAxis);
};
You need a deep copy to update the state:
const addAxis = index => {
setDataContext(dataContext => dataContext.map((data, idx) => {
return idx === index ? {
...data,
datasets: [...data.datasets, { label: "", data: "", background: "" }]
} : data
})
};
You need to deep copy DataContext.
const _copy = (value) => {
let object;
if (Array.isArray(value)) {
object = [];
value.forEach((item, index) => {
if (typeof value[index] === 'object') {
object[index] = _copy(value[index]);
} else {
object[index] = value[index];
}
});
} else {
object = {};
for (let key in value) {
if (typeof value[key] === 'object') {
object[key] = _copy(value[key]);
} else {
object[key] = value[key];
}
}
}
return object;
};
const addAxis = index => {
let addAxis = _copy(DataContext);
addAxis[index].datasets.push({ label: "", data: "", background: "" });
setDataContext(addAxis);
};

I want to create checkbox checked in nested data in react js

My data is in nested array objects. I want to make checked/unchecked the nodes like a tree view. ie. when any child node is selected then the parent node is checked itself.
This is my nested JSON. From this object, I create a tree view from this data:
const nodes = [
{
value: "/app",
label: "app",
children: [
{
value: "/app/Http",
label: "Http",
children: [
{
value: "/app/Http/Controllers",
label: "Controllers",
children: [
{
value: "/app/Http/Controllers/WelcomeController.js",
label: "WelcomeController.js",
},
],
},
{
value: "/app/Http/routes.js",
label: "routes.js",
},
],
},
{
value: "/app/Providers",
label: "Providers",
children: [
{
value: "/app/Http/Providers/EventServiceProvider.js",
label: "EventServiceProvider.js",
},
],
},
],
},
{
value: "/config",
label: "config",
children: [
{
value: "/config/app.js",
label: "app.js",
},
{
value: "/config/database.js",
label: "database.js",
},
],
},
{
value: "/public",
label: "public",
children: [
{
value: "/public/assets/",
label: "assets",
children: [
{
value: "/public/assets/style.css",
label: "style.css",
},
],
},
{
value: "/public/index.html",
label: "index.html",
},
],
},
{
value: "/.env",
label: ".env",
},
{
value: "/.gitignore",
label: ".gitignore",
},
{
value: "/README.md",
label: "README.md",
},
];
I am using this function to make parent checked when child is checked.
checkChange(targetNode: any, event) {
/// debugger;
const targetNodeId = targetNode.id;
this.findIndexNestedforCheckbox(targetNode, targetNodeId);
let newTableData = [...this.state.tableData];
this.setState({ tableData: newTableData, isActionFooter: true });
}
findIndexNestedforCheckbox(data, index) {
if (data.id === index) data.isChecked = "Yes";
let result;
const i = (data.children || []).findIndex((child) => {
child.isChecked = "Yes";
return (result = this.findIndexNestedforCheckbox(child, index));
});
if (result) return [i, ...result];
}
npm install react-checkbox-tree
import React from 'react';
import CheckboxTree from 'react-checkbox-tree';
const nodes = [{
value: 'mars',
label: 'Mars',
children: [
{ value: 'phobos', label: 'Phobos' },
{ value: 'deimos', label: 'Deimos' },
],
}];
class Widget extends React.Component {
state = {
checked: [],
expanded: [],
};
render() {
return (
<CheckboxTree
nodes={nodes}
checked={this.state.checked}
expanded={this.state.expanded}
onCheck={checked => this.setState({ checked })}
onExpand={expanded => this.setState({ expanded })}
/>
);
}
}

Export Google Chart to Excel Sheet in Angular

Im using ng-google-chart to create charts from data I receive from a database. I store the data in a table. I need to export both the table and the chart.
I'm using the following technique to export tables (where "exportable" is the div the contains the table):
$scope.export = function ()
{
var blob = new Blob([document.getElementById('exportable').innerHTML], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
});
saveAs(blob, "Record.xls");
alert("export done");
};
I cannot find any way to add the chart to this file.
This is the code to generate a chart
var chart1 = {};
chart1.type = "ColumnChart";
chart1.cssStyle = "height:400px; width:500px;";
chart1.data = {
"cols": [
{ id: "gender", label: "Gender", type: "string" },
{ id: "number", label: "number", type: "number" }
], "rows": [
{
c: [
{ v: "male" },
{ v: $scope.male, f: $scope.male }
]
},
{
c: [
{ v: "female" },
{ v: $scope.female }
]
}
]
};
chart1.options = {
"title": "",
"isStacked": "true",
"fill": 20,
"displayExactValues": true,
"vAxis": {
"title": "Number", "gridlines": { "count": 6 }
},
"hAxis": {
"title": "gender"
}
};
chart1.formatters = {};
$scope.chart = chart1;
}
To getImageURI of the chart, wait for the ready event and call the function.
Then you can add the image somewhere on the page.
You can even hide the original chart if needed...
Following is an example of loading the image URI into another element.
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
function drawChart() {
var data = google.visualization.arrayToDataTable([
["Element", "Density", { role: "style" } ],
["Copper", 8.94, "#b87333"],
["Silver", 10.49, "silver"],
["Gold", 19.30, "gold"],
["Platinum", 21.45, "color: #e5e4e2"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2]);
var options = {
title: "Density of Precious Metals, in g/cm^3",
width: 600,
height: 400,
bar: {groupWidth: "95%"},
legend: { position: "none" },
};
var chart = new google.visualization.ColumnChart(document.getElementById("chart_div"));
google.visualization.events.addListener(chart, 'ready', function () {
document.getElementById("chart_image").insertAdjacentHTML('beforeEnd', '<img alt="Chart Image" src="' + chart.getImageURI() + '">');
});
chart.draw(view, options);
}
<script src="https://www.google.com/jsapi"></script>
<span>CHART</span>
<div id="chart_div"></div>
<br/>
<span>IMAGE</span>
<div id="chart_image"></div>

Resources