How to get iterator in a Object Key Map - javascript

I have the following code where I am iterating through a map. I want to get some type of iterator for each map entry I go through. Here is my code:
{
Object.keys(element.auditdiff).map(dataType => {
if (dataType !== "Lid" && dataType !== "Datacenter" && dataType !== "Id")
return Object.keys(element.auditdiff[dataType]).map(data => {
//can I somehow make this include an iterator???
return (
<Table.Row key={data}>
<Table.Cell>
<Button
content="Update Row"
color="green"
disabled={updated.indexOf(key) > -1}
onClick={() => {
this.handleUpdate(key);
}} //I want to send the update for each iterator
/>
</Table.Cell>
</Table.Row>
);
});
});
}

Within your map function you can pass and index to check against.
I would suggest using the index as your key.
Like so:
{Object.keys(element.auditdiff).map((dataType, index) => {
return (
<Table.Row key={index}></Table.Row>
)
})}

Related

React Map Method within Map Method

I am trying to include map method in a map method while getting a list as an element from the first map method.
{columns &&
columns.map(column =>
column.list && column.list?
(column.list.map((item)=>{
return (
<CustomTableCell align="center">{item.name}
<span>{item.convertMethod(item.id, item.lists)}</span>
</CustomTableCell>
);
})):
<CustomTableCell align="center"> {column.name} </CustomTableCell>
) }
Error still exists
return (
<div className="App">
{
columns.map(column => {
return (
column.list && column.list.length > 0 ? (
column.list.map(item => {
return (
<div key={item.name}>{item.name}</div>
)
})
): ("")
)
})
}
</div>
);
demo

React Component inside .map() is throwing an error: TypeError: notes.map is not a function

am trying to show Noteitem component which is returned inside a map function.
{notes.map((note) => {
return (
<Noteitem key={note._id} updateNote={updateNote} showAlert={props.showAlert} note={note} />
);
})}
notes should be an array for map function to work. You can check it in following way if notes is not null and is an array using notes.length and apply map function
{notes && notes.length && notes.map((note) => {
return (
<Noteitem key={note._id} updateNote={updateNote} showAlert={props.showAlert} note={note} />
);
})}
You can put if/else statement inside JSX to check the variable whether is exist or not
return (
<>
{
notes.length
? 'fallback'
: notes.map(note => <Noteitem key={note._id} updateNote={updateNote} showAlert={props.showAlert} note={note} />)
}
</>
)
IIFE
{(() => {
if ("check note") {
// fallback
}
return notes.map((note: NoteProps) => (
<Noteitem key={note._id} updateNote={updateNote} showAlert={props.showAlert} note={note} />
));
})()}

React: how to return a table with a button, when the value of the .map function matches a string value

I have a SPARQL query that holds certain properties. i want to return a table with these properties to which i can add a hyperlink to each value to redirect to a certain page. In particular, I want to do this when the value from the .map function matches the string "http://linkedbuildingdata.net/ifc/resources20201208_005325/". This is my code down below.
const QueryTable = ({guidList}) => {
const { context, setContext } = useContext(AppContext);
const isString ='https://LINKEDBUILDINGDATA.NET/IFC/RESOURCES20201208_005325/CPASensor_11NR008TE_001CPA'
return (
<div>
QueryTable
<tbody>
{guidList && guidList.length > 0 && guidList.map((myguids, key) => {
console.log(myguids, key)
return [(
<React.Fragment>
<tr key={key}>
<td>property: <Button>{myguids.guid}</Button></td>
</tr>
</React.Fragment>
)]
})}
</tbody>
</div>
)
}
export default QueryTable
this is what it looks like when i console log the items.
Try with:
guidList && guidList.length > 0 && guidList.map((myguids, key) => {
return (
<tr key={key}>
<td>property: {myguids.guid === isString ? <Button>{myguids.guid}</Button> : myguids.guid}</td>
</tr>
);
});

useState remove item from array

I'm trying to remove an item from an error but it's not working like expected.
Im using state:
const [actions, setActions] = useState([
{
action: "",
key: ""
}
]);
I have a button to add actions:
<IconButton
icon="add"
bgColor="white"
iconColor="darkGray"
onClick={() =>
setActions([
...actions,
{
action: "",
key: ""
}
])
}
/>
Each row has a delete and I'm trying to use the row index to delete the item in the actions array:
<IconButton
disabled={actions.length === 1}
icon="dash"
iconColor="red"
onClick={() => {
console.log(index);
setActions(actions => {
return [...actions.splice(index, 1)];
});
}}
/>
https://codesandbox.io/s/actions-selector-n9xb4
Try using filter. It does not modify the existing array and can be used like this:
setActions(prevActions => (
// Filter out the item with the matching index
prevActions.filter((value, i) => i !== index)
));
<IconButton
disabled={actions.length === 1}
icon="dash"
iconColor="red"
onClick={() => {
setActions(actions.filter((item, i) => i !== index));
}}
/>
I tested it in your Codesandbox and it worked

react and conditional rendering

Currently I am using the following code to conditionally render some HTML based on hasLocations variable.
Code works, but I wish to know if there is a better way to achieve the same result, for example, I am not sure having two return is a good practice.
const Finder = ({ locations, onLocationClick }) => {
let hasLocations = locations.length > 0
if (hasLocations) {
return (
<ul>
{locations.map((location, index) =>
<Location
key={index}
{...locations[index]}
onLocationClick={() => onLocationClick(location)}
/>
)}
</ul>
)
} else {
return (null)
}
}
Alternatively you chould use conditional rendering. For your example, this would look like this.
const Finder = ({ locations, onLocationClick }) => {
return (
<ul>
{locations.length > 0 &&
locations.map((location, index) =>
<Location
key={index}
{...locations[index]}
onLocationClick={() => onLocationClick(location)}
/>
)}
</ul>
);
}
EDIT: My solution would be the following.
I would avoid adding any logic in it(AKA presentational component). So it would become
const Finder = ({ locations, onLocationClick }) => {
return (
<ul>
locations.map((location, index) =>
<Location
key={index}
{...locations[index]}
onLocationClick={() => onLocationClick(location)}
/>
)
</ul>
);
}
And when you need to use it you can do something like this:
return (
<div>
{locations.length > 0 && Finder}
</div>
);
There's nothing wrong with using multiple returns in a function, but when you do it's good practice to put a "default" return as the last statement in the function to make it more apparent that the function always returns something.
In your case that means you could move your return (null) (no need to wrap null in brackets, btw) statement out of the else clause and just put it as the last statement of the function.
It's also possible to use a single return statement with ternary in your return, like this:
return locations.length > 0 ? (
<ul>
{locations.map((location, index) =>
<Location
key={index}
{...locations[index]}
onLocationClick={() => onLocationClick(location)}
/>
)}
</ul>
) : null

Categories