in Flutter Provider How to check when data received in consumer is updated
Solution 1
You can do this by 02 ways
- Using Selector() instead of Consumer().
- Using PuhserDataProvider() class.
1. Using Selector() instead of Consumer().
An equivalent to Consumer that can filter updates by selecting a limited amount of values and prevent rebuild if they don't change.
2. Using PuhserDataProvider() class.
Check your logic before calling notifyListers()
Here
class PuhserDataProvider extends ChangeNotifier {
final Pusher pusher;
Logger log = getLogger("PuhserDataProvider");
//I changed _devicePusherData into _devicePusherDataGps
//I dont know Data type of your .gps , so temperary i said it as Object , you need to change it
Object _devicePusherDataGps;
//I changed devicePusherData into devicePusherDataGps
//I dont know Data type of your .gps , so temperary i said it as Object , you need to change it
Object get devicePusherDataGps => _devicePusherDataGps;
//counter variable with default value 1 ,this will increment when each time value changed
int counter = 1;
PuhserDataProvider(String imei, String token, String pusherKey)
: pusher = Pusher(
pusherKey,
PusherOptions(
cluster: 'eu',
authEndpoint: AUTH_URL,
auth: PusherAuth(headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
'Accept': 'application/json'
})),
) {
Channel channel = pusher.subscribe('private-$imei-send');
channel.bind(
'deviceevent',
(data) =>
_setDeviceData(DevicePusherData.fromJson(json.decode(data)[0])));
}
_setDeviceData(DevicePusherData devicePusherData) {
if (_devicePusherDataGps == null) {
_devicePusherDataGps = devicePusherData.gps;
}
else{
if (devicePusherData.gps != _devicePusherDataGps) {
//This will check value changes for 5 times.
if (counter == 5) {
counter = 1;
this._devicePusherDataGps = devicePusherData.gps;
notifyListeners();
} else {
counter++;
}
}
}
}
}
In above class, setter function was changed only to set gps value. Because in your question you said that you want to check Lat Lang value individually, So I create seperate setter method for it.
And Now in Consumer widget you need to change data.devicePusherData.gps
into data.devicePusherDataGps
final lat = extractLat("${data.devicePusherDataGps}");
final lang = extractLang("${data.devicePusherDataGps}");
Hope this will help you. If you have any question on above, please comment I will try to help. (Sometimes code just have syntax errors, because I didnt have your json model class to import)
Solution 2
Your class should be looks like:
PusherDataProvider with ChangeNotifier {
final Object _value;
set value(Object value) {
if (value != _value) {
_value = value;
// Notify listeners only when data changed
notifyListeners();
}
Object get value => _value;
}
}
So now yor Consumer
's builder will be called when data is changed. Declare a counter variable which will be checked inside builder.
Javeed Ishaq
I am a passionate Software Developer, I love to build mobile apps. My expertise is Flutter, Android, Kotlin, Jetpack Compose, and Firebase.
Updated on December 26, 2022Comments
-
Javeed Ishaq over 1 year
How can we check if data receiving in
consumer
viaprovider
is updated or changed, I want to add a buffer to check theLat Lang
value before passing togoogle_maps_flutter
, I want to check the value 5 times before passing to thegoogle_maps_flutter
widget to update the locationConsumer<PuhserDataProvider>(builder: (context, data, child) { if (data.devicePusherData != null) { final lat = extractLat("${data.devicePusherData.gps}"); final lang = extractLang("${data.devicePusherData.gps}"); log.w(lat); log.w(lang); return GoogleMap( onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, myLocationButtonEnabled: false, initialCameraPosition: CameraPosition( target: LatLng(lat, lang), zoom: 16, ), markers: [ Marker( markerId: MarkerId('0'), position: LatLng(lat, lang), onTap: () => setState(() => selectedPoint = LatLng(lat, lang))) ].toSet(), onTap: (point) => setState(() => selectedPoint = null), ); } else { return Container( height: MediaQuery.of(context).size.height * 0.8, width: double.infinity, child: Center(child: CircularProgressIndicator()), ); } }),
the provider used is a change notifier provider, Default constructer functions call the pusher to get values, the setter, and getter function to retrieve values.
class PuhserDataProvider extends ChangeNotifier { final Pusher pusher; Logger log = getLogger("PuhserDataProvider"); DevicePusherData _devicePusherData; DevicePusherData get devicePusherData => _devicePusherData; OBDPuhserData _obdPusherData; OBDPuhserData get obdPusherData => _obdPusherData; PuhserDataProvider(String imei, String token, String pusherKey) : pusher = Pusher( pusherKey, PusherOptions( cluster: 'eu', authEndpoint: AUTH_URL, auth: PusherAuth(headers: { 'Authorization': 'Bearer $token', 'Content-Type': 'application/json', 'Accept': 'application/json' })), ) { Channel channel = pusher.subscribe('private-$imei-send'); channel.bind('obd-event', (data) => _setOBDData(OBDPuhserData.fromJson(json.decode(data)[0]))); channel.bind( 'deviceevent', (data) => _setDeviceData(DevicePusherData.fromJson(json.decode(data)[0]))); } _setDeviceData(DevicePusherData devicePusherData) { this._devicePusherData = devicePusherData; notifyListeners(); } _setOBDData(OBDPuhserData obdPusherData) { this._obdPusherData = obdPusherData; notifyListeners(); } }
-
dilshan over 3 yearsYou can check value 5 times inside your PusherDataProvider class. After checking 5 times and if update or changed occurs then you can call notifyListeners() method.
-
dilshan over 3 yearsif you show the PusherDataProvider class, it helps to give better solution
-
Javeed Ishaq over 3 yearsthanks, @TDM for your Kind comment, I have added the code for PusherDataProvider class
-
-
Javeed Ishaq over 3 yearsThanks, @BambinoUA I am looking into implementing code as per your instructions
-
Javeed Ishaq over 3 yearsthanks TDM for you kind perfect answer :)