Notify view from service layer

Hi, All

I am creating Flutter Mobile app with MVVM pattern. Here my question is how to notify to views from service class? For example, I am getting data from service and display in UI, after that I am checking the device is in Geo-fence in some service class. Once I confirm that the device is in within Geo-fence I need to update the UI. If I do the above logic in View model we can notify to view but I am doing in service class because the same service class I can use for other purpose. In AngularJs, I was using $on and $boradcast option. How do I achieve this in flutter? Please help me and give me the sample.

Thanks
Manivel

Hi @Manivel_Ponnusamy, you could use the Provider package.

With this you can create a Provider of type ChangeNotifierProvider and put it on top of the Widget you want to use it in. Then call context.select<ServiceClass, bool>((service)=>service.inGeoFence) This will trigger the rebuild of the widget every time the value changes.

Using context.select you guarantee that the Widget only rebuilds when that param changes and not when any other thing in the Service changes.

Hi, F.Iucadetena

Thank you so much for your help. Will it trigger automatically, if I assign value in boolean variable in service call?

Thanks
Manivel

No, you need to create a Class that extends ChangeNotifier, there create setters and getters and in the set function you call notifyListeners(). That will notify all widgets listening to rebuild. Like this:

import 'package:flutter/material.dart';

class GeoFenceState with ChangeNotifier {
  bool _inGeo = 0;

  get inGeoFence => _inGeo;
  set inGeoFence(bool inside) {
    _inGeo = inside;
    notifyListeners();
  }
}

Be aware that if you create an object and update the whole object, all listeners will react. That is why it is good for performance to create getters and setters for each property if you have complex classes. For example if you have a User class, don’t create a UserState with ChangeNotifier that has a User _user inside and change that object, but instead extend the User Class and add setters and getter for the value you wish to update.

For example:

class User {
  final String name;
  final String mail;
  final String avatar;

  User({
    @required this.name,
    @required this.mail,
    @required this.avatar,
  });
}

class UserState extends User with ChangeNotifier {
UserState():super(
name: '',
mail: '',
avatar:'',
);

  String get name => super.name;

  set name(String value) {
    super.name = value;
    notifyListeners();
  }
}

You can add the getters and setters straight into the User class, but I don’t like to be able to modify straight into the class, I prefer to use the User class only as a Type to get intellisense.
For anything that is going to be changing for a limited period of time and affecting the UI I create a separate class. So later when I come back, I know where things can be change and listen to, and where not.

Just a preference. On that same tone, I normally create a separate state folder inside of my models folder and hold files for the different ChangeNotifiers I create. Just to be cleaner.

Hop it helps :wink:

Thanks for your reply. I will try out and let you know the output.

Thanks
Manivel

1 Like