arqex / freezer

A tree data structure that emits events on updates, even if the modification is triggered by one of the leaves, making it easier to think in a reactive way.
MIT License
1.28k stars 56 forks source link

Trigger returns undefined #101

Closed YPCrumble closed 7 years ago

YPCrumble commented 7 years ago

@arqex still loving this library! Thanks for building. I have a question about returning a value from a trigger:

I have the following pseudocode in my trigger:

freezer.on('something', function() {
    let someObject = resultOfAnAsyncCall();
    return someObject;
});

and in my code:

let someObject = State.trigger('some-trigger', variable1);
if (someObject != "undefined") { 
  doSomething();
} else {
  console.log('failure');
}

The issue is that if (someObject != "undefined") is running before the async call is able to finish.

Is there a way to make sure the async call finishes and actually passes the variable to someObject so that I can use it in my React code as a variable passed from my trigger?

arqex commented 7 years ago

Hey @YPCrumble

I'm glad you are still enjoying freezer.js, 2 years after its creation I keep thinking it's the simplest way of creating complex react apps :)

The return value is a powerful feature of the event trirggering. The rule is, it returns the return value of the last event callback that doesn't returns undefined.

In your use case I use to work with Promises. It's a pattern very common in the way I use freezer, for example, I want to show a toast to the user when something has been saved:

My component:

render(){
  return <button onClick={ () => this.save() }>Save</button>
}
save(){
  freezer.trigger('thing:save', thingData)
   .then( () => Toast.show('Your thing has been saved') )
  ;
}

My reaction

freezer.on('thing:save', data => {
  return Ajax.post('/thing', data); // This async operation will return a promise
});

Other option would be pass a callback function to the reaction like

freezer.trigger('thing:save', data, clbk)

I personally prefer the first option, it's more elegant and I don't like to pass functions in the arguments.