cant access nested array in react-bootstrap-table-next

Solution for cant access nested array in react-bootstrap-table-next
is Given Below:

having trouble accessing a nested array to display in react-bootstrap-table-next.

my object is coming from redux store and bringing me groupDetails.

The BootstrapTable has a property called data={}. From what Ive read in the documentation you pass your initial object in my case data={groupDetails} to the ToolkitProvider and then it passes those props down to the BootstrapTable. Once done, then in your columns dataField prop you pass in the nested object.
so In my case I want to access groupDetails.group.data.contacts.firstName But I cannot seem to get this to work Ive been working on this for 2 days

here is my reducer

import { GROUP_DETAILS_REQUEST, GROUP_DETAILS_FAIL, GROUP_DETAILS_SUCCESS } from "../actions/types"

export default function groupDetailsReducer ( state = { group: {} }, action ) {
    switch(action.type) {
        case GROUP_DETAILS_REQUEST:
            return { loading: true }
        case GROUP_DETAILS_SUCCESS:
            return { loading: false, group: action.payload}
        case GROUP_DETAILS_FAIL:
            return { loading: false, error: action.payload}
            default:
                return state
    }
}

Here is the console.log(groupDetails)

{loading: false, group: {…}} <-- this group is nested
group: <--- here is the nested group
config: {url: "http://localhost:5000/groups/60d2d43345f1de1135185efe", method: "get", headers: {…}, transformRequest: Array(1), transformResponse: Array(1), …}
data: < --- within this data is the contacts array of objects I need
contacts: [{…}]
title: "vacant"
_id: "60d2d43345f1de1135185efe"
[[Prototype]]: Object
headers: {content-length: "384", content-type: "application/json; charset=utf-8"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 200
statusText: "OK"

Be prepared its large, The table is near the bottom
Here is my component

import React, { createRef, useEffect, Fragment, useState, Suspense } from 'react';
import {
  Button,
  ButtonGroup,
  Card,
  CardBody,
  Col,
  CustomInput,
  DropdownItem,
  DropdownMenu,
  DropdownToggle,
  Form,
  Input,
  InputGroup,
  Label,
  Media,
  Modal,
  ModalBody,
  ModalHeader,
  Row,
  UncontrolledDropdown
} from 'reactstrap';
import FalconCardHeader from '../common/FalconCardHeader';
import ButtonIcon from '../common/ButtonIcon';
import paginationFactory, { PaginationProvider } from 'react-bootstrap-table2-paginator';
import BootstrapTable from 'react-bootstrap-table-next';
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
import { FontAwesomeIcon , faSms} from '@fortawesome/react-fontawesome';
import { useSelector, useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import Flex from '../common/Flex';
import Avatar from '../common/Avatar';
import { getPaginationArray } from '../../helpers/utils';

import GroupContactChoose from './GroupContactChoose'
import { listGroups, createGroup, listContacts, deleteGroup, deleteContact, groupById } from '../../actions/index';

const GroupEdit = ({match}) => {


const GroupId = match.params.id
  let table = createRef();
  
  const { SearchBar } = Search;

  const [showGroupModal, setShowGroupModal] = useState(false);
  const [showContactModal, setShowContactModal ] = useState(false);
  const [isSelected, setIsSelected] = useState(false);
  const dispatch = useDispatch();
   
  const groupCreate = useSelector((state) => state.groupCreate)
  const {success: successCreate} = groupCreate

  const groupDelete = useSelector((state) => state.groupDelete)
  const {success: successDelete } = groupDelete
  // group delete

  const groupDetails = useSelector((state) => state.groupDetails)
  const { success: successGet } = groupDetails

  const [group, setGroup] = useState({
    title: '',
    contacts: []
  })

  const CustomTotal = ({ sizePerPage, totalSize, page, lastIndex }) => (
    <span>
      {(page - 1) * sizePerPage + 1} to {lastIndex > totalSize ? totalSize : lastIndex} of {totalSize} —{' '}
    </span>
  );

  const handleDeleteGroup = (_id) => {
   
    if(window.confirm("Are you sure?")) {
  dispatch(deleteGroup(_id))}
  
  }

  const firstNameFormatter = (dataField, {_id, avatar}) => {
    console.log('this ran') // this will not run....
    return (
    
      <Link to={`/dashboard/contact/${_id}`}>
        <Media tag={Flex} align="center">
          <Avatar name={firstName} {...avatar} />
          <Media body className="ml-2">
            <h5 className="mb-0 fs--1">{firstName}</h5>
          </Media>
        </Media>
      </Link>
    );
  };
  
  const lastNameFormatter = (dataField, { _id, lastName }) => {
    return (
      <Link to={`/dashboard/contact/${_id}`}>
        <Media tag={Flex} align="center">
          <Media body className="ml-2">
            <h5 className="mb-0 fs--1">{lastName}</h5>
          </Media>
        </Media>
      </Link>
    );
  };

  const phoneFormatter = (dataField, { _id, phone_number}) => {
    console.log("this ran")
    return (
      <Link to={`/dashboard/contact/${_id}`}>
        <Media tag={Flex} align="center">
          <Media body className="ml-2">
            <h5 className="mb-0 fs--1">{phone_number}</h5>
          </Media>
        </Media>
      </Link>
    );
  };

  
  const actionFormatter = (dataField, { _id }, row) => (
    // Control your row with this id
    <UncontrolledDropdown>
      <DropdownToggle color="link" size="sm" className="text-600 btn-reveal mr-3">
        <FontAwesomeIcon icon="ellipsis-h" className="fs--1" />
      </DropdownToggle>
      <DropdownMenu right className="border py-2">
        <DropdownItem onClick={() => console.log('Edit: ', _id)}>Edit</DropdownItem> 
        <DropdownItem onClick={() => { handleDeleteGroup(_id)} } className="text-danger">
          Delete
        </DropdownItem>
      </DropdownMenu>
    </UncontrolledDropdown>
  );

  
  console.log(groupDetails?.group?.data?.contacts) // this console.log works fine
const columns = [
  {
    dataField: 'firstName', // when I change dataField to group.data.contacts.firstName it breaks
    text: 'First Name',
    headerClasses: 'border-0',
    classes: 'border-0 py-2 align-middle',
    formatter: firstNameFormatter,
    sort: true
  },
 {
   dataField: 'lastName',
   text: 'Last Name',
   headerClasses: 'border-0',
   classes: 'border-0 py-2 align-middle',
   formatter: lastNameFormatter,
   sort: true
 }, 
 {
  dataField: 'phone_number',
  headerClasses: 'border-0',
  text: 'Phone',
  classes: 'border-0 py-2 align-middle',
  formatter: phoneFormatter,
  sort: true
},

{
  dataField: 'group',
  headerClasses: 'border-0',
  text: 'Type',
  classes: 'border-0 py-2 align-middle',
  sort: true
},
{
  dataField: 'created',
  headerClasses: 'border-0',
  text: 'Created',
  classes: 'border-0 py-2 align-middle',
  sort: true,
  align: 'right',
  headerAlign: 'right'
},
{
  dataField: 'actions',
  headerClasses: 'border-0',
  text: 'Actions',
  classes: 'border-0 py-2 align-middle',
  formatter: actionFormatter,
  align: 'right'
}
];

const options = {
  custom: true,
  sizePerPage: 12,
  totalSize: groupDetails?.group?.data?.contacts?.length // this works just fine
  
};
const SelectRowInput = ({ indeterminate, rowIndex, ...rest }) => (
  <div className="custom-control custom-checkbox">
    <input
      className="custom-control-input"
      {...rest}
      onChange={() => {}}
      ref={input => {
        if (input) input.indeterminate = indeterminate;
      }}
    />
    <label className="custom-control-label" />
  </div>
);


const selectRow = onSelect => ({
  mode: 'checkbox',
  columnClasses: 'py-2 align-middle',
  clickToSelect: false,
  selectionHeaderRenderer: ({ mode, ...rest }) => <SelectRowInput type="checkbox" {...rest} />,
  selectionRenderer: ({ mode, ...rest }) => <SelectRowInput type={mode} {...rest} />,
  headerColumnStyle: { border: 0, verticalAlign: 'middle' },
  selectColumnStyle: { border: 0, verticalAlign: 'middle' },
  onSelect: onSelect,
  onSelectAll: onSelect
});
 
  const handleNextPage = ({ page, onPageChange }) => () => {
    onPageChange(page + 1);
  };

  const handlePrevPage = ({ page, onPageChange }) => () => {
    onPageChange(page - 1);
  };

  const onSelect = () => {
    setImmediate(() => {
      setIsSelected(!!table.current.selectionContext.selected.length);
    });
  };



  useEffect(() => {
    dispatch(groupById(GroupId))   
  }, [successGet])
  
  return (
    <Card className="mb-3">
      <CardBody className="p-0">
      
     <ToolkitProvider
           keyField="_id"
           columns={columns}
           data={groupDetails}
           bootstrap4
           >
             { props => (
        <PaginationProvider pagination={paginationFactory(options)}>
          {({ paginationProps, paginationTableProps }) => {
            const lastIndex = paginationProps.page * paginationProps.sizePerPage;
            return (
              <Fragment>
                <div className="table-responsive">
                <SearchBar className="ml-3 p-2" {...props.searchProps} 
                >
                <FontAwesomeIcon icon="search" className="contacts-search-icon" />
                </SearchBar>
                  <BootstrapTable
                    ref={table}
                    selectRow={selectRow(onSelect)}
                    bordered={false}
                    classes="table-dashboard table-striped table-sm fs--1 border-bottom border-200 mb-0 table-dashboard-th-nowrap"
                    rowClasses="btn-reveal-trigger border-top border-200"
                    headerClasses="bg-200 text-900 border-y border-200"
                    {...paginationTableProps}
                    {...props.baseProps}
                  />
        
                </div>
                <Row noGutters className="px-1 py-3 flex-center">
                <Col className="pl-3 fs--1">
                <CustomTotal {...paginationProps} lastIndex={lastIndex} />
              
              </Col>

                  <Col xs="auto">
                    <Button
                      color="falcon-default"
                      size="sm"
                      onClick={handlePrevPage(paginationProps)}
                      disabled={paginationProps.page === 1}
                    >
                      <FontAwesomeIcon icon="chevron-left" />
                    </Button>
                    {getPaginationArray(paginationProps.totalSize, paginationProps.sizePerPage).map(pageNo => (
                      <Button
                        color={paginationProps.page === pageNo ? 'falcon-primary' : 'falcon-default'}
                        size="sm"
                        className="ml-2"
                        onClick={() => paginationProps.onPageChange(pageNo)}
                        key={pageNo}
                      >
                        {pageNo}
                      </Button>
                    ))}
                    <Button
                      color="falcon-default"
                      size="sm"
                      className="ml-2"
                      onClick={handleNextPage(paginationProps)}
                      disabled={lastIndex >= paginationProps.totalSize}
                    >
                      <FontAwesomeIcon icon="chevron-right" />
                    </Button>
                  </Col>
                </Row>
              </Fragment>
            );
          }}
        </PaginationProvider>
         )}
         </ToolkitProvider>
        
      </CardBody>
    </Card>
  )

};

export default GroupEdit;