Flutter : Provider do not update data in the previous screen

768 views Asked by At

In my Flutter application I am using Provider version 4.0.4 to manage the state of my app. In basic terms, my app will list down the nearby companies with their rating. users can select a organisation, open it and add their rating as well, so the final rating will be updated. I am using the Consumer concept in Provider to handle the tasks.

  1. In NearByPlacesPage class I am listing down the companies around me with rating information. User can click on a company and they will be taken to OrganizationPage page.
  2. In OrganizationPage class, the rating is displayed again. user can add their rating to the system. Then the rating information in both OrganizationPage page and NearByPlacesPage (back page) need to be updated.

The issue is, when the user update the rating, the rating in OrganizationPage get updated but not NearByPlacesPage in back stack. When we go back to NearByPlacesPage, we can clearly see the old rating values. The page need to be reloaded to get updated values.

Below are the important sections in my code

NearByPlacesPage

    class NearByPlacesPage extends StatelessWidget {
      int orgTypeID;
      String orgTypeName;
    
      NearByPlacesPage(this.orgTypeID, this.orgTypeName);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: MultiProvider(
            providers: [
              ChangeNotifierProvider(create: (context) => RatingService()),
            ],
            child: SingleChildScrollView(
              child: _NearByPlacesPageUI(orgTypeID, orgTypeName),
            ),
          ),
          appBar: AppBar(
            title: Text(orgTypeName),
          ),
        );
      }
    }

class _NearByPlacesPageUI extends StatefulWidget {
  int orgTypeID;
  String orgTypename;

  _NearByPlacesPageUI(this.orgTypeID, this.orgTypename);

  @override
  State<StatefulWidget> createState() {
    return _NearByPlacesPageState();
  }
}

class _NearByPlacesPageState extends State<_NearByPlacesPageUI> {
    @override
  Widget build(BuildContext context) {
    Consumer<RatingService>(builder: (context, data, child){
    return Flexible(
        child: ListView.builder(
            itemCount: orgList.length,
            itemBuilder:(BuildContext context, int index) {
                Organization organization = orgList[index];

                if (organization.isDisabled != true) {
                   RatingValue ratingValue = data.getData();

                    return Container(
                        margin: EdgeInsets.only(
                            top: 5, left: 5, right: 5),
                            child: _buildPlace(organization, ratingValue));
                } else {
                    return Container();
                 }
            },),
        );
    },);
  }
}

OrganizationPage

class OrganizationPage extends StatelessWidget {
  Organization organization;
  String orgTypeName;

  OrganizationPage(this.organization, this.orgTypeName);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: _OrganizationPageUI(organization, orgTypeName),
      ),
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text(organization.name),
      ),
    );
  }
}

class _OrganizationPageUI extends StatefulWidget {
  Organization organization;
  String orgTypeName;

  _OrganizationPageUI(this.organization, this.orgTypeName);

  @override
  State<StatefulWidget> createState() {
    return _OrganizationPageState();
  }
}

class _OrganizationPageState extends State<_OrganizationPageUI> {

    @override
  Widget build(BuildContext context) {
    Consumer<RatingService>(
       builder: (context, data, child) {

        Consumer<RatingService>(

            return Row(
                children: <Widget>[
                    Container(
                        margin: EdgeInsets.only(top: 10, left: 10),
                        child: Text(daa.getData()
                        style: Theme.of(context).textTheme.bodyText2.apply(color: Colors.grey),
                        ),
                    ),
                ],
            );
                        
        ),
            
        }
    }
}

In OrganizationPage there is a AlerDialog, which allows the user to rate and save. When saved, it will call another method which will reload the data.

Widget _ratingDialog(double _rating) {
    RatingService _ratingService =
        Provider.of<RatingService>(context, listen: false);
    Rating _rating = _ratingService.returnRating();
    double _ratingValue = _ratingService.returnRating().rating;

    return AlertDialog(
      title: const Text("Your Rating"),
      actions: [
        new FlatButton(
          child: const Text("Save"),
          //onPressed: () => Navigator.pop(context),
          onPressed: () async {
            Rating rating = Rating(
                    idrating:
                        _rating.idrating != null ? _rating.idrating : null,
                    user: _user,
                    organization: widget.organization,
                    rating: _ratingValue,
                    dateCreated: DateTime.now().millisecondsSinceEpoch,
                    lastUpdated: DateTime.now().millisecondsSinceEpoch);

                await _ratingService.saveOrUpdateRating(rating, authToken);
                _loadRatingByUserAndOrganization(authToken);
                _loadRatingValueByOrganization(authToken);

                Navigator.pop(context);
          },
        ),
      ],
    );
  }

  Future _loadRatingByUserAndOrganization(String authToken) {
    RatingService _ratingService =Provider.of<RatingService>(context, listen: false);

    return _ratingService.getRatingByUserAndOrganization(
        _authService.getDatabaseUser().user.iduser,
        widget.organization.idorganization,
        authToken);
    
  }

RatingService

This is the class which is responsible for calling notifyListeners(). It will be triggered by the above AlertDialog and the expected behaviour is to reload data in both OrganizationPage and NearByPlacesPage

class RatingService with ChangeNotifier {

  List<RatingValue> _ratingValueList ;

  List<RatingValue> getData()
  {
    return _ratingValueList;
  }

  //Load rating by user and Organization
  Future<void> getRatingByUserAndOrganization(int idUser, int organizationID, String authToken) async {
 
    try {
      var data = await http.get(
        _navLinks.getRatingByUserAndOrganization(idUser, organizationID),
        headers: {HttpHeaders.authorizationHeader: "Bearer $authToken"},
      );
      print(data.body);
      _rating = Rating.fromJson(convert.json.decode(data.body));
   

      notifyListeners();
    } catch (error) {
      print(error);
      throw error;
    }
  }
}

What I have I done wrong?

0

There are 0 answers