goatslacker / alt

Isomorphic flux implementation
http://alt.js.org/
3.45k stars 321 forks source link

Why are Datasources attached to a store? #702

Open Rybadour opened 7 years ago

Rybadour commented 7 years ago

I couldn't find a similar question anywhere, sorry if this was already brought up.

It seems weird to me that Datasources are attached to a store in such a way that I have to call the store to execute actions. Isn't that not in-line with how Flux is designed?

Example flow when using a datasource: Component -> Store -> Datasource -> Action -> Store -> Component

I thought with Flux ideally you'd have: Component -> Action/Datasource -> Action -> Store -> Component

mmoss commented 7 years ago

Typically with alt the flow would be more:

Component -> Action -> Store [-> Datasource] -> Store -> Component

c0d3ster commented 7 years ago

@mmos I don't see where you're getting that "typical" data flow from... The alt documentation clearly says that datasources should be connected to the store because of the fact that you have access to the state of that store. I can see the benefits of this data flow, but I agree with @Rybadour in that it seems to contradict the data flow that Flux presents. I'd like to see this issue addressed because I also feel as if the component should call the data source directly, then the result of that CRUD operation should be relayed to the appropriate action handler. In other words, I'd like to use the success/error callbacks from the source to route my errors to different action handlers, but it seems like the error callback can only be used when the server rejects the request altogether. For example, if a user attempts to log in but types their password incorrectly, I'd like to have that response routed to a different action from my source error callback but I'm not sure how to do that.

cveilleux commented 7 years ago

We do:

Component -> Store

If store is empty:

Component -> Action -> Store -> Component

pretty simple and works. components look like:

var data = getFromStore(); if (!data) { // trigger load action }

c0d3ster commented 7 years ago

@cveilleux The discussion here was centered around the data comes from initially and the flow of that data retrieval. In other words when you do component -> Action -> Store -> component, is it your action that does the fetch from the database directly or are you using a data source file to communicate with your database? If you were using a source file, the recommendation is to attach that source file to the store by calling exportAsync in the store, but this seems to go against the Flux design in my mind.

To follow up on the error handling portion of my response, we ended up just handling any errors from the server operation in the sources "success:" callback function by checking for an error field in the response. This is documented as an acceptable method here; however, it still returns a warning stating that an action was called but nothing was dispatched. This doesn't seem applicable considering we are calling another action to dispatch to the correct store handler for errors, but maybe I'm missing something.