Hi I have an event like so
(rf/reg-event-fx
:map/swap-results
(fn [{:keys [db]} [_ results]]
{:dispatch-n [[:map/remove-results]
[:map/add-results results]]}))
For react component reasons, I need to remove results before adding them. This sends the 2 events in order but it seems like there is not to render the map after :map/remove-results
is there a way to wait
for awhile before the :map/add-results
event?There is: https://github.com/day8/re-frame/blob/master/docs/Solve-the-CPU-hog-problem.md#forcing-a-one-off-render But I would definitely not use it here simply because you're changing your re-frame workflow to, as far as I understand, work around some React component issues. Instead of doing that, create a thin Reagent wrapper around that component and work around that problem there. It will become much simpler in the end, much easier to reason about, and easier to reuse.
For now my workaround is to have a button dispatching map/remove-results
to clear the map, then click the result that dispatches map/add-result
to display the geojson on the map
might sound dumb, but track the requests in your state
and when each one finishes, see if its the last one to finish and then fire off the http request if so
(defn maybe-send-e [db]
(if (= #{:a :b :c :d}
(:process-state db))
{:db db
:fx [[:http-xhrio ...]]}
{:db db
:fx []}))
(rf/reg-event-fx
::start
(fn [{:keys [db]} _]
{:fx [[:http-xhrio [:on-success [::got-a]]
[:http-xhrio [:on-success [::got-b]]
[:http-xhrio [:on-success [::got-c]]
[:http-xhrio [:on-success [::got-d]]]}))
(rf/reg-event-fx
::got-a
(fn [{:keys [db]} [_ a]
(-> db
(update :process-state conj :a)
(assoc :somewhere a)
(maybe-send-e))))
and so on
and then make sure to also handle on-failures
that would be the explicit way if the requests had some data dependency
it sounds like your main concern is rate limiting so that might miss the mark somewhat, but implementing your own effect handler is somewhat tedious so that would be the explicit way without making a new mechanism
Question about app-db form state related to file fields. Normally I update app-db based on form field input change events but for "file" fields I'm fetching js/FormData from the htmlelement in my re-frame submit handler which feels ugly and dependent on stable dom rendering when handling submit.
(defn samplefile-submit-click
[{:keys [db]} _]
{:app/retrieve-file-submit
{:form-data (js/FormData. (.getElementById js/document "samplefileupload"))
:success-v [:app/-retrieve-samplefile-submit-success]
:failure-v [:app/-retrieve-samplefile-submit-failure]}})
Do you treat upload forms differently to regular data entry forms?
No. I extract File
objects myself, put them in the state, and construct FormData
manually. Of course, there's no reverse direction of the data flow - there are no subscriptions that set the input back. It can create issues during code reloading (the form will appear blank but app-db will have the file), but in most of my use-cases I replace the input with some representation of the file (usually by using object URLs) when it's available, so it works out just fine.
Alternatively, if that form can be reused, you can create a Reagent form and then use it from re-frame.
Thanks for this.
Sample form to clarify
Related react doco: https://reactjs.org/docs/uncontrolled-components.html#the-file-input-tag
Welcome :thumbsup: Thanks for the report @rberger
Is there now a way to make codox/docstrings work with reg-event-*
and subscription
declarations? Or any other way to have inline documentation that can flow into codox documentation?
FWIW you can document the handler functions themselves. But I'm not sure how useful it would be.
@rberger You can create a thin macro over reg-event-fx and subscription declarations that will insert a named function in the namespace bound to a var
(defmacro my-reg-event-fx
[& args]
(... a sprinkle of parsing ...))
(my-reg-event-fx
"Wow, what a function!"
::something
(fn [{:keys [db]} [_ ...]]
...))
;; expands to
(defn handler:something
"Wow, what a function"
...)
(rf/reg-event-fx
::something
handler:something)
Thanks @emccue I will give that a try!
if you're starting a new reframe project, what template/scaffolding is recommended to use?
Easy question https://github.com/day8/re-frame-template
I'm a beginner and I totally love to have a structured introduction to a new tool. This template is what you're looking for
And that link has already been posted here. ;)
I would recommend none. Figure out what components you need, find libraries that cover those needs, choose the ones you like and use them freely.
but i dont know what i dont know
If FOMO is strong, then just take a look at what some existing templates use, and research those libraries.
IMO unless you made a template yourself and you create new projects rather often, templates have more downsides than upsides.
That's solid advice in general but if we're talking about beginners, I don't think FOMO is the problem. Beginners need a closed garden and cljs/re-frame doesn't have one afaik. Ego depletion/decision fatigue is a thing! I really believe there should be a guide that says, ok, here are some conventions that work 70-80% of the time. That way you have something to begin with and if you outgrow the conventions you're still able to replace a block with another (in other words, leave the garden).
Not sure what you mean by a "closed garden" here. Apart from those 20-30%, all conventions and maintained/finished libraries work just fine. When it comes to libraries, if a person is not sure what they need or don't want to research too hard, they can just pick one at random. When it comes to conventions - same thing, although here it's harder to look them up because there are no GitHub repos with conventions. But there's this documentation page that describes one: http://day8.github.io/re-frame/App-Structure/ FWIW, re-frame documentation mentions this template: https://github.com/day8/re-frame-template
By "closed garden" I mean limiting the information/functionality the user is exposed to. Beginners do not need a lot of what reframe offers. > When it comes to libraries, if a person is not sure what they need or don't want to research too hard, they can just pick one at random. Let me answer that with a question. Which is more authoritative? Randomly picking shadow-cljs or the maintainers of re-frame telling you that it's good enough for most of your needs? The links you shared are useful but there's other stuff (not part of the original question, granted) that's also important, e.g. state management. How should you organize your subscriptions? Should you have a single subscription for the whole page or multiple smaller ones?
> Which is more authoritative? Re-frame maintainers develop a very special kind of software. IIRC they develop desktop apps with web technologies, that's it. Whatever they recommend, can be affected by that fact. If I want to develop a mobile React Native application, I definitely should not listen to their suggestions unless they come from an experience with such apps. > How should you organize your subscriptions? It is very well documented.
@micahasmith I have a minimal template repo I use cause it helps me cross the barrier of the “Blank Page Syndrome” when I’m starting a new project https://github.com/omnyway-labs/cljs-shadow-reframe-reagent-template
ty @rberger!