Reputation: 11
I need to catch a specific value of a characteristic instantly onPress. So I wrote a function for this. The problem is, that I couldn't manage to assign the value to a variable so far. What is the best way to solve the problem?
I'm using the flutter_blue example code below: https://pub.dev/packages/flutter_blue#-readme-tab-
My function is:
List<int> _testReadCharacteristic(String uuid) {
List<int> value;
device.services.forEach((ls) async {
//Scans the Liste for all services
ls.forEach((s) async {
// Scans the List of services for a specific service
// do something with s
List<BluetoothCharacteristic> characteristics = s.characteristics;
for (BluetoothCharacteristic c in characteristics) {
// Scans all characteristics
if (c.uuid.toString().toUpperCase().substring(4, 8) == uuid) {
value = await c.read();
print('**************** value is: $value');
}
}
});
});
return value;
}
And the code for the Button is:
RaisedButton(
onPressed: () {
capturedValue = _testReadCharacteristic('1100');
print('***********The captured Value is: $capturedValue');
},
child: const Text('Read Characteristic',
style: TextStyle(fontSize: 20)),
),
When I press the button, I get a print of the capturedValue which is Null first. After that I get a print of value which is exactly the value I want to assign to capturedValue. How can I change the order so that I can work with capturedValue?
Upvotes: 1
Views: 962
Reputation: 978
The problem is that List.forEach
does not respect / await async functions. That means your variable is never assigned in time but instead returned empty and then assigned after the read completes asynchronously.
You can achieve your intended behavior with you have to convert your _testReadCharacteristic
into and sync method as well and await it in your button onPressed
handler. Additionally you need to use Future.forEach
instead of List.forEach
so that the outer method can wait for the result:
List<int> _testReadCharacteristic(String uuid) async {
List<int> value;
await Future.forEach(device.services.forEach((ls) async {
//Scans the Liste for all services
await Future.forEach(ls, (s) async {
// Scans the Liste of services for a specific service
// do something with s
List<BluetoothCharacteristic> characteristics = s.characteristics;
for (BluetoothCharacteristic c in characteristics) {
// Scans all characteristics
if (c.uuid.toString().toUpperCase().substring(4, 8) == uuid) {
value = await c.read();
print('**************** value is: $value');
}
}
});
});
return value;
}
And finally in your onPressed
capturedValue = await _testReadCharacteristic('1100');
Upvotes: 1