Iterate a card component with properties from an array of objects

I am trying to iterate out a card component with details relating to specific object in each field from a database. I have the details in state but I want my component to list cards for each of the objects I have saved to the database. I have done similar on PHP but I am new to React.

Am I going about this the right way? I want to iterate out three cards per line (the grid for material UI is set-up correctly above this). In each of the fields I want it

<GridList
                        className="team"
                        key="Subheader"
                        cellHeight={360}
                        cols={3}
                        spacing={2}
                    >

                       **{{schoolList.length > 0: i=0: i++}
                           return (

                    <Grid item xs={6} sm={4}>
                        <Card className={classes.root}>
                            <CardHeader
                                avatar={
                                    <Avatar aria-label="scubaSchool" className={classes.avatar}>
                                        S
                                    </Avatar>
                                }
                                action={
                                    <IconButton aria-label="settings">
                                        <MoreVertIcon />
                                    </IconButton>
                                }
                                title= {this.state.schoolList.diveSchoolName[i]}
                                subheader= {this.state.schoolList.diveSchoolLocation[i]}
                            />
                            <CardMedia
                                className={classes.media}
                                image="/static/images/cards/paella.jpg"
                                title="Scuba School"
                            />
                            <CardContent>
                                <Typography variant="body2" color="textSecondary" component="p">
                                    {this.state.schoolList.diveCertificatesOfferredID[i]}
                                </Typography>
                            </CardContent>
                            <CardContent>
                                <Typography variant="body2" color="textSecondary" component="p">
                                    {this.state.schoolList.diveSpotsOfferredID[i]}
                                </Typography>
                            </CardContent>
                            <CardActions disableSpacing>
                                <IconButton aria-label="add to favorites">
                                    <FavoriteIcon />
                                </IconButton>
                                <IconButton aria-label="share">
                                    <ShareIcon />
                                </IconButton>
                                <IconButton
                                    className={clsx(classes.expand, {
                                        [classes.expandOpen]: expanded,
                                    })}
                                    onClick={handleExpandClick}
                                    aria-expanded={expanded}
                                    aria-label="show more"
                                >
                                    <ExpandMoreIcon />
                                </IconButton>
                            </CardActions>
                            <Collapse in={expanded} timeout="auto" unmountOnExit>
                            </Collapse>
                        </Card>
                            </Glad>

                            )}

                </GridList>

I am aware of the map method in javascript but how would specify the different property for each field?

Split out your specific card component, use props for the dive school properties you’re going to pass in. You don’t have to do this, you can do it all inline, but for one thing the code gets very unwieldy if you don’t. So like:

const MyCard = ({ name, location }) => (
  <Card className={classes.root}>
    <CardHeader
      avatar={...avatar stuff}
      action={...action stuff}
      title={diveSchoolName}
      subheader= {diveSchoolLocation}
    />
    ...rest of the card stuff
  </Card>
);

Then something like:

<GridList
  className="team"
  key="Subheader"
  cellHeight={360}
  cols={3}
  spacing={2}
>
  { schoolList.map((school) => (
    <Grid item xs={6} sm={4}>
      <MyCard
        name={school.diveSchoolName}
        location={school.diveSchoolLovation}
      />
    </Grid>
  )}
</GridList>

You can’t use a loop, it’s not valid JS syntax – loops are statements, so you can’t have something in an object like:

{
  foo: for(let i = 0; i < 10; i++) {
    // Do something
  }
}

And that’s what you’re trying to do there in the commented out code. Whatever you use in the JSX code has to be an expression, because JSX is just a way of writing JS objects/functions using a syntax that looks like HTML. map is an expression, it just evaluates to a value, which in this case is an array of React components. map loops over an array of things (in this case objects), so each iteration of the loops lets you access the current item (which seems to be an object containing some information about dive schools).

1 Like

Legend, got it working. :slight_smile:

1 Like