react-bootstrap-table2 icon indicating copy to clipboard operation
react-bootstrap-table2 copied to clipboard

Custom Filter Issue: Uncaught TypeError: Cannot read properties of undefined (reading 'afterFilter')

Open jaridgeway opened this issue 3 years ago • 1 comments

Question I am getting an error when trying to use a custom data filter. The filter looks like it is working based on the console.logs, but the table is not actually filtering anything.

Error: context.js:140 Uncaught TypeError: Cannot read properties of undefined (reading 'afterFilter') at FilterProvider.doFilter (context.js:140) at context.js:103 at Object.onFilter (context.js:112) at DateFilter.filter (Filter.js:16) at HTMLUnknownElement.callCallback (react-dom.development.js:3945) at Object.invokeGuardedCallbackDev (react-dom.development.js:3994) at invokeGuardedCallback (react-dom.development.js:4056) at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4070) at executeDispatch (react-dom.development.js:8243) at processDispatchQueueItemsInOrder (react-dom.development.js:8275)

Screenshots If applicable, add screenshots to help explain your problem. Filtered Data Screen Shot 2022-01-08 at 12 49 15 PM

Original data: Screen Shot 2022-01-08 at 12 49 50 PM

Code:

import React, { useState, useEffect } from "react"; import { LinkContainer } from "react-router-bootstrap"; import { Button } from "react-bootstrap"; import { useDispatch, useSelector } from "react-redux"; import Loader from "../components/Loader"; import Message from "../components/Message"; import DateFilter from "../components/Filter"; import { listOrders, deliverOrder } from "../actions/orderActions"; import { ORDER_DELIVER_RESET } from "../constants/orderConstants"; import BootstrapTable from "react-bootstrap-table-next"; import filterFactory, { customFilter } from 'react-bootstrap-table2-filter';

function OrderListScreennew({ history }) { const dispatch = useDispatch();

const orderList = useSelector((state) => state.orderList); const { loading, error, orders } = orderList;

const userLogin = useSelector((state) => state.userLogin); const { userInfo } = userLogin;

const orderDeliver = useSelector((state) => state.orderDeliver); const { loading: loadingDeliver, success: successDeliver } = orderDeliver;

const filterDate = (filterVals, data) => { console.log(filterVals); console.log(data); let min= new Date(parseInt(filterVals.min.substring(0,4),10),parseInt(filterVals.min.substring(5,7),10)-1,parseInt(filterVals.min.substring(8,10),10)) let max= new Date(parseInt(filterVals.max.substring(0,4),10),parseInt(filterVals.max.substring(5,7),10)-1,parseInt(filterVals.max.substring(8,10),10))

const filteredData = data.filter(
  // here this is not books but this is undefined here
  row => {
     let datejs= new Date(parseInt(row.date.substring(0,4)),parseInt(row.date.substring(5,7))-1,parseInt(row.date.substring(8,10)))
     console.log(datejs)
     console.log(min)
     console.log((((min && datejs >= min) || !filterVals.min) && ((max && datejs <= max) || !filterVals.max)))

    return (((min && datejs >= min) || !filterVals.min) && ((max && datejs <= max) || !filterVals.max))}
);
console.log(filteredData);
return filteredData;

};

const instructionsFormatter = (cell, row) => { return row.orderItems.map((item, index) => { return

{item.instructions}
; }); }; const orderFormatter = (cell, row) => { return row.orderItems.map((item, index) => { return
{item.name}
; }); }; const ratingFormatter = (cell, row) => { return row.orderItems.map((item, index) => { return
{item.rating}
; }); }; // const dateFormatter = (cell, row) => { // return
{cell.substring(0, 10)}
;

// };

const timeFormatter = (cell, row) => { return cell ? (

{cell.substring(11, 16)}
) : ( <Button type="button" className="btn btn-block" onClick={() => deliverHandler(row)} > Mark as Delivered </Button> ); };

const columns = [ { dataField: "_id", text: "ID", sort:true }, { dataField: "user.name", text: "Name", }, { dataField: "date", text: "Date", //formatter: (cell, row) => dateFormatter(cell, row), filter: customFilter({ onFilter: filterDate }), filterRenderer: (onFilter, column) => ( <DateFilter onFilter={onFilter} column={column} /> ) }, { dataField: "totalPrice", text: "Total Price", }, { dataField: "tip", text: "Tip", }, { dataField: "isPaid", text: "Paid", sort:true, }, { dataField: "table", text: "Table", sort:true, }, { dataField: "orderItems.name", text: "Order", formatter: (cell, row) => orderFormatter(cell, row),

},
{
  dataField: "orderItems.instructions",
  text: "Instructions",
  formatter: (cell, row) => instructionsFormatter(cell, row),
},
{
  dataField: "orderItems.rating",
  text: "Spice",
  formatter: (cell, row) => ratingFormatter(cell, row),
},
{
  dataField: "deliveredAt",
  text: "Finished",
  formatter: (cell, row) => timeFormatter(cell, row),
},

];

useEffect(() => { if (userInfo && userInfo.isAdmin) { dispatch(listOrders()); } else { history.push("/login"); } if (successDeliver) { dispatch({ type: ORDER_DELIVER_RESET }); } }, [dispatch, history, userInfo, successDeliver]);

const deliverHandler = (order) => { dispatch(deliverOrder(order)); };

return (

Orders

{loading ? ( <Loader /> ) : error ? ( <Message variant="danger">{error}</Message> ) : ( <BootstrapTable striped hover keyField="_id" data={orders} columns={columns} condensed filter={ filterFactory() } /> )}
); }

export default OrderListScreennew;

Data: I am using data that is in JSON. It is an array of objects. I pasted one of the objects below.

[{"_id":1,"orderItems":[{"_id":1,"name":"Latte","qty":1,"rating":0,"instructions":null,"price":"3.00","image":"/images/placeholder.png","product":1,"order":1}],"shippingAddress":{"_id":1,"address":"1781 S Fish Hatchery Rd","city":"Fitchburg","postalCode":"53575","country":"US","shippingPrice":null,"order":1},"user":{"id":1,"_id":1,"username":"[email protected]","email":"[email protected]","name":"James","isAdmin":true},"date":"2021-12-24","paymentMethod":"PayPal","taxPrice":"0.25","tip":"0.45","totalPrice":"3.70","table":1,"isPaid":false,"paidAt":null,"isDelivered":true,"deliveredAt":"2022-01-04T11:43:24.448221Z","createdAt":"2021-12-24T21:30:42.081771Z"}, ...]

codesandbox

I have this codesandbox that is working. There are only a couple of differences between this one and mine.

  1. My data is a bit more complicated.
  2. I am creating this inside of a function that I am using to route my screens
  3. I am importing the class used for rendering.

The only thing I can think of is that my data must be different somehow.

(https://codesandbox.io/s/date-filter-h60ye?file=/src/App.js)

jaridgeway avatar Jan 08 '22 10:01 jaridgeway

I swapped out the data that I am using in my actual code for the same data in the codesandbox. I ended up with the same error, so something else must be going wrong

jaridgeway avatar Jan 09 '22 09:01 jaridgeway