'How do I compare 2 arrays in React render?
I am creating a dashboard in React, of which I am rendering data from JSON files to a table.
I want to compare the values from both JSON files and conditional render a className based on whether the values match or not.
The 2 JSON files are as follows:
test.json
{
"applications": {
"app1": {
"version": "8.0.2"
},
"app2": {
"version": "8.0.26"
},
"app3": {
"version": "N/A"
}
}
}
goldenTest.json:
{
"applications": {
"app1": {
"version": "10.0.0"
},
"app2": {
"version": "8.0.26"
},
"app3": {
"version": "N/A"
}
}
}
The goldenTemplate.json file contains the expected version of the applications. The test.json file contains the actual versions.
I want to check to see if the versions inside of test.json match goldenTemplate.json, if they do leave the table cell the same, but if they don't I want to render the table cell background red.
So far I have managed to render all data to the dashboard by adding the JSON contents to an array and using .map() to iterate over the files.
test.js:
import React, { Component } from "react";
import test from './test.json';
import golden from './goldenTest.json';
class Test extends Component {
constructor(props) {
super(props);
this.state = {
"test": test,
"golden": golden
}
}
render() {
const { test, golden } = this.state;
const goldenData = [golden];
const testData = [test];
const goldenSite = Object.keys(golden.applications);
const testSite = Object.keys(test.applications);
const allKeysArray = [...new Set([...goldenSite, ...testSite])];
const allKeysSorted = allKeysArray.sort();
return (
<div className="container-fluid">
<div className="row justify-content-center">
<div className="col-12">
<p className="display-4 text-center mb-3">Test Data</p>
<table className="table table-hover table-responsive" id="all-data-table">
<thead className="sticky-top bg-white">
<tr>
<th scope="col">Application Name</th>
<th scope="col">Golden Version</th>
<th scope="col">Test Version</th>
</tr>
</thead>
<tbody>
{allKeysSorted.map((k) => (
<tr>
<td>{k}</td>
{goldenData.map((g) => (
<td>{g.applications[k] && g.applications[k]["version"] ? g.applications[k]["version"] : "Not Present"}</td>
))}
{testData.map((t) => (
<td>{t.applications[k] && t.applications[k]["version"] ? t.applications[k]["version"] : "NULL"}</td>
))}
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
)
}
}
export default Test;
I know I need to add something like className={t.applications["version"] !== g.applications["version"] ? "text-danger" : ""} but I can't figure out how to .map() 2 arrays at the same time.
Any help would be appreciative.
Solution 1:[1]
i have just quickly came up with this portion of code... of course you would need to adjust output to your needs.
const colorBackgroundInRed = (test, expected) => {
if (typeof test === 'object') {
for (const key of Object.keys(test)) {
const exist = expected[key];
if (!exist) {
return { colorBg: true, diff: `${key} does not exist in expected json` };
}
console.log( test[key], exist);
const res = colorBackgroundInRed(test[key], exist);
if (res.colorBg) {
return res;
}
}
}
if (typeof test === 'string') {
if (test !== expected) {
return {
colorBg: true,
diff: `value of test json ${test} does not match with expected: ${expected}`,
};
}
}
return {
colorBg: false,
diff: `none`,
};
};
const test = {
applications: {
app1: {
version: '8.0.2',
},
app2: {
version: '8.0.26',
},
app3: {
version: 'N/A',
},
},
};
const expected = {
applications: {
app1: {
version: '10.0.0',
},
app2: {
version: '8.0.26',
},
app3: {
version: 'N/A',
},
},
};
const colorBackgroundInRed = (test, expected) => {
if (typeof test === 'object') {
for (const key of Object.keys(test)) {
const exist = expected[key];
if (!exist) {
return { colorBg: true, diff: `${key} does not exist in expected json` };
}
console.log(test[key], exist);
const res = colorBackgroundInRed(test[key], exist);
if (res.colorBg) {
return res;
}
}
}
if (typeof test === 'string') {
if (test !== expected) {
return {
colorBg: true,
diff: `value of test json ${test} does not match with expected: ${expected}`,
};
}
}
return {
colorBg: false,
diff: `none`,
};
};
const result = colorBackgroundInRed(test, expected);
console.log('color me ', result.colorBg, ' because of - ', result.diff);
Solution 2:[2]
I figured it out.
I was able to .map() inside of the className property and it gave me the expected output.
<td className={goldenSites.map((gs) => (s.applications[k] && s.applications[k]["version"] && gs.applications[k] && gs.applications[k]["version"] && gs.applications[k]["version"] !== "N/A" && s.applications[k]["version"] === gs.applications[k]["version"] ? "" : "bg-danger"))}>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Stefan Zivkovic |
| Solution 2 | ATN |
