Looping through the data object and Mapping Header to values in React - javascript

I have a question on how to use this data to map the headers to it's corresponding values and put that on the UI
This is how the data is structured:
{
"data": {
"details": [
{
"address_line_1": "C O Cwtsatotravel",
"address_line_2": "Not Available",
"city_name": "Arlington",
"state_name": "-",
"country_name": "Japan",
"postal_code": "22203",
"phone_number": "7638527755",
}
]
}
}
This is what I am trying to do in react
const profile_info = data?.details;
const profileHeaders = [
'Address1',
'Address2'
'City',
'State',
'Postal Code',
'Country',
'Phone',
];
return (
<Grid
id="top-card"
className={classes.mainContainer}
container
style={{
marginBottom: '4px',
}}
>
{/* <Grid item md={11} lg={11} id="item-card"> */}
<Grid container item>
<Typography variant="subtitle1">
{profile_info.agency_name}
</Typography>
</Grid>
<Grid
container
style={{
backgroundColor: '#f9f9f9',
}}
>
{profileHeaders.map((v) => (
<Grid
item
style={{
padding: '0px 4px',
}}
>
<Typography className={classes.profileData} gutterBottom={true}>
{v}
</Typography>
<Typography className={classes.profileData}>
{' '}
{profile_info[v]}
</Typography>
</Grid>
))}
</Grid>
</Grid>
);
When I do this, it's getting me all blank values on the UI for the headers
Please help, thank you !

Encode your headers using the same [as in data] keys:
const headers = {
"address_line_1": "Address1",
"address_line_2": "Address2",
"city_name": "City",
later, you can list it
Object.entries(headers).forEach(([key, value]) => console.log(`${key}: ${value}`));
console.log(data) to see its structure and use const to 'alias' iterable (object with props or array) element:
// choose the right data source - depends on what logged out
// console.log(data);
// if(data) console.log(data.details); //... step by step
// const profile_info = data?.details;
// const profile_info = data?.data.details;
const profile_info = data?.details[0]; // object in array here
render values from both headers and profile_info
Object.entries(headers).forEach(([key, value]) => (
<Grid
key={key}
item
style={{
padding: '0px 4px',
}}
>
<Typography className={classes.profileData} gutterBottom={true}>
{value}
</Typography>
<Typography className={classes.profileData}>
{' ??? use css instead! '}
{profile_info[key]}
</Typography>
</Grid>
or you can do the same using .map (you can use index if required)
Object.keys(headers).map((key, idx) => (
<Element key={key}>
<Name title={headers[key]} />
<Value data={profile_info[key]} />

There is some crucial erros on your code:
const profile_info = data?.details;
Your details are stored on property data.data.details, not data.details
So fix this, first:
const profile_info = data?.data.details;
The items in ProfileHeaders are not mapped like properties in profile_info: you have a profile_info['address_line_1'], but not profile_info['Address1'], wich is what you are trying to do in your component.
To make this work the way you want, you should map title and property correctly.
const profileHeaders = [
{
title: "Address1",
property: "address_line_1"
},
{
title: "Address2",
property: "address_line_2"
},
// map all other properties like above.
]
then you can go for that:
{profileHeaders.map((v) => (
<Grid
item
style={{
padding: '0px 4px',
}}
>
<Typography className={classes.profileData} gutterBottom={true}>
{v.title}
</Typography>
<Typography className={classes.profileData}>
{' '}
{profile_info[v.property]}
</Typography>
</Grid>
))}
I am not checking if profile_info is undefined, but you must do it in your component to avoid errors.

Related

Can't use the multiple prop in Autocomplete while also using onChange

I am trying to use the Multiple prop with Autocomplete in Material UI. But every time I try to add it in it breaks my code. Seems to have an issue with my onChange prop, but I cannot figure out how to make them work together. Basically I am trying to display multiple values as well as the information inside the array on my page. Here is my code below. Thanks in advance!
type Movie = {
label: string
year: number
}
export default function ComboBox() {
const [value, setValue] = useState<string | null>(null)
const [movie, setMovie] = useState<Movie | null>(null)
console.log({ movie });
return (
<Grid container padding='32px'>
<Stack direction='row' spacing={2} divider={<Divider orientation='vertical' flexItem sx={{ width: 'auto' }} />}>
<Autocomplete
sx={{ width: 300 }}
options={top100Films}
renderInput={(params) => <TextField {...params}
label='Skills' />}
value={movie}
onChange={(event: any, newValue: Movie | null) => setMovie(newValue)}
/>
<Paper sx={{ width: 300 }} elevation={4} >
<Typography fontSize='40px'> {movie === null?"": movie.label} </Typography>
</Paper>
<Paper sx={{ width: 300 }} elevation={4}>
<Typography fontSize='40px'>
{movie === null?"": movie.year}
</Typography>
</Paper>
</Stack>
</Grid>
);
}

Remove repeated elements

I'm displaying US region incidents from Google Cloud API, but the problem is that it displays also repeated data, example:enter image description here
How can I remove the repeated ones? Here's the code.
DATA RETRIEVING:
export const getGoogleStatus = async () => {
const response = await axios.get('https://status.cloud.google.com/incidents.json')
console.log('Raw Data: ', response.data)
const status = response.data.map((e) => {
return {
name: e.affected_products.map((e) => {
return e.title
}),
status: e.most_recent_update.status,
location: e.most_recent_update.affected_locations.map((e) => {
return e.title
}).filter((r) => r.includes("(us-"))
}
})
return status
}
DATA DISPLAYING IN FRONTEND:
export default function GoogleStatusSummary({ listStatus }) {
if (!listStatus) return <div>Loading...</div>
return (
<Grid container padding={2} justifyContent='center'>
<Grid item padding={2}>
<Typography variant='h1' marginLeft={5}>
<TwitterIcon sx={{ mr: 2, mt: 1 }} />
Google API Status
</Typography>
{listStatus.map((item, index) => {
const { name, status, location } = item
const colorStatus = status === 'AVAILABLE' ? 'success' : 'danger'
return (
location.length > 0 && (
<Grid display='flex' m={3} key={index}>
<RadioButtonCheckedIcon sx={{ ml: 2, mt: 1 }} color={colorStatus} />
<Grid ml={2}>
<Typography variant='h4'>
{name}
</Typography>
<Typography variant='h6' style={{ fontSize: 12 }}>
{status.charAt(0).toUpperCase() + status.slice(1)}
</Typography>
</Grid>
</Grid>
)
)
})
}
</Grid>
</Grid>
)

how can i append selected row data in another table

what my task is I am using a table with two different conditions like in the first table whatever data coming I will show that in the first table and in the second table whatever row I select in the first table that I want to show in the second table as the second table I called select summary so my task is in the first table whatever row I selected in need to how that row in the second table I am using same table component for this for better you can see CodeSandBox link
import React, { useState, useMemo, useEffect } from "react";
import {
Grid,
makeStyles,
CardContent,
Card,
Box
} from "#material-ui/core";
import EnhancedTable from "./EnhancedTable";
const useStyles = makeStyles((theme) => ({
root: {
padding: theme.spacing(0, 2, 2),
},
formGrid: {
padding: theme.spacing(2),
},
cardColor: {
borderColor: "#0bb7a7",
},
}));
function AddToExclusionList() {
const classes = useStyles();
const [sanctionsList, setSanctionsList] = useState([]);
const updateListsRow = ({ index, value, row }, listType) => {
switch (listType) {
case "sanctions":
setSanctionsList((prevState) => {
prevState[index].status = value;
return [...prevState];
});
break;
default:
}
};
return (
<Grid className={classes.root}>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<EnhancedTable
show={true}
step="first"
/>
</>
</CardContent>
</Card>
</Grid>
<Box mt={3}></Box>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<h3>summary table</h3>
<EnhancedTable
checkboxToggle={(rowDetails) => {
updateListsRow(rowDetails, "sanctions");
}}
/>
</>
</CardContent>
</Card>
</Grid>
</Grid>
);
}
export default AddToExclusionList;
CodeSandBox Link
You've achieved your goal very weird! Anyway, based on your code in codesandbox. You need to add a state to AddToExclusionList component, like this:
const [newRows, setNewRows] = useState([]);
const setSummaryRows = (selectedRows) => {
const copy = [...rows];
const filteredRows = copy.filter((x) => selectedRows.includes(x.name));
setNewRows(filteredRows);
};
We need the mentioned state to update the summary table's rows.
Also add rows and setNewRows prop to EnhancedTable and give it rows from out of the component. In addition move rows and createData to App.js. So you should use EnhancedTable in App.js same as bellow:
<Grid className={classes.root}>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<h3>first table</h3>
<EnhancedTable
// passing data for rendering table according condition
step="first"
rows={rows}
setNewRows={(selected) => {
setSummaryRows(selected);
}}
/>
</>
</CardContent>
</Card>
</Grid>
<Box mt={3}></Box>
<Grid item xs={12} style={{ textTransform: "capitalize" }}>
<Card className={classes.cardColor} variant="outlined">
<CardContent>
<>
<h3>summary table</h3>
<EnhancedTable
// trying to pasing selected data
rows={newRows}
setNewRows={() => {}}
/>
</>
</CardContent>
</Card>
</Grid>
</Grid>
And the last part is using useEffect based on selected in EnhancedTable component:
useEffect(() => {
setNewRows(selected);
}, [selected]);

React js - data.map is not a function

export default function Case() {
const classes = useStyles();
const[data,setData]=useState([])
const getcovid=async()=>{
const api=await fetch('https://api.rootnet.in/covid19-in/stats/latest');
const res=await api.json();
console.log(res.data.summary)
setData(res.data.summary)
}
useEffect(()=>{
getcovid()
},[])
return (
<div>
<Typography variant="subtitle1" gutterBottom>
Material-UI Grid:
</Typography>
{
data&&data.map(item=>{
return(
<Grid container spacing={3}>
<Grid item xs={3}>
<Paper className={classes.paper}>Confirmed Cases: <br/>{item}</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
<Grid item xs={3}>
<Paper className={classes.paper}>xs=3</Paper>
</Grid>
</Grid>
)
})
}
</div>
);
}
My api - {
"success": true,
"data": {
"summary": {
"total": 26289290,
"confirmedCasesIndian": 26289242,
"confirmedCasesForeign": 48,
"discharged": 23070365,
"deaths": 295525,
"confirmedButLocationUnidentified": 0
},
But it shows an error - TypeError: data.map is not a function
I have tried both with data&&data.map and only with data.map but still i get same errorenter code here
Your data is an object not an array. You can try to use this instead:
Object.keys(data).map(function(key, item) {
console.log(data[key]);
return(
...
)
});
The API response you posted shows that data.summary is an object, not an array. Objects don't have a map method, but arrays do. Instead of using map you can just access the properties individually, such as {data.total} and {data.deaths}.

history.push() not working while sending the data

I have defined a route in Main component as:
<Route path="/user/:action?/:name?" component={DataForm} />
MainDataCard component:
var data = [ {name: 'abc", label: "ABC", path:"/assets/data/source1.jpg" },
{name: 'pqr", label: "PQR", path:"/assets/data/source2.jpg" },
{name: 'xyz", label: "XYZ", path:"/assets/data/source3.jpg" },
]
I am iterating over a data array and onClick of each card, I ll be navigating to another component which is DataForm. While pushing, I need to send the selected card object.
{data.map((card, index) => {
return (
<Card
key={index}
className="cardStyle"
onClick={() => {
this.onClickForm(card);
}}
>
<CardContent className="cardContent">
<Grid container>
<Grid item md={12}>
<img src={card.path} alt="card" />
</Grid>
<Grid item md={12}>
<Typography color="textSecondary" gutterBottom>
{card.name}
</Typography>
</Grid>
</Grid>
</CardContent>
</Card>
onClickForm = card => {
const {action} = this.props; // action value can be add/update. Currently action = "add"
this.props.history.push({
pathname: `/user/${action}/${card.label}`,
state: { card: card }
});
};
In DataForm component, its showing that card is undefined. It means the data is not being sent to DataForm component. Why is it so?
Thanks in advance.

Categories

Resources