2

I am new to Flutter and stuck with this I have a page that uses a class named GoogleMapsNotifier with ChangeNotifier and when I pop the page I want to dispose the Stream inside this class (last function).

class GoogleMapsNotifier with ChangeNotifier {
  final geolocatorService = GeolocatorService();
  final placesService = PlacesService();
  final markerService = MarkerService();

  Position? currentLocation;
  List<PlaceSearch> searchResults = [];
  StreamController<Place> selectedLocation = BehaviorSubject<Place>();
  StreamController<LatLngBounds> bounds = BehaviorSubject<LatLngBounds>();
  late Place selectedLocationStatic;
  List<Marker> markers = <Marker>[];

  GoogleMapsNotifier() {
    setCurrentLocation();
  }

  setCurrentLocation() async {
    currentLocation = await geolocatorService.determinePosition();
    selectedLocationStatic = Place(
        geometry: Geometry(
          location: Location(
              lat: currentLocation!.latitude, lng: currentLocation!.longitude),
        ),
        name: '',
        vicinity: '');
    notifyListeners();
  }

  searchPlaces(String searchTerm) async {
    searchResults = await placesService.getAutocomplete(searchTerm);
    notifyListeners();
  }

  setSelectedLocation(String placeId) async {
    var sLocation = await placesService.getPlace(placeId);
    selectedLocation.add(sLocation);
    selectedLocationStatic = sLocation;
    searchResults = [];
    markers = [];
    var newMarker = markerService.createMarkerFromPlace(sLocation);
    markers.add(newMarker);
    var _bounds = markerService.bounds(Set<Marker>.of(markers));
    bounds.add(_bounds as LatLngBounds);
    notifyListeners();
  }

  @override
  void dispose() {
    selectedLocation.close();

    super.dispose();
  }
}

and then I have a Go Back button that pops the page and I call this function with Provider before.

onTap: () async {
                    Provider.of<GoogleMapsNotifier>(context, listen: false)
                        .dispose();
                    Navigator.pop(context);
                  },

It works fine for the first time but when I enter the page for the second time and press Go Back button again, it return an error

Unhandled Exception: A GoogleMapsNotifier was used after being disposed. E/flutter (13173): Once you have called dispose() on a GoogleMapsNotifier, it can no longer be used.

How can I fix this?

TonyWyomy
  • 570
  • 5
  • 17

1 Answers1

5

The Provider should be inside the Route you push. If you use a global provider, the instance of GoogleMapsNotifier will always be the same. Therefore the second time you go on the page it won't work (since it's the same instance you already disposed the first time)

Here is a concrete example

// GOOD
runApp(MaterialApp(...));

...

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => ChangeNotifierProvider<GoogleMapsNotifier>(
      create: (_) => GoogleMapsNotifier(),
      child: ...,
    ),
  ),
);


// BAD
runApp(
  ChangeNotifierProvider<GoogleMapsNotifier>(
    create: (_) => GoogleMapsNotifier(),
    child: MaterialApp(
      home: ...,
    ),
  )
);

...

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => ...,
  ),
);
Lulupointu
  • 3,364
  • 1
  • 12
  • 28
  • ok, if I construct my MaterialPageRoute like this to go to this page its not showing the error but now do I access this provider now? before I was just declaring it as a final final googleMapsNotifier = Provider.of(context); – TonyWyomy Sep 22 '21 at 23:40
  • Well you can still access it with Provider.of(context) when you are in the right Route can't you? – Lulupointu Sep 23 '21 at 00:02
  • the problem is that there are no any errors now but looks like notifylisteners() does not work. I can print all the requests from the screen to the `GoogleMapsNotifier with ChangeNotifier` class but nothing returns to the page. If I come back to the previous MaterialPageRoute builder - it works fine. Any ideas – TonyWyomy Sep 23 '21 at 00:52
  • If you want your change notifier updates to rebuild the UI you have to use ChangeNotifierProvider. I updated my answer. – Lulupointu Sep 23 '21 at 08:43