Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when calling "stopListeningToAll" on a store listening to other stores #27

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

solerbartomeu
Copy link

I don't know if this is the correct way of doing this.

Encountered a crash when calling the function "stopListeningToAll" on a store that listens other stores. The listened stores subscriptions where being removed instead of the listener store subscriptions.

Tried to fix by passing the listener subscriptions to the unsubscriber function so they can be spliced correctly.

David Soler added 2 commits March 29, 2016 11:17
…ultiple stores ( The listened stores subs where being deleted instead of the listener subs)
@devinivy
Copy link
Contributor

Thanks for looking into this! Do you have the time to write a failing test case to reproduce your issue?

@solerbartomeu
Copy link
Author

Here is an example of it happening.

There is an aggregator store that listens with joinTrailing to two stores and then listens normally another store.
Once the aggregator has triggered I want for it to unsubscribe from those stores, but doing so makes it crash.
( It can be that I am not using the API correctly, but this is the only way that I have found to unsubscribe from stores )

Thank you very much.

var Reflux = require('reflux');
var _ = require('lodash');


// First we define some actions
var actions = Reflux.createActions([
    "action01",
    "action02",
    "printInfo"
  ]);


// Here we define three different stores that listen to some actions
const store_01 = Reflux.createStore({

  listenables: actions,

  onAction01: function (){
    console.log("store_01 triggered");
    this.trigger(true);
  }

});

var store_02 = Reflux.createStore({

  listenables: actions,

  onAction02: function (){
    console.log("store_02 triggered");
    this.trigger(true);
  }
});

var store_info = Reflux.createStore({

  listenables: actions,

  onPrintInfo: function () {
    console.log("store_info triggered");
    this.trigger({ msg: Date.now() });
  }
});

// This aggregator will listen to an array of stores until all of them have triggered
// and another store that will only print the Date in this case
function createAggregatorFromStores( stores_to_listen, other_store ) {

  var store_def = {};

  // Generate the conditions from the definition
  store_def.listened_stores = stores_to_listen;

  // This is the function that crashes
  store_def.destroy = function (){
    // Remove reference to stores
    this.listened_stores = [];
    // Stop listening to stores
    this.stopListeningToAll(); // THIS CRASHES WHEN REMOVING THE SUBSCRIBERS
  };

  // Called once other_store triggers
  store_def.printInfoStore = function (info){
    console.log("aggregator printInfoStore: ", JSON.stringify(info));
  }

  // Called once all stores_to_listen have triggered
  store_def.storesReady = function (){
    this.trigger(true);
  }

  store_def.init = function (){
    // Listen to the other_store
    this.listenTo(other_store,this.printInfoStore);

    // Listen to the array of stores stores_to_listen
    const params = _.flattenDeep([this.listened_stores, this.storesReady]);
    this.joinTrailing.apply(this, params);
  };

  // Create the store with the definitio above
  return Reflux.createStore(store_def);
}

// This store listen to the aggregator and will destroy it once it has triggered
var user_store = Reflux.createStore({

  aggregator: null,

  init: function (){
    // Create the array of stores we want to listen to
    const stores_array = [store_01, store_02];
    // Create the aggreagator
    this.aggregator = createAggregatorFromStores(stores_array, store_info);
    // Listen to the aggreagator
    this.listenTo(this.aggregator,this.onDataLoaded);
  },

  // This is called once the aggregator is triggered, finally destroying it
  onDataLoaded: function(){
    console.log("Aggregator triggered!\n");
    this.aggregator.destroy(); // This is the function that crashes
  }
});

actions.action01(); // First action, store_01 will trigger
actions.printInfo(); // This will trigger store_info
actions.action02(); // This will trigger store_02, triggering the aggregator

// Here store_01 and store_02 should trigger but the aggreagator should not be listening to these stores
actions.action01();
actions.action02();

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

Successfully merging this pull request may close these issues.

2 participants