How to map inside map function and show the data in Reactjs

Viewed 1708

I am making two API calls; 1st one is used for rendering a list of data in a table format. In each row, there is a button. And while clicking the button I am firing the 2nd API(with a data property from 1st one). Now I want to view the date when I click the button and a modal opens. As I am mapping 1st place I need to map again to view individual data in a button click.

In the given code snippet - I am trying to view the data which is coming from the 1st API call and added a button to it.

import React, { Component } from 'react';
import { Table, Button, Modal } from 'react-bootstrap';

import axios from 'axios';

class TableData extends Component {
  state = {
    loading: true,
    TableData: [],
    show: false,
    roomData: [],
  };

  handleClose = () => {
    this.setState({ show: false });
  };

  handleShow = () => {
    this.setState({ show: true });
  };

  getRoomInfo = (roomName) => {
    this.handleShow();
    const url = `https://dev.meets.openhouse.study/room_participants/${roomName}`;
    axios.get(url).then((res) => {
      this.setState({ roomData: res.data });
    });
  };

  componentDidMount() {
    const url = 'https://dev.meets.openhouse.study/meets_teachers/';
    axios.get(url).then((res) => {
      this.setState({ TableData: res.data });
      this.setState({ loading: false });
    });
  }

  render() {
    return (
      <div>
        <Table>
          <thead>
            <tr>
              <th>Room Name</th>
              <th>Teacher Name</th>
              <th>Subject</th>
              <th>Class</th>
            </tr>
          </thead>

          {this.state.TableData.map((data) => (
            <tr key={data.created_at}>
              <td>{data.room_name}</td>
              <td>{data.teacher.user.full_name}</td>
              <td>{data.subjects_str}</td>
              <td>{data.classes_str}</td>
              <Button
                variant="secondary"
                onClick={() => this.getRoomInfo(data.room_name)}
              >
                Details
              </Button>

              {this.state.roomData.map((room) => (
                <div key={room.created_at}>
                  <Modal
                    size="lg"
                    aria-labelledby="contained-modal-title-vcenter"
                    centered
                    show={this.state.show}
                    onHide={this.handleClose}
                  >
                    <Modal.Header closeButton>
                      <Modal.Title>{room.room}</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>reading this text in a modal!</Modal.Body>
                    <Modal.Footer>
                      <Button variant="secondary" onClick={this.handleClose}>
                        Close
                      </Button>
                    </Modal.Footer>
                  </Modal>
                </div>
              ))}
            </tr>
          ))}
        </Table>
      </div>
    );
  }
}

export default TableData;

1 Answers

If you want your modal to show results of 2nd api call you should move it outside of this.state.TableData.map((data) => (

and map results inside it. I don't know what contents of modal should show, but here is how it could be done.

Hope it would help.

import React, { Component } from "react";
import { Table, Button, Modal } from "react-bootstrap";

import axios from "axios";

class TableData extends Component {
  state = {
    loading: true,
    TableData: [],
    show: false,
    roomData: []
  };

  handleClose = () => {
    this.setState({ show: false });
  };

  handleShow = () => {
    this.setState({ show: true });
  };

  getRoomInfo = roomName => {
    this.handleShow();
    const url = `https://dev.meets.openhouse.study/room_participants/${roomName}`;
    axios.get(url).then(res => {
      this.setState({ roomData: res.data });
      console.log(res.data);
    });
  };

  componentDidMount() {
    const url = "https://dev.meets.openhouse.study/meets_teachers/";
    axios.get(url).then(res => {
      this.setState({ TableData: res.data });
      this.setState({ loading: false });
    });
  }

  render() {
    return (
      <div>
        <Table>
          <thead>
            <tr>
              <th>Room Name</th>
              <th>Teacher Name</th>
              <th>Subject</th>
              <th>Class</th>
            </tr>
          </thead>

          {this.state.TableData.map(data => (
            <tr key={data.created_at}>
              <td>{data.room_name}</td>
              <td>{data.teacher.user.full_name}</td>
              <td>{data.subjects_str}</td>
              <td>{data.classes_str}</td>
              <Button
                variant="secondary"
                onClick={() => this.getRoomInfo(data.room_name)}
              >
                Details
              </Button>
            </tr>
          ))}
        </Table>
        <div>
          <Modal
            size="lg"
            aria-labelledby="contained-modal-title-vcenter"
            centered
            show={this.state.show}
            onHide={this.handleClose}
          >
            <Modal.Header closeButton>
              <Modal.Title>{"room.room"}</Modal.Title>
            </Modal.Header>
            <Modal.Body>
              {this.state.roomData.map(room => (
                <p>Room: {room.room}</p>
              ))}
            </Modal.Body>
            <Modal.Footer>
              <Button variant="secondary" onClick={this.handleClose}>
                Close
              </Button>
            </Modal.Footer>
          </Modal>
        </div>
      </div>
    );
  }
}

export default TableData;

https://codesandbox.io/s/runtime-microservice-t2jbq?file=/src/App.js

Related