MeteorFlux Flow

I tried RefluxJS for simple ecommerce, simple, less code and less boilerplate than Flux

I’m all for something like this. I started looking into Flux because it describes clearly some features and organizational flow I would like to use.

But I started to think that a lot of the flux features and concepts seem like they are built into Meteor and Blaze,. However, it’s not obvious how to structure these built-in features to create a flow like Flux or PureMVC.

Just giving one example to use Meteor features along the style of flux :
Use Mongo Collections to hold application state (store). An observer can observe changes on those collections (controller-view). I think all we’re missing is a place to hold all the ‘actions’ (Dispatcher) , a good event system (actions) which wouldn’t be too difficult to implement.

thanks

Yes, I am aware of Reflux and I studied it as well. It’s interesting but I don’t see enough benefits to introduce changes to the patter all people know. Besides, they changed the WaitFor() behaviour and their solution (stores can send actions so other stores can update themselves) is going back to chained actions, and that’s what Flux is trying to avoid.

We can build the same kind of helpers on top of the normal Flux dispatcher so there is less boilerplate, but without changing the pattern anyway.

Totally! I think it can be a perfect match with way less code than with React because Meteor already does some of the things automatically for us.

That’s my next step :slight_smile:

I’m going to recode the Facebook dispatcher (to get rid of JSX) and try to create some examples. I will post them here.

1 Like

Hey Arunoda, I’m not sure from your comment on what you ended up with that you like but isn’t flux. Could you elaborate some more or point to an example?

Sure. I like flux because of its unidirectional data flow. Here I think flux is is too much for meteor.

  1. we need most of the apps to be router specific. We build web apps which has more activities in the router. It’s a good idea if we can create a route for every case. Chat is a different example. So, router tends to be a good dispatcher.

  2. Stores. We have minimongo and reactive queries. That’s a better place for stores.

  3. I got confused with their action implementation. May be guys at fb may like to write more codes. It just a single event to me.

What they basically build an even emitter pattern with some more stuff to It which is specific to how fb architect their apps.

They later release another UI architecture, I don’t remember the name. So, it’s like they just throw out different stuff. But should not use all of them. But I like react.

Okay, then what’s the issue with meteor. If we designed a router based app normally, that’s tend to be with unidirectional data flow.

But with IR we re-run stuff in the router layer, with or without our concern. We need to stop that. We did it with flow-router.

In meteor stores get updated automatically. Then the UI also gets updated using reactive queries. Yes, now we don’t have a better control over that. But I couldn’t find a patter which works best for us.

Other things is template is meteor and there is no place to maintain the app state and the logic. We solves this using flow-components. It enforces single direction data flow and prevent talking to parent components.

3 Likes

Arunoda, when did you take a look at Flux? I have seen some outdated posts talking about things which have been improved and their dispatcher is simpler now than it used to be.

I have just thought… that the two things I listed as changing the “App State” without triggering actions can be solved quite easily:

  • Updates to MiniMongo: Those went thru other user’s client dispatcher so data has been properly processed.

  • Changes in the url: You can easily use the onBeforeAction to send a proper action Stores can react to.

    Router.onBeforeAction(function() {
    Dispatcher.dispatch( “URL_HAS_CHANGED”, { url: this.url });
    this.next();
    });
    We can even add a plugin so that behaviour is automatic. Then you can subscribe to that action with the Stores.

I am not following you here.

In Flux, Stores contain the logic of the app, not only the model (Mongo Collections and Session variables).

  • Stores: Contain the logic of the app state.
  • Controller-views: Contain the logic to transform that generic app state data into views the users can see and interact with.

In Meteor, the Controller-view part can be easily done in the Template Helpers.

Could you explain the difference between IronRouter and your FlowRouter?

Seems like dispatcher has simplified. We tried it when it releaed initially.

Flow Router is a router which does not handle rendering. And it does not re-run parts inside the router. Check Readme.

I hope it’s a good fit for this kind of work.

1 Like

That’s what I thought :blush:

I’ve seen your introductory video and it looks like it can be a great match for this!
I’ll try to make it work.


I have just published a first version of the dispatcher:


https://atmospherejs.com/meteorflux/dispatcher

You can add it with:

meteor add meteorflux:dispatcher

Then you can use the three Dispatcher methods:

// Register Store callbacks and receive a token
thisStore.tokenId = Dispatcher.register( thisStore.callback );

// Send actions
Dispatcher.dispatch( { actionType: "SOMETHING_HAPPENED", data: "some data" } );

// Do stuff when actions happen and use waitFor()
thisStore.callback = function(payload){
   switch( payload.actionType ){
       case "SOMETHING_HAPPENED":
           do_something();
           break;
      case "OTHER_THING_HAPPENED":
           // Hold and wait until otherStore has finished processing
           Dispatcher.waitFor([otherStore.tokenId]);
           // Now do something
           do_other_thing();
           break;
    }         
}

I didn’t add a readme yet, but I want to see how this fits with Meteor and if it needs some changes.

Right now is a clone of Facebook’s dispatcher, so you can use it exactly in the same way:


You can see more examples of use in their repo.

I will create some Meteor examples as soon as I can.

Thanks @arunoda . We’re thinking along similar lines.

1 Like

I have created the Todo App example:


http://todoflux.meteor.com/

I think the code is pretty straightforward and easy to understand:

  • Template Helpers: get what they need from the Collections and Session variables.
  • Template Events: emit actions.
  • Stores: subscribe to those actions and update the Collections and Session variables accordingly.

My only concern about this example right now is where the Meteor.methods() should be…

What I like very much about the flux architecture is the dispatcher (a.k.a. Mediator-Pattern). I first found a very good implementation of this pattern with ChaplinJS a framework for backbone.js.

I was also starting to think about implementing flux for meteor but found a pretty solid solution that was already build: space-ui

Space-UI has some more benefits e.g. having complete control over the application and no need to rely on the folder depended load order or even alphabetically one. Also the package-only structure is not needed for the whole application anymore.

What space-ui lacks are components and a router, but if you combine it with the simple flow-router and flow-components (or react.js if you like) I think you have a pretty solid application architecture based on the core concepts of flux.

4 Likes

I’ll take a look at those. Thanks @manuelschoebel!!

I’ve been taken a deep look at the space-ui but that’s the kind of overcomplicated framework I don’t want.
It’s like your are making an app with space-ui and not with Meteor anymore.

By design these frameworks can be great, but in the end, something like this is very slow to code and figuring out how something works is not straightforward because you need to follow complex chains.

For example, the chain of the clearCompleted action in their todo example goes like this:

// event is fired in '/client/views/footer/footer.coffee'
'click #clear-completed': () -> template.mediator.onClearCompletedTodos()

// then it looks like you have to write this in '/client/lib/events.coffee'
CompletedTodosCleared: {}

// then do this in '/client/views/footer/footer_mediator.coffee'
onClearCompletedTodos: -> @publish new CompletedTodosCleared()

// then in '/client/stores/todos_store.coffee'
@handle CompletedTodosCleared, on: -> @commandBus.send new ClearCompletedTodos()

// then write this in '/shared/lib/commands.coffee'
class @ClearCompletedTodos extends Space.messaging.Command
    @type 'ClearCompletedTodos'

// and finally in '/server/todos_controller.coffee' you get to delete the items
@handle ClearCompletedTodos, allowClient: true, on: (command) ->
    @todos.remove isCompleted: true

I love Meteor because everything is as simple as it can be. No boilerplate code anywhere. Everything is straightforward.

The Facebook’s Dispatcher implementation is the minimal amount of API needed to ensure you can follow the Flux principles, and all the other stuff is done with te Meteor tools we already know.

So I am going to stick with the Facebook’s implementation for now and keep working to see if I can find its boundaries.

1 Like

I’ve got to say, your implementation looks pretty darn clean to me (at a quick glance at least). So what was your reasoning for embracing flux, but not react? Obviously (as you’ve proved) they aren’t inseparable, but as they follow the same sort of ethos, I imagined I’d see them used together almost exclusively.

Meteor doesn’t impose you any architecture. That’s a good thing because you can choose the one you prefer, or don’t use any architecture at all.

Coding with an architecture is better, because you don’t have to think where to put your code each time you add something. And it saves you a lot of trouble when the application gets bigger because bugs are easy to find and everything is organised following some pattern.

Flux is a new architecture designed by Facebook for reactive apps. React is one of those. But Meteor is another one. I prefer Meteor over React because it gives you way more than just the front-end.

So I’m just trying to figure out the best way to make Meteor apps with Flux architecture, but with this singularity:

  • Make things as simple as possible, like Meteor does. This means no boilerplate code, complicated APIs or more stuff to learn.
  • Use as many Meteor tools as I can: Spacebars, Template helpers & events, Mongo Collections, Subscriptions, Sessions, Meteor methods… even IronRouter or Arunoda’s Flow Router.

I don’t want to reinvent the wheel.

By the way, any help is welcomed :smile:

Sorry I didn’t mean using Flux and React alone, I meant using the official package: https://github.com/reactjs/react-meteor

As then you’re not replacing Meteor at all, just Blaze.

Ohhhh, ok, sorry.

Like I said, I would like to make it work with the official supported tools.

Besides, I prefer Blaze over React. I think it is simpler to use and you have to write less code to do the same things. But if you prefer React, you can use it instead.

I have added another example: a simple shopping cart.


http://cartflux.meteor.com/

This time, it has two stores and some error handling (when adding a product to the catalog).

I will add another version with accounts and routing as soon as I have more free time!

@luisherranz thanks for sharing the examples. It’s really interesting indeed.
One question about your implementation compare to space:UI. How do you check the MAGIC callback strings correctness. Looks like dispatcher doesn’t care about the actual actionName, if I rename actionType only on one side of dispatcher interaction from dispatcher perspective everything still works. With mediator you at least get JS error during test run, while with current dispatcher you need to have a full functional test for every action. Which can be challenging sometimes if it’s something like a mouse drag event.