This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 5 years ago.
This may be a really daft question or an impossible question..
I have a table which uses two arrays of objects like so:
const columnData = [
{ id: 'name', label: 'Name' },
{ id: 'value', label: 'Value' }
];
const rowData = [
{ name: 'Name 01', value: 100 },
{ name: 'Name 02', value: 150 },
{ name: 'Name 03', value: 200 },
];
I am writing this as a separate react component so I can reuse it and just change the two sets of data passed in as props. This is all fine and working, however I am struggling to figure out how to map the rows and columns to be dynamic.
i.e.:
...
{this.props.rowData.map(row => {
return (
<tr>
{this.props.columnData.map(column => {
return (
<td>{row.(THE_COLUMN_ID_TO_GET_THE_VALUE)}</td>
);
}
</tr>
);
}
...
I hope I make some sense here as it's a bit vague.. I basically want to get the value from rowData using the column id name. EG: <td>{row.name}</td><td>{row.value}</td> without hardcoding the item.
You can use the [] syntax on objects to obtain values based on computed properties.
{this.props.rowData.map(row => {
return (
<tr>
{this.props.columnData.map(column => {
return (
<td>{row[column.id]}</td>
);
}
</tr>
);
}
So you just want to get the property of the row that matches the column id? You can access a property with dynamic name using square brackets like row[column.id]
{this.props.rowData.map(row => {
return (
<tr>
{this.props.columnData.map(column => {
return (
<td>{row[column.id]}</td>
);
}
</tr>
);
}
Related
This question already has answers here:
How to determine if Javascript array contains an object with an attribute that equals a given value?
(27 answers)
Array.includes() to find object in array [duplicate]
(8 answers)
Javascript: Using `.includes` to find if an array of objects contains a specific object
(7 answers)
Closed 7 months ago.
Trying to add new object value in an array but not working. How to add it? If anyone knows please help to find the solution.
getting this error:
Property 'includes' does not exist on type '{ name: string; id:
string; }[]'. Do you need to change your target library? Try changing
the 'lib' compiler option to 'es2016' or later.
app.component.ts:
public a = { name: 'test1', id: '12345' };
public b = { name: 'test2', id: '12345' };
addVala() {
if (this.arr.includes(this.a)) {
console.log('This obj already there');
} else {
this.arr.push(this.a);
}
console.log(this.arr);
}
Demo : https://stackblitz.com/edit/angular-ivy-jj7sna?file=src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fapp.component.ts
You can simplify your "add" logic by passing-in the object that you want to add and checking if another object (already in the list) shares the same ID.
const arr = [
{ name: 'test1', id: 'A' },
{ name: 'test3', id: 'C' },
];
const a = { name: 'test1', id: 'A' };
const b = { name: 'test2', id: 'B' };
const add = (obj) => {
if (!arr.find(({ id }) => id === obj.id)) {
arr.push(obj);
console.log(`Added ${obj.id}`);
} else {
console.log(`Object ${obj.id} already exists!`);
}
}
function addA() { add(a); }
function addB() { add(b); }
<button onclick="addA()">Add A</button>
<button onclick="addB()">Add B</button>
This question already has answers here:
How to convert array of items to array of objects?
(2 answers)
Closed 1 year ago.
I am trying to convert an array of elements to an array of objects in Javascript (react)
Here is the data I am getting from my API
"versions": [
"1.0.1.2",
"1.0.22.0",
"1.1.0.12",
"2.5.2.6",
"2.5.2.7",
"2.7.5.11",
"2.7.7.7",
"3.9.2.94",
"3.9.3",
"5.2.0.87",
"9.5.0.210" ]
And I am trying to convert to an array of object which should look like this
options = [
{ value: "1.0.1.2", label: "1.0.1.2" },
{ value: "1.0.22.0", label: "1.0.22.0" },
{ value: "2.5.2.6", label: "2.5.2.6" },
];
I tried using the map function
versions = VersionloginData.data.versions.map((version) => [version.value, version.label])
But didn't work out well , i am getting undefined as value objects
You needed to return an object inside the map callback:
versions = VersionloginData.data.versions.map((version) => ({ value: version, label: version }))
Its should be.
const data = {
"versions": [
"1.0.1.2",
"1.0.22.0",
"1.1.0.12",
"2.5.2.6",
"2.5.2.7",
"2.7.5.11",
"2.7.7.7",
"3.9.2.94",
"3.9.3",
"5.2.0.87",
"9.5.0.210"]
}
const output = data.versions.map(item => ({ value: item, label: item }));
console.log(output);
Why your code is not working?
You are accessing incorrect nodes with [version.value, version.label]. value and label doesnot exist on version. Instead, you should return an object with keys value and label having same value.
you can try this
var options = []
versions.forEach((v)=>{
options.push({
value: v,
label: v,
})
})
In my react app, I have an array of objects data that gets render to the table. The data structure of the data that I have is in the following format:
this.state = {
inspectionViewAllRsData: [
{
INSPN_PERFORMER_CD: {label: "Contractor", value: "C"}
},
{
INSPN_RSN_CD: {label: "Initial", value: "INIT"}
},
{
INSPN_STS_CD: {label: "", value: "1000"}
}
]
}
and here's my code for the table:
<table>
<tr>
<th>Performed By</th>
<th>Inspection</th>
<th>Residence Size</th>
</tr>
{this.state.inspectionViewAllRsData.map((item, i) => (
<tr>
<td>{item.INSPN_PERFORMER_CD.label} <button id="close-btn" onClick={() => this.handleRemove(i)}>X</button></td>
<td>{item.INSPN_RSN_CD.label}</td>
<td>{item.RSDNC_SIZE_QTY.value}</td>
</tr>
))}
</table>
What I want to do is remove the selected index of an array from the state when I click on the "X" button. This is what I tried to do but it's giving me an error that row.filter is not a function
handleRemove = index => {
const newData = this.state.inspectionViewAllRsData.map(row => {
return row.filter((el, i) => i !== index);
});
console.log(newData)
this.setState({ inspectionViewAllRsData: newData });
}
Can someone please help me with my functionality? Any help would be appreciate it.
You were very close. You just tried to do too much, using map to filter on each individual element of the array - which isn't possible because these are objects, not arrays. You simple want a top-level filter. Replace the definition of newData with this and all should be fine:
const newData = this.state.inspectionViewAllRsData.filter((el, i) => i !== index);
I don't know how you managed to render this, because it seems to me that you're confusing data structures and implementations.
In particular:
{this.state.inspectionViewAllRsData.map((item, i) => (
<tr>
<td>{item.INSPN_PERFORMER_CD.label} <button id="close-btn" onClick={() => this.handleRemove(i)}>X</button></td>
<td>{item.INSPN_RSN_CD.label}</td>
<td>{item.RSDNC_SIZE_QTY.value}</td>
</tr>
))}
Every item is something like:
{
property: {label: "string", value: "string"}
}
So you basically have an array of 3 elements which are Object type and you're trying to render them all when just one of them is selected by the map function.
I guess you meant to have an array of objects (Object[]) in which every single Object has 3 properties, so your "hard-coded" data should look like this:
inspectionViewAllRsData = [
{
INSPN_PERFORMER_CD: {label: "Contractor", value: "C"},
INSPN_RSN_CD: {label: "Initial", value: "INIT"},
INSPN_STS_CD: {label: "", value: "1000"}
},
// Other Objects with this structure
]
I hope what I wrote is clear enough and that I guessed your intentions right, if not, please tell me and I'll edit my answer.
EDIT
I think you should parse your input in a more easy to read/work with data structure.
This is my attempt and I'll try to explain my thought process.
In your state you should add another empty array:
this.state= {
inspectionBlaBlah: //your initial data structure,
newDataArray: []
}
In your constructor you should add an Object that will be useful to reorganize your data:
let toFillWithProperties = {};
After that u should do something like this:
inspectionViewAllRsData.map(
// Cycle through your initial array
(item, i) => {
// Cycle through the properties of every item of your array
return Object.keys(item).map(
(property, j) => {
// Create the same key/value for each property in your new object
toFillWithProperties[property] = item[property];
if ((i + 1) % 3 == 0){
// Every 3 steps you update your new Array
this.state.newDataArray.push(toFillWithProperties);
toFillWithProperties = {};
}
}
)})
Once this is done you can then render the table like you were doing before but you should use the map function on this.state.newDataArray. The same applies for your handler function, use setState on your newDataArray.
It should work this way, but I really don't encourage you to work with this kind of data because this procedure is assuming that every 3 elements of your array they would repeat in structure, it won't work in any other cases.
when I look at the react-table documentation for the columns array it has a Cell property that is a function. If my json coming through is from the server how do I implement that Cell function?
The json for the columns coming from the server looks like:
[
{
Header: "name",
id: "name"
},
{
Header: "age",
id: "age"
}
]
End result:
[
{
Header: "name",
id: "name",
Cell: props => (
return props.whatever
),
},
{
Header: "age",
id: "age",
Cell: props => (
return props.whatever
),
}
]
UPDATE:
Lets say you have this link below
https://codesandbox.io/s/lrn7j5vjrl?from-embed
Within this link he gets the data from the api call and then uses it to display within the data property. Then below he has a hard coded columns array with some properties. My issue that I'm having is my columns array will be coming from the server as well so how would i add a cell property function to the incoming columns array json?
You need to add cell field explicitly in the response array like below.
AddCell(response) {
let responseArr = [...response];
return responseArr.map((ele, i) => {
let obj = {...ele}
obj.cell = <RowElement />
return obj
})
}
//Please don't do any network call and set state inside constructor because it will re-render all the child component so use componentDidMount to call.
componentDidMout() {
axios.get("https://jsonplaceholder.typicode.com/posts").then(res => {
const updatedData = AddCell(res.data);
// Update react-table
this.setState({
posts: updatedData,
data: updatedData.slice(0, 5),
pages: updatedData.length / 5,
loading: false
});
});
}
Happy Coding friend :)
This question already has answers here:
How to iterate over a JavaScript object?
(19 answers)
Closed 5 years ago.
I have an object in array like the following:
bears: [
{
Yogi: "123kg",
Pooh: "110kg",
Grizly: "112kg",
BooBoo: "200kg",
Polar: "100kg",
}
]
`
What is the best way to iterate through such object in order to display both names and values in the row, like returning something in the type of: <p>${name} ${value}</p>
So I would display:
Yogi 123kg
Pooh 110kg
Grizly 112kg
BooBoo 200kg
Polar 100kh
It's an array containing an object, not an object. Anyway just get the first item of the array.
This should work:
Object.keys(bears[0]).map(key => <p>{`${key} ${bears[0][key]}`}</p>);
I think that the JSON object's structure itself is wrong.
It should be structured like this:
var bears = [{
name: "Yogi",
weight: "123kg"
}, {
name: "Pooh",
weight: "110kg"
}, {
name: "Grizly",
weight: "112kg"
}, {
name: "BooBoo",
weight: "200kg"
}]
Then you can go ahead and iterate through it using a for loop inside of the render() method like this.
render() {
var bearElements = [];
for (var bearIndex = 0; bearIndex < bears.length; bearIndex++) {
bearElements.push(
<p>{`${bears[bearElements].name}` `${bears[bearElements].weight}`}</p>
)
}
return (
<div>{bears}</div>
);
}