The problem we have is that there doesn’t seem to be a way to reset the scanner’s data, even if you unmount and remount a dedicated scanning component.
Example
Here’s an naive example. We unmount and remount the <Scanner /> component after the merchant scans a barcode successfully and clicks “Scan again”, but in practice the useScannerDataSubscription()'s data variable will not reset state.
Therefore the useEffect on the data will fire immediately.
Hi @Dylan, thanks for the feedback. Unfortunately, this is due to the nature of subscribables, and the way they are held onto in memory on the POS side so long as the extension is running. I see this is a bad API design for your use case, so I think what we can look into is providing a reset() function as a part of the object returned by the useScannerDataSubscription hook. I’ll create a ticket in our backlog to try and get this in for a future release.
@RobDukarski I don’t think there’s a work around for completely resetting the state of the data, if getting it to be undefined is what you’re trying to accomplish. Can you provide a specific example of what you’re trying to achieve on a higher level, and I’ll see if I can think of an approach?
@JS_Goupil For us, the biggest pain point is that merchants have to close the tile and re-open it to scan multiple barcodes. Since that’s the only way to clear the state of the data variable.
We’ve tried using a ref in combination with the data variable from the hook, but still not able to find a workaround to re-load the Camera without the useEffect on the data variable firing immediately.
@Dylan , interesting, I would have thought that you can still scan multiple items serially without closing the modal. ie The scanner should replace the current value with the new value. You’re saying that’s not the case?
@JS_Goupil You can, but the problem is writing a useEffect that can differentiate between scans, since you can only depend on the data attribute.
In our case we need to make an external API call to process the information on the barcode.
So we need a loading state, then a results state.
There’s quite a bit of data extracted, so we need to minimize/unmount the camera component while viewing results.
Then when you attempt to remount the Scan component, since data is populated from the first scan, it’ll fire the useEffect statement process the old data, and then you’re looping the customer back to the Results state before they have the opportunity to scan a different barcode.
// Scanner.js example
const { data } = useScannerDataSubscription();
useEffect(() => {
if(!data) return;
// first effect call data == null -> data == "first scan"
// second effect call data === "first scan", so someApiRequest it fires immediately again
someApiRequest
.then(() => { setState('processed') }
}, [data])
This may not be helpful but would it be possible to add some sort of unique event identifier to the data being sent each call so that if it receives the same identifier again it will know to ignore it and you can proceed like you want?
Just trying to help think of a workaround for the time being…