This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-18
Channels
- # alda (6)
- # architecture (1)
- # bangalore-clj (3)
- # beginners (39)
- # boot (292)
- # braveandtrue (1)
- # cider (7)
- # clara (2)
- # cljs-dev (20)
- # cljsjs (9)
- # cljsrn (42)
- # clojure (127)
- # clojure-chennai (1)
- # clojure-dev (96)
- # clojure-india (1)
- # clojure-russia (175)
- # clojure-spec (56)
- # clojure-uk (11)
- # clojureindia (1)
- # clojurescript (82)
- # core-async (7)
- # cursive (21)
- # data-science (1)
- # datomic (173)
- # funcool (4)
- # hoplon (8)
- # instaparse (1)
- # jobs (7)
- # jobs-discuss (1)
- # jobs-rus (30)
- # lambdaisland (1)
- # lein-figwheel (8)
- # off-topic (5)
- # om (51)
- # onyx (79)
- # other-languages (7)
- # planck (8)
- # re-frame (95)
- # reagent (6)
- # rum (8)
- # specter (4)
- # untangled (54)
- # yada (5)
My other thought is: do you have two concurrent instances of re-frame-async-flow
happening?
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.
[day8.re-frame/async-flow-fx "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) http://re-demo.s3-website-ap-southeast-2.amazonaws.com/#/input-text
and then try your test again with :change-on-blure?
set to false
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): http://reagent-project.github.io/ I have to go I'm afradi. Dinner here
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
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 https://github.com/Day8/re-frame-async-flow-fx/blob/develop/src/day8/re_frame/async_flow_fx.cljs#L108 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](https://github.com/Day8/re-frame/blob/develop/docs/Effects.md#db-not-always-needed) . 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
There's good implementations available http://stackoverflow.com/questions/14488150/how-to-write-a-dissoc-in-command-for-clojure
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
If you don't give a db-path then the state is not even stored in app-db
(reframe/reg-event-fx
:boot/authenticating
(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."
[db]
(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.
(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?))
reframe/trim-v
]
)
(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
default."
([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))
Just nest
[default-interceptors more]
re-frame will flatten
and remove nil
But that's an aside
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 ?
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.
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
You can return {}
from an -fx
handler which means no effects. Not sure why you'd do it. But it is valid
Have another read through: https://github.com/Day8/re-frame/tree/develop/docs
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.
thanks
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
(reframe/reg-event-db
:boot/authenticated
(fn [db [user a b]]
(-> db
(db>/set-user user)
(db>/authenticated))))
…
: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
Got late here
https://github.com/Day8/re-frame-forward-events-fx#tutorial
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 https://github.com/Day8/re-frame-forward-events-fx/blob/master/src/day8/re_frame/forward_events_fx.cljs#L19 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?