Fork me on GitHub

My other thought is: do you have two concurrent instances of re-frame-async-flow happening?


Anyones got an example of using re-frame (or similar) to enable server side FRP?


I'm assuming it has something to do with the keystroke/event handlers of the browser and reagent/react interleaving, but I don't understand the internals enough to know what I can do about it.


@lwhorton can you please try the latest. I've fixed the two "bugs" (circumstances) I imagined might be contributing to what you were seeing. [ "0.0.6"] [re-frame "0.8.0-alpha12"] If you still see the same problem, I'll have to get a gist from you to investigate further.


@mbertheau I don't normally do char by char processing. Can you perform your test on these (pure reagent) widgets (see the widget under "Demo" heading)


and then try your test again with :change-on-blure? set to false


Ah, so you just commit to app-db on blur?


I have that luxury


BUT ... a widget like the one in re-com should give you the option of on-change processing


Before going any further, I'm just making sure a pure reagent widget (no re-frame) works for you


I have it too for most of my inputs. Nice! Thanks. I can't reproduce it on the re-com demo site.


It looks as if the tiny pause due to processing each event is still enough to miss chars. So you'll have to use a widget which stores state in a local atom. AND then dispatches.


A bit like the re-com widget does


I never actually change the text in the input in these events, so I guess at first I can avoid updating the part of app-db that triggers a change to the input's value attribute.


@mbertheau: we do char-by-char processing on slow (mobile) processors - we found that we needed to put the text-field value into a local atom or we lost chars on some phones


@mccraigmccraig: @mikethompson: I see. That also answers my question about inputting combining characters in korean and other languages. Thanks for the insight!


Sorry for asking the same question twice: anyone here knows about an example of using re-frame db/dispatch/subscribe for the server side? 🙂


@luposlip I'm not sure what that means. You mean using re-frame on the JVM? Nodejs?


Is this some sort of isomorphic requirement perhaps


Hmm, if I understand correctly after looking at re-com's input-text, you can't have commit-only-on-blur on an input and be able to set the input value during the lifetime of its component without doing the internal-model dance. Since that's non-trivial, I wonder if it would be feasible to extract these parts from re-com, leaving the markup/CSS-specific parts out.


From memory, the todomvc example at the end of the reagent page has a barebones input field which commits to a local atom (I think): I have to go I'm afradi. Dinner here

Oliver George09:08:30

Hello. I see there is a 0.8 release on GitHub but it's not marked as the latest stable release. Just wanted to check if it's close.


@mikethompson: I’m not exactly sure either. I don’t want to do server-side rendering of react (reagent). What I want is to use re-frame’s dispatch/subscribe on the server to achieve server side FRP. Like a single framework for using FRP in both client and server, like Sente is for both server and client (and has the same'ish API).


@olivergeorge At this point, I'm thinking that 0.8.0-alpha12 will be the last alpha before release


I'm just syncing up satellite libs like re-frame-undo


re-frame-test is getting plenty of skillful love from Sam


A release-ready async-flow-fx is done


Not much more to go

Oliver George12:08:37

Fantastic. Thanks for the update.


@mikethompson I was fooling around with 0.0.4 and then 0.0.5. Moving to 0.0.5 fixed some issues I was having in addition to a “unknown deregister”. What also helped was to not explicitly include forward-events if I already had async-flow… figured that out after taking a look at flow’s source and seeing the dependency. Might be worth mentioning in the docs if you’re using both to only include flow. I’ll look at 0.0.6. While I have you, wrt can you not do (update-in db db-path dissoc) to “dissoc-in”? Until such time I don’t expect db-path to work, and thus two flows at the same time won’t be possible.


@mikethompson I was also thinking yesterday about effects and particularly [this]( . I’m currently running with my own implementation of reg-event-fx such that :db (if not returned by an -fx) will be tacked back on to whatever was returned. Given the docs linked here, that seems to be the default behavior, but the impl doesn’t match?


The reason I stumbled on this is an :after interceptor doing schema checking — hand the interceptor factory a fn to be run on :after, and it will receive a :db. But if any -fx handler fails to return {:db (:db cofx)} in addition to their other effects, [db] inside after will always be null.


@lwhorton I'm not sure your dissoc-in works. For example (update-in {:a {:b {:d 4} :c 1}} [:a :b] dissoc) doesn't make a change


It would depend on the path - if you had {:db {:my-flow-1 … :my-flow-2 …} and the path is [:db :my-flow-1] you would have to do some sniffing on the last


(update in db path-except-last dissoc last-in-path)


not sure how reliable that is 😕


I just groan a bit every time I have to copy this function to another place


But even as it is, there's should be no problem with two flows at the same time.


Without the dissoc-in, all that's happeing is that state might not be cleaned up in the teardown


Which probably won't hurt anything much


I see - and if you leave it to the default path are things just keyed under :id? {:db :path-to-flows {:flow-1 … :flow-2 ...}>? in that case default has my vote 😉


BTW, I don't really follow you description regarding "tacking on db" So i can't comment


let me give an example ..


If you don't give a db-path then the state is not even stored in app-db


Ohh that’s right - dumb question. I remember now seeing it’s in an atom.


  (fn [cofx]
    {:http {:method :get
            :uri (:user routes)
            :success [:boot/authenticated]
            :failure [:boot/unauthenticated]
            :error [:boot/unauthenticated]}}))

;; registered as interceptor
(reframe/after valid-schema?)

(defn valid-schema?
  "Validate the given db, logging any problems to the console."
  (let [res (s/check Schema db)]
    (when (some? res)
      (console :warn "schema problem: " res))))


After a [:boot/authenticating], which only returns {:http … } and not {:http … :db (:db cofx)}, that after fn will have a null db.


it just seems like cognitive overhead (but the gain of being explicit) to have every -fx handler pass-through :db.


I'm confused by your code.


wouldn’t be the first time someone’s said that 😛


(reframe/after valid-schema?) returns an Interceptor


yea that’s just a bad example, this will help:

(def default-interceptors
   (when ^:boolean goog.DEBUG debug)
   (when ^:boolean goog.DEBUG (reframe/after valid-schema?))

(defn reg-event-db
  "Register a db handler that automatically uses app-wide default interceptors.
  Optionally provide additional interceptors (as a vec) to include after the
  ([id handler]
    (reframe/reg-event-db id default-interceptors handler))
  ([id more handler]
    (if-not (vector? more)
      (console :error "re-frame: registering a handler with additional
                   middleware requires that middleware to be inside a vector.")
      (reframe/reg-event-db id (into [] (concat default-interceptors more)) handler))))


For it to be used, it must be added to an event handler


my own reg-event-db as well as reg-event-fx automatically register with the default interceptors^ above


BTW, you don't need to (into [] (concat default-interceptors more))


[default-interceptors more]


re-frame will flatten and remove nil


But that's an aside


ah, good to know


also this was written a month ago when I was brand new to clojure and “hey this seems to work” was more often than not my case


Oh, right, so you have: 1. Schema checking in your default-interceptors 2. And you are using default-interceptors on all event handlers 3. But some of your event handlers don't returns a :db 4. Which means there's nothing to check?


Correct, for all handlers that are reg-event-db, db is always going to be returned because that’s the way it is.


So you need to make your after interceptor NOT do a Schema check if there's no :db ?


Well, I’m not sure if that’s the solution or if that will get me in trouble?


Seems like a solution to me


i.e. if a -fx handler doesn’t return a db, is that db “gone” from the context in all future handlers?


If there's not :db in :effects then there can't be any change to app-db


So no need to check anything


i see.. ill have to look over the interceptor code a bit more - but you’re saying the context will only update :effects (the new db) if a handler returns :db.


that makes sense


So to say that more correctly: do-fx (which is the interceptor which actions effects) will only perform the effects it finds in a context's :effects. And if :db is not in there, then there's no update to perform on app-db


wonderful. This is a really great idea btw, i’m very impressed with the concept.


You can return {} from an -fx handler which means no effects. Not sure why you'd do it. But it is valid


They've got better in the last week


Should be a bit clearer now


I was actually reading through everything multiple times just this mon/tues.. and yes its much clearer. I’m going to make a pass again once everything is dandy within my own app to help out with some ref errors in the docs… some still point to old function names, or dont utilize [cofx] but [world] instead, etc.


They need a bit of proofing


btw - one more question… is there a reason forward-effects forwards the “whole stack of events”, the event that caused the forward and then the event to forward?


from my perspective, I would like to reuse existing handlers and forward events to them from some control point, but can’t reuse them because the function signature is different when forwarded versus dispatched


  (fn [db [user a b]]
    (-> db
        (db>/set-user user)

     :forward-events {:register :boot/load-after-public-login
                      :events #{:public/authenticated}
                      :dispatch-to [:boot/authenticated]}


this, for example, won’t be reusable.. ill have to have a diff handler like boot/authenticated-forwarded


and I couldn’t find any 100% reliable way to determine if something is forwarded versus dispatched, in which case I could use an interceptor to trim-v that first event


Sorry, not following.


But I'd better disappear to bed


Oops, sorry — see ya.

lwhorton14:08:12 In this tutorial it says "The payload of this dispatch is the entire event dispatched in the first place”. This means that a handler cannot be reused if it is the target of a forwarded event. In the normal (dispatch [:foo 1]), the handler :foo would have the fn signature of [db [args]] (without trim-v it would be [db [_ args]]).


If :foo is involved in a forward-event, such as

:forward-events {:register :bar/forward
                      :events #{:bar/happened}
                      :dispatch-to [:foo]}
Then suddenly the signature of :foo has to be [db [trigger-event args]], which in this example would look like [[:bar/happened] 1]].


Basically, why does this include the whole event-v as opposed to only the payload (conj dispatch-to (rest event-v))? If it’s used internally I understand, but can we perhaps mark it so that it can be identified and removed with something like trim-v?


I’m going to do some more thinking on that function signature issue to see how really impactful it is (if at all). it might be the odd-man-out case where you actually can reuse a -db handler that expects to receive a forward as well as a normal dispatch.