This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-10
Channels
- # adventofcode (76)
- # announcements (7)
- # aws (3)
- # babashka (75)
- # beginners (25)
- # calva (37)
- # cider (9)
- # clara (4)
- # clj-kondo (17)
- # cljsrn (1)
- # clojure (106)
- # clojure-europe (4)
- # clojure-india (2)
- # clojure-italy (12)
- # clojure-nl (27)
- # clojure-spec (33)
- # clojure-uk (20)
- # clojurescript (103)
- # clojutre (3)
- # core-async (1)
- # cryogen (10)
- # cursive (24)
- # datomic (113)
- # dirac (5)
- # emacs (12)
- # events (4)
- # fulcro (64)
- # garden (5)
- # jobs (1)
- # kaocha (5)
- # luminus (2)
- # malli (14)
- # off-topic (53)
- # planck (11)
- # re-frame (9)
- # reagent (16)
- # reitit (26)
- # remote-jobs (2)
- # shadow-cljs (137)
- # spacemacs (34)
ok, so derived data requires that you do either one of:
1. Use the keyframe renderer, and don’t worry about anything like this ever again.
2. Add a standard F2 follow-on read of a prop on the parent to the transact!
that makes the change.
There’s a 3rd option I’ve added recently that actually is a better alt in many (probably all) cases: <http://book.fulcrologic.com/#RenderingOptimizations>
It does keyframe, but supports :only-refresh
on transactions. This lets you do targeted refresh at component-local state speeds when you need it, but otherwise “just works”
I love this approach, this is way simpler to learn to my colleagues
I personally have come to prefer this last option, as it is a “forget it” until something is slow, then add a single option to a transact to speed it back up
it will probably become the default when I have time to rewrite the portions of the book that matter…which means reading the whole book 😜
haha, ok yeah I just read about those earlier today, sounds like keyframe2 is the way to go
Where do we need Legacy UI Routers When we have Dynamic Router ?
The union router has a lighter footprint in general than the new dynamic router, and a lot of older apps are still using it. It isn’t as full-featured, and probably should not be used for new apps. The old dynamic router has code splitting integrated into it, but is similarly limited, and it would not be that hard to just use the new dyn router and do your code loading in it. TL;DR: new apps never need the legacy ui routers.
Hi there! I’m trying to figure out how to get ::fs/config
normalized when I add it in :pre-merge
:
(defsc SomeComponent [this props]
{:query [:some-field
fs/form-config-join]
:form-fields #{:some-field}
:ident (fn [] [:component/id :some-component])
:pre-merge (fn [{:keys [data-tree]}]
(fs/add-form-config SomeComponent data-tree))})
I’m merging the component via df/load!
, which is apparently eliding ::fs/config
from the query to send to remote, but I wonder why isn’t the original query used on the final merge (given that missing fields are already marked as ::not-found
). The case: I want to add initial values to the incoming data-tree, and make them to look new when using fs/dirty-fields
, but I don’t want to use tempid
(and new-entity?
would mark the whole entity, which is wrong in this case).Eventually couldn’t find a better way than to init in a post-mutation, but that scales kinda bad for large forms with a lot of subforms. Anyway, much better than anything I worked with so far. I can’t really describe how much I’m in love with your work, @tony.kay!
@UDQ2UEPMY there is a bug in F3 pre-merge…which is probably your problem…working on it. Thanks for the compliment.
Also, the way to work around form complexity like this is to use UISM…See RAD’s approach, for example: https://github.com/fulcrologic/fulcro-rad/blob/develop/src/main/com/fulcrologic/rad/form.cljc#L247
where the start edit or create functionality does the proper amount of marking complete and setting defaults (incomplete implementation, but coming along…)
Then you’ve generalized ALL form logic to one bit of reusable code that isn’t as complected with the component that renders the form.
How much does Fulcro weigh at baseline when gzipped, together with cljs? Is it around ~500kb?
within a component, can I expect calling set-value!
on a second, imported component to work correctly? e.g. (fm/set-value! SomeOtherImportedComponent :field 123)
any known impediment of using react 16.10.x with fulcro ?
Hi. I’m a total beginner with fulcro and I’m trying to get a websocket connection working both ways. I got com.fulcrologic/fulcro-websockets working on the client side:
(defonce APP (app/fulcro-app
{:remotes {:remote (fws/fulcro-websocket-remote
{:push-handler (fn [whatever] (println (str "WS EVENT! " whatever)))})}}))
and on the server side:
(def websockets
(fws/start! (fws/make-websockets
api-parser
{:http-server-adapter (get-sch-adapter)
:sente-options {:csrf-token-fn nil}})))
(def middleware
(-> not-found-handler
(fws/wrap-api websockets)
(server/wrap-transit-params)
(server/wrap-transit-response)
wrap-keyword-params
wrap-params
(wrap-resource "public")
wrap-content-type))
The application loads data correctly and the remote calls to mutations work as they should, but I’m entirely unable to get the :push-handler
to be triggered from the server. I can call the handler from the cljs repl connected to the application and it works - prints out as expected, but anything I do with the (:send-fn websockets)
function does nothing. Can someone please give me a pointer what I’m doing wrong?@nocnashada sente has a concept of client IDs
Assuming websockets
is your “started” websockets:
(defn active-cids
"Returns the active websocket client IDs in the given websockets handler. If a websockets handler
is not supplied it defaults to the running server's gondola.component.websockets/websockets."
([]
(active-cids websockets))
([ws-net]
(-> ws-net :connected-uids deref :any set)))
(defn push-notification!
"Send a message with verb :verb and payload :edn to all clients matching the :cids. If ws-net is not
supplied it defaults to the running gondola.component.websockets component."
([cids verb edn]
(push-notification! websockets cids verb edn))
([ws-net cids verb edn]
(let [clients (active-cids ws-net)
scids (set cids)
valid-ids (set/intersection clients scids)]
(doseq [id valid-ids]
(wsp/push websockets id verb edn)))))
the env
of a mutation or resolve should include a client ID of the client (I think under key :cid
) that talked to you (so if you want to do subscription registration, etc.)
would love it if you want to update the docs…that got lost somewhere along the lines…used to be well-documented
(defn send-ws [uid] ((:send-fn app.server.server/websockets) uid [::asdf {:data "data"}]))
=> #'user/send-ws
(map send-ws (:ws @(:connected-uids app.server.server/websockets)))
=> (nil)
I’ve been doing this on the server REPL, hoping something would come through, but nothing does …REPL eval probably saves you, but if you look I think you don’t have the data path quite right?
i mean, i played around with creating the client ID watch (what’s it called …?) and it prints out client ids into the repl nicely
I actively use the websockets support in two production projects. It works. The problem is almost certainly an understanding of how Sente figures out who you want to talk to
Thanks for the help. I’ll go over this a bit more and check the code you pasted and I’ll see if I manage to get it working.
it is defined as follows:
(defrecord Websockets [parser server-adapter server-options transit-handlers
ring-ajax-post ring-ajax-get-or-ws-handshake websockets-uri
ch-recv send-fn connected-uids stop-fn listeners
parser-accepts-env?]
WSNet
(add-listener [this listener]
(log/info "Adding channel listener to websockets")
(swap! listeners conj listener))
(remove-listener [this listener]
(log/info "Removing channel listener from websockets")
(swap! listeners disj listener))
(push [this cid verb edn]
(send-fn cid [:api/server-push {:topic verb :msg edn}])))
@nocnashada https://github.com/fulcrologic/fulcro-websockets/blob/develop/README.adoc#connected-clients-and-server-push I updated the README…let me know if I messed up at all