I'm building a receipt scanner using the Flutter OCR plugin provided by Veryfi.
Here's a Stream function that reads an image and returns a dynamic array containing the necessary values.
Note the credentials from VeryfiDart
are removed.
The showImage
variable is an image file either captured from a camera or selected from an image gallery.
class ReceiptProcessor {
Future<dynamic> processReceipt(File image) async {
List<List<Widget>> itemList = [];
Uint8List imageData = image.readAsBytesSync();
String fileData = base64Encode(imageData);
VeryfiDart client = VeryfiDart(
'ClientId',
'ClientSecret',
'Username',
'ApiKey',
);
await client.processDocument('receipt.jpg', fileData).then(
(response) {
String totalPayment = response['total'].toString();
String currencyCode = response['currency_code'];
String vendorName = response['vendor']['name'];
for (var item in response['line_items']) {
String description = item['description'];
String quantity = item['quantity'].toString();
String totalCost = item['total'].toString();
List<Widget> itemInfo = [
Text(description),
Text(quantity),
Text(totalCost)
];
itemList.add(itemInfo);
}
List<dynamic> processedDetails = [
Text(totalPayment),
Text(currencyCode),
Text(vendorName),
itemList
];
return processedDetails;
},
).catchError((error) {
return Text('Error');
});
}
}
Apparently the data are properly fetched, but issues occur when trying to retrieve the data and display it.
class ReceiptDetailsView extends StatefulWidget {
const ReceiptDetailsView({Key? key}) : super(key: key);
@override
State<ReceiptDetailsView> createState() => _ReceiptDetailsViewState();
}
class _ReceiptDetailsViewState extends State<ReceiptDetailsView> {
Future<dynamic> loadProcessedReceipt() async {
ReceiptProcessor rp = ReceiptProcessor();
return await rp.processReceipt(showImage!);
}
late Future<dynamic> processedReceipt;
@override
void initState() {
super.initState();
processedReceipt = loadProcessedReceipt();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
child: FutureBuilder<dynamic>(
future: processedReceipt,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return CircularProgressIndicator();
case ConnectionState.done:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (snapshot.data != null) {
return Text('Success');
}
}
return Text('Error');
},
),
);
}
}
I used a FutureBuilder
here, but continuously an empty snapshot containing a null data is returned; thus, 'Error'
is displayed on the view.
Any suggestions would be appreciated. A 'Success'
Text should appear when the snapshot data is properly retrieved.