Skip to content
This repository has been archived by the owner on Jan 10, 2023. It is now read-only.

Method listening to an action gets called multiple times #44

Open
DhudumVishal opened this issue Nov 27, 2018 · 4 comments
Open

Method listening to an action gets called multiple times #44

DhudumVishal opened this issue Nov 27, 2018 · 4 comments

Comments

@DhudumVishal
Copy link

If a method is listening to an action then for first time it gets hit once, then for next time if user gets back to the same page then the method gets hit twice and on third time its 3 times and increases every time.

Below is a code to simulate the same on click of Next a action is called and on action change the user is taken to second page, but on second time the action listening method gets hit twice.

    import 'package:flutter/material.dart';
    import 'package:flutter_flux/flutter_flux.dart';

    void main() => runApp(MyApp());

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MyHome(),
        );
      }
    }
    //========
    class MyHome extends StatefulWidget {
      @override
      _MyHomeState createState() => _MyHomeState();
    }

    class _MyHomeState extends State<MyHome> with StoreWatcherMixin<MyHome>  {
      AppStore store;
      @override
      void initState() {
        store = listenToStore(appStoreToken);
        changeStatus.listen(_openSetupDialogue);
        super.initState();
      }

      void _openSetupDialogue(dynamic payload){
        if(payload == true) {
          print("method got hit");
          Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
        }
      }

      @override
      Widget build(BuildContext context) {
        return RaisedButton(
          child: Text("Next"),
          onPressed: (){
            changeStatus(true);
          },
        );
      }
    }
    //===========
    class SecondPage extends StatefulWidget {
      @override
      _SecondPageState createState() => _SecondPageState();
    }

    class _SecondPageState extends State<SecondPage> {
      @override
      Widget build(BuildContext context) {
        return RaisedButton(
          child: Text("back"),
          onPressed: (){Navigator.push(context, MaterialPageRoute(builder: (context) =>MyHome()),
            );
          },
        );
      }
    }
    //===========
    class AppStore extends Store {
      bool state = true;
      AppStore(){
        triggerOnAction(changeStatus, (status){
          state = status;
        });
      }
      bool get getAppStore => state;
    }
    final Action changeStatus = Action<bool>();
    final appStoreToken = StoreToken(AppStore());
@iptton
Copy link

iptton commented Mar 7, 2019

maybe you should call unlistenFromStore in dispose method ?

  @override
  void dispose() {
    super.dispose();
    unlistenFromStore(store);
  }

@DhudumVishal
Copy link
Author

DhudumVishal commented Mar 14, 2019

@iptton
I did tried your suggestion but it the issue is still there, the method gets hit multiple times.
Bellow is the updated code
import 'package:flutter/material.dart';
import 'package:flutter_flux/flutter_flux.dart';

  void main() => runApp(MyApp());

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        home: FirstPage(),
      );
    }
  }

  //===========
  class FirstPage extends StatefulWidget {
    @override
    _FirstPageState createState() => _FirstPageState();
  }

  class _FirstPageState extends State<FirstPage> {
    @override
    Widget build(BuildContext context) {
      return RaisedButton(
        child: Text("next"),
        onPressed: (){
          Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
        },
      );
    }
  }
  
  //========
  class SecondPage extends StatefulWidget {
    @override
    _SecondPageState createState() => _SecondPageState();
  }

  class _SecondPageState extends State<SecondPage> with StoreWatcherMixin<SecondPage>  {
    AppStore store;
    @override
    void initState() {
      store = listenToStore(appStoreToken);
      store.listen(_openSetupDialogue);
      super.initState();
    }
    @override
    void dispose() {
      super.dispose();
      unlistenFromStore(store);
    }

    void _openSetupDialogue(dynamic payload){
        print("method got hit");
    }

    @override
    Widget build(BuildContext context) {
      return RaisedButton(
        child: Text("back"),
        onPressed: (){
          changeStatus(true);
          Navigator.pop(context);
        },
      );
    }
  }
  
  //===========
  class AppStore extends Store {
    bool state = true;
    AppStore(){
      triggerOnAction(changeStatus, (status){
        state = status;
      });
    }
    bool get getAppStore => state;
  }
  final Action changeStatus = Action<bool>();
  final appStoreToken = StoreToken(AppStore());

@DhudumVishal
Copy link
Author

The issue is unlistenFromStore(store); is not working in my case,

Workaround: add listener only once on App start up.

@mvresh
Copy link

mvresh commented Nov 1, 2019

Instead, you could try calling unlistenFromStore(store); when the routing takes place. Reason why it's not working in your case is that it's not being disposed in the first place.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants