Skip to content Skip to sidebar Skip to footer

How To Remove Children Objects Recursively From Object?

I am working on solution I have created basic tree kind of table whenever user click on expand data related to clicked row will appear under it based on row data I have achieved ba

Solution 1:

import React, { useState, useEffect, useRef, Fragment } from "react";
import axios from "axios";

const test_data = [{
  "id":1,
    "name":"Leanne Graham",
    "username":"Bret",
    "email":"Sincere@april.biz",
    "address":{
      "street":"Kulas Light",
      "suite":"Apt. 556",
      "city":"Gwenborough",
      "zipcode":"92998-3874",
      "geo":{
        "lat":"-37.3159",
        "lng":"81.1496"
      }
    },
    "phone":"1-770-736-8031 x56442",
    "website":"hildegard.org",
    "company":{
      "name":"Romaguera-Crona",
      "catchPhrase":"Multi-layered client-server neural-net",
      "bs":"harness real-time e-markets"
    }
}];

class TableRowData extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      showIcon: false,
      selection: [],
      data: [],
      splitOption: ["campid"]
    };
  }

  // function to check if next split is there or not if there than return nextsplit
  checkIfSplitExist = (currentSplit) => {
    const i = this.state.splitOption.indexOf(currentSplit);

    if (i > -1 && this.state.splitOption[i + 1]) {
      return this.state.splitOption[i + 1];
    }
    return null;
  }

  getReportData = () => {
    // axios.get("https://jsonplaceholder.typicode.com/users?_start=0&_limit=1").then(({data}) => {
      this.setState({
        data: test_data.map((row) => {
        row.name = this.state.splitOption[0];
        row.isExpanded = false;
        row.currentSplit = this.state.splitOption[0];
        row.nextSplit = this.checkIfSplitExist(this.state.splitOption[0])
        row.parentId = 0;
        row.isVisble = true;
        console.log(row)
        return row;
      })
      });
    // });
  }
  
  componentDidMount() {
    this.getReportData()
  }

  render() {
    // update state function
    const updateState = () => {
      this.setState({
        data: [...this.state.data],
        splitOption: [...this.state.splitOption],
        selection: [...this.state.selection],
      }, () => { })
    }

    const recursionUpdateAndDeleteRow = (parentRow, childRow, split, index = 0) => {
      childRow.children && childRow.children.forEach((r) => {
        recursionUpdateAndDeleteRow(childRow, r, split, index + 1);
      });

      if (parentRow && split.indexOf(childRow.currentSplit) == -1) {
        delete parentRow.children;
      }

      childRow.currentSplit = split[index];
      childRow.nextSplit = split[index + 1] || null;
      if (!childRow.children) {
        childRow.isExpanded = false;
      }
    }

    const recursionUpdateAndDeleteRows = (rows, split) => {
      const _copy = [...rows];
      _copy.forEach((row) => {
        recursionUpdateAndDeleteRow(null, row, split);
      });
      return _copy;
    }

    const toggleSplit = (split) => {
      const index = this.state.splitOption.indexOf(split);
      let currentSplitOptions = [...this.state.splitOption];
      if (index > -1) {
        currentSplitOptions.splice(index, 1)
      }
      else {
        currentSplitOptions.push(split);
      }

      const _data = recursionUpdateAndDeleteRows(this.state.data, currentSplitOptions);

      this.setState({
        splitOption: currentSplitOptions,
        data: _data
      })
    }

    // add lazyload expand data
    const ExpandableTableRow = ({ rows }) => {

      const expandRow = (row) => {
        row.children = [
          {
            id: "_" + Math.random().toString(36).substr(2, 5),
            name: row.id + "_" + row.nextSplit,
            isExpanded: false,
            parentId: row.id,
            currentSplit: row.nextSplit,
            nextSplit: this.checkIfSplitExist(row.nextSplit),
            isVisble: true
          }, {
            id: "_" + Math.random().toString(36).substr(2, 5),
            name: row.id + "_" + row.nextSplit,
            isExpanded: false,
            parentId: row.id,
            currentSplit: row.nextSplit,
            nextSplit: this.checkIfSplitExist(row.nextSplit),
            isVisble: true
          }
        ];
        row.isExpanded = true;
        updateState();
      };

      // call whenever - click
      const collapseRow = (row) => {
        delete row.children;
        row.isExpanded = false;
        updateState();
      };

      // toggle
      const ExpandCollapsToggle = ({ row }) => {
        // display +/- only if nextsplit is not undefined or null
        if (row.nextSplit) {
          if (row.isExpanded) {
            return (
              <button type="button" onClick={() => collapseRow(row)}>
                -
              </button>
            );
          }
          return (
            <button type="button" onClick={() => expandRow(row)}>
              +
            </button>
          );
        }
        return null;
      };

      if (rows) {
        return rows.map((row) => {
          return (
            <Fragment key={row.id}>
            <tr key={row.id}>
              <td>
                <ExpandCollapsToggle
                  row={row}
                />
                {" "}{row.split} - {row.id}
              </td>
              <td>{row.name}</td>
            </tr>
            <ExpandableTableRow rows={row.children} />
          </Fragment>
          );
        });
      } else {
        return null;
      }
    };

    if (this.state.data) {
      return (
        <Fragment>
          {this.state.splitOption.join(', ')} <br />
          <button onClick={() => toggleSplit("name")}>
            camp name
          </button>
          <button onClick={() => toggleSplit("os")}>os</button>
          <button onClick={() => toggleSplit("country")}>country</button>
          <br />
          <ExpandableTableRow rows={this.state.data} />
        </Fragment>
      );
    } else {
      return null;
    }
  }
}

export default function App() {
  return (
    <div>
      <TableRowData />
    </div>
  );
}

Here working example


Post a Comment for "How To Remove Children Objects Recursively From Object?"