Closed jgaskins closed 7 years ago
Unfortunately, this doesn't help async dispatching. If I want to fetch remote data, I don't know if there's really a way to make this more concise without making it ugly:
button({ onclick: method(:get_data) }, 'Get Data')
def get_data
store.dispatch(FetchData.new).then do |response|
store.dispatch LoadData.new(response)
end
end
I'm very interested in suggestions for this particular use case. If I'm going to dispatch to the store, I don't want to do it two different ways inside the same component. :-\
I wonder if something like this might be doable:
Dispatch.async(FetchData.new).then do |response|
Dispatch.new LoadData.new(response)
end
The async
indicates that this is an async action that has a promise. The return value of that call would itself be a Promise
that gets resolved/rejected when the given action's promise is resolved/rejected. The thing is, we may not be able to return an actual Promise
, but instead a Promise
-like object because the return value of the block would need to be call
ed.
After playing with this over the weekend, I've determined that not only is the above suggestion really difficult to implement (I still haven't done it successfully), but it would also be weird to put as an inline event handler on an element in a Clearwater app:
button({ onclick: Dispatch.async(FetchData.new).then { |resp| Dispatch.new(LoadData.new(resp) } }, 'Get Data')
You could extract it to a method, but then that's not really different from the onclick: method(:get_data)
approach, except you wouldn't pass the method itself, but rather the return value of the method. I'd still like to be able to have first-class support for async dispatching, but it should be simpler and easier.
I noticed in Clearwater apps I do this a lot:
This is a lot of repetition of
proc { |e| store.dispatch my_action }
. The only thing that differs between them is the action that gets dispatched. Since Clearwater allows anycall
-able object to handle UI events, I wanted to be able to simplify this to something like this:That way, we don't have to wrap the dispatch in a proc but we still delay it until the event occurs. For events that pass parameters, like input events, we could pass a block instead of an argument to the
Dispatch
constructor:Now, as for how
Dispatch
knows how to direct it at the store we created (since stores are not singletons and we don't track store creation), we would set that up after our store is declared:Then all dispatches triggered by
Dispatch
go tostore
.