iamharry
iamharry

Reputation: 128

How to play one video from array at a time in ReactJS & AG Grid

Getting response from API. API response

API response : 

    0:
    Camera_Number: "Camera_1"
    Company_Name: "Fraction Analytics Limited"
    Floor Number: "Ground_Floor"
    Group_Name: "Group_1"
    Video_Name: "http://localhost:4000/video/0"

After populating data to table create one button then ag-grid look like this

enter image description here

I am currently mapping through all the videos to button and I click button it opens multiple video but I want only one video at a time.

app.js

const initialValue = { Name: "", Floor: "", Group: "", Camera: "", Videos: "" };

export default function App(data, handleFormSubmit) {
  const { id } = data;
  const actionButton = (params) => {
    setResponse(params.response);
    setOpen(true);
  };

  const [response, setResponse] = useState(0);
  const [open, setOpen] = React.useState(false);
  const [formData, setFormData] = useState(initialValue);
  const handleClose = () => {
    setOpen(false);
    setFormData(initialValue);
  };

  const onChange = (e) => {
    const { value, id } = e.target;
    // console.log(value,id)
    setFormData({ ...formData, [id]: value });
  };

  const columnDefs = [
    { headerName: "Name", field: "Company_Name", filter: "agSetColumnFilter" },
    { headerName: "Floor", field: "Floor Number" },
    { headerName: "Group", field: "Group_Name" },
    { headerName: "Camera", field: "Camera_Number" },
    { headerName: "Videos", field: "Video_Name" },
    {
      headerName: "Actions",
      field: "Video_Name",
      cellRendererFramework: (params) => (
        <div>
          <Button
            variant="contained"
            size="medium"
            color="primary"
            onClick={() => actionButton(params)}
          >
            Play
          </Button>
        </div>
      ),
    },
  ];

  const onGridReady = (params) => {
    console.log("grid is ready");
    fetch("http://localhost:8000/get_all")
      .then((resp) => resp.json())
      .then((resp) => {
        console.log(resp.results);
        setResponse(resp.results);
        params.api.applyTransaction({ add: resp.results });
      });
  };
  return (
    <div className="App">
      <h1 align="center"> React FastAPI Integration</h1>
      <h3> API Data </h3>
      <div className="ag-theme-alpine" style={{ height: "400px" }}>
      </div>
      <div>
          <DialogContent>
            <iframe width="420" height="315" title="videos" src={id} />
          </DialogContent>
          ;
          <DialogActions>
            <Button onClick={handleClose} color="secondary" variant="outlined">
              Cancel
            </Button>
            <Button
              color="primary"
              onClick={() => handleFormSubmit()}
              variant="contained"
            >
              {id ? "Update" : "Download"}
            </Button>
          </DialogActions>
        </Dialog>
      </div>
    </div>
  );
}

Multiple video open at same time,I don't know how to properly play one at a time. I appreciate any help. I've been stuck on this for a few days.

Multiple video open at a time. but i want one video at a time

enter image description here

Upvotes: 5

Views: 453

Answers (2)

A G
A G

Reputation: 22617

No need to use the click handler of the button. You cannot get row data with that.

Add a colId to column definition for actions. Then handle the onCellClicked action of the grid. You can get the row data using params.node.data.

const [videoName, setVideoName] = useState("");

function onCellClicked(params) {
    // maps to colId: "action" in columnDefs,
    if (params.column.colId === "action") {
      // set videoName for the row
      setVideoName(params.node.data.Video_Name);
      setOpen(true);
    }
}

// grid config
<AgGridReact
  ...
  rowData={response}
  onCellClicked={onCellClicked}>
</AgGridReact>

// access videoName in dialog content
<DialogContent>
 {/* <iframe width="420" height="315" title="videos" src={id} /> */}
 <div>{videoName}</div>
</DialogContent>

Edit reverent-zhukovsky-gt4mln

Output - Click on any row's play button. Result is that rows video url. You can now use this to play the actual video.

Output

Upvotes: 1

Giorgi Moniava
Giorgi Moniava

Reputation: 28685

If I correctly understood the question, it is because in DialogContent you are mapping through all response, and showing all of them. Instead why not here:

const actionButton = (params) => {
    setOpen(true);
  };

instead of storing true, store id (it seems video name could work in your case too) of the row clicked. Then inside DialogContent render only one iframe, with video based on that id.

PS. You can pass !!id as open prop to Dialog, which means if there is something in id, the Dialog will open (assuming there are no ids with falsy values).


Or you can actually store the whole row itself in state, and then you can more easily access it, here is simple example what I mean:

let data = [
  { name: 'david', id: 0 },
  { name: 'nick', id: 1 },
  { name: 'john', id: 2 },
];

export default function App() {
  let [clicked, setClicked] = React.useState(null);
  return (
    <div>
      {data.map((x) => {
        return (
          <div
            key={x.id}
            onClick={() => {
              setClicked(x);
            }}
          >
            Row {x.name}
          </div>
        );
      })}
      <div>Clicked row {clicked && clicked.name}</div>
    </div>
  );
}

Upvotes: 1

Related Questions