-
-
Notifications
You must be signed in to change notification settings - Fork 392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OBPIH-5264 Create a custom hook for fetching logic on new list pages #3741
Conversation
10ee1a4
to
b39257c
Compare
.catch(() => { | ||
setLoading(false); | ||
return Promise.reject(new Error(translate('react.productsList.fetch.fail.label', 'Unable to fetch products'))); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you are not the author of this, but could we maybe add finally
, so we setLoading(false)
only once?
Apply for each hook if the same thing is there
currentParams: params, | ||
}); | ||
}) | ||
.catch(() => Promise.reject(new Error(translate('react.stockMovement.outbound.fetching.error', 'Unable to fetch outbound movements')))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see setLoading(false)
if an error occurs? Consider using finally
})); | ||
|
||
const fireFetchData = () => { | ||
sourceRef.current = CancelToken.source(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bring back the comment that was here
if (currentLocation?.id) { | ||
sourceRef.current.cancel('Fetching canceled'); | ||
} | ||
}, [currentLocation?.id]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you removed return
from this useEffect
- it was supposed to be a cleanup function (return
statement inside useEffect
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like we can move quite a lot of stuff into useTable hook.
Since every TableHook has a loading state a tableData state with data, pages, totalCount and currentParams we can make it more generic and move it into useTable hook
const [loading, setLoading] = useState(true);
const [tableData, setTableData] = useState({
data: [],
pages: -1,
totalCount: 0,
currentParams: {},
});
same with fetching table data,a ll it does it fetches the data and set it in tabelData state which means we can just pass the url and params to the useTable hook like:
const url = "openboxes/api/invoice
const parmas = { ... }
const {} = useTable({ url, params })
I see that each list page has it own unique error when fetch is unsuccessful so this can also be an optional parameter that is passed to the useTable hook like an errorMessage
cc @kchelstowski
totalCount: res.data.totalCount, | ||
pages: Math.ceil(res.data.totalCount / tableState.pageSize), | ||
currentParams: params, | ||
totalPrice: res.data.totalPrice, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really like that totalPrice
is defined in this hook. This is a specific data that from what I can tell is used in only one case which is Purchase Orders.
I think a solution to that could be having an optional callback onFetchedData(data) => { ... } that is passed to the useTable hook like
in useTable.jsx
.then((res) => {
setTableData({
data: res.data.data,
totalCount: res.data.totalCount,
pages: Math.ceil(res.data.totalCount / tableState.pageSize),
currentParams: params,
});
if (onFetchedData) onFetchedData(res.data)
and in usePurchaseOrderData.jsx
const [totalPrice, setTotalPrice] = useState(0);
const { ... } = useTable({ params, url, onFetchedData: (data) => setTotalPrice(data.totalPrice) })
....
return {
...,
tableData: { ...tableData, totalPrice }
}
I feel like we should keep useTable hook as generic as possible and avoid having to add some single case solutions because eventually this component will grow out of control and will become messy
const url = '/openboxes/api/products'; | ||
const messageId = 'react.productsList.fetch.fail.label'; | ||
const defaultMessage = 'Unable to fetch products'; | ||
const getSortingParams = tableState => (tableState.sorted.length > 0 ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also feel like getSortingParams
can be moved to useTableData.
The logic for this seems very generic across all of the use*TableData hooks and you would only need to pass the sortColumn: 'lasUpdated'
and sortOrder: 'desc'
as params
56f9d03
to
c97730f
Compare
import { translateWithDefaultMessage } from 'utils/Translate'; | ||
|
||
const useInboundListTableData = (filterParams) => { | ||
const messageId = 'react.stockMovement.inbound.fetching.error'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be named as errorMessageId
...sortingParams, | ||
}, (value) => { | ||
if (typeof value === 'object' && _.isEmpty(value)) return true; | ||
return !value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this function's arguments should be as ( { offset, currentLocation, state, sortingParams })
, because having so many arguments it might be difficult to follow the order of arguments. Making this change, you'll allow yourself not to pass them in the order that you have now.
Moreover I think that for better readability, it would be good to destructure filterParams
, having:
const { receiptStatusCode, origin, destination, requestedBy, createdBy, updatedBy } = filterParams
and proceed with that, so we have:
origin: origin?.id
|
||
|
||
useEffect(() => { | ||
if (!isShipmentStatusesFetched || shipmentStatuses.length === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for length === 0
, could be only if (shipmentStatuses.length)
pages: Math.ceil(res.data.totalCount / tableState.pageSize), | ||
currentParams: params, | ||
}); | ||
if (onFetchedData) onFetchedData(res.data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try onFetchedData?.(res.data)
instead of having this if - if it doesn't work (but it should), at least follow the convention we have, so using brackets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know that optional chaining works with functions. Thanks for that
@@ -14,24 +14,32 @@ import exportFileFromAPI from 'utils/file-download-util'; | |||
import { translateWithDefaultMessage } from 'utils/Translate'; | |||
|
|||
const useInboundListTableData = (filterParams) => { | |||
const messageId = 'react.stockMovement.inbound.fetching.error'; | |||
const errorMessageId = 'react.stockMovement.inbound.fetching.error'; | |||
const defaultMessage = 'Unable to fetch inbound movements'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changing from messageId
to errorMessageId
as I requested, you should also change the defaultMessage
naming to defaultErrorMessage
@@ -77,9 +81,10 @@ const useTableData = ({ | |||
pages: Math.ceil(res.data.totalCount / tableState.pageSize), | |||
currentParams: params, | |||
}); | |||
if (onFetchedData) onFetchedData(res.data); | |||
// eslint-disable-next-line no-unused-expressions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this comment eslint shows that there is an unused expression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bring it back to if
version then, but remember about brackets I mentioned earlier. We should avoid disabling eslint even though it is working fine. Maybe some kind of bumping up eslint even higher would help, but it's not the scope of this ticket, I just wanted to know out of curiosity if it would work so thanks for checking that
No description provided.