This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-03
Channels
- # announcements (21)
- # aws (6)
- # babashka (28)
- # beginners (39)
- # biff (1)
- # calva (23)
- # cider (5)
- # clj-kondo (108)
- # clojure (11)
- # clojure-europe (17)
- # clojure-nl (2)
- # clojure-nlp (10)
- # clojure-uk (8)
- # clojurescript (29)
- # community-development (4)
- # conjure (20)
- # css (3)
- # datalevin (9)
- # datomic (3)
- # events (2)
- # figwheel-main (11)
- # fulcro (36)
- # honeysql (7)
- # humbleui (5)
- # interceptors (4)
- # introduce-yourself (3)
- # jobs (1)
- # lsp (51)
- # malli (1)
- # meander (71)
- # minecraft (8)
- # other-languages (18)
- # pathom (15)
- # polylith (25)
- # portal (10)
- # re-frame (5)
- # reitit (15)
- # releases (1)
- # remote-jobs (1)
- # shadow-cljs (11)
- # tools-deps (27)
Is :body
called with a result-handler
in a custom fulcro remote special in a way? When I call (result-handler {:body data}
, I receive {:body {}}
in my default result action, but when I call (result-handler {:any-other-key data})
I receive the excepected data in my default result action.
I’d suggest using the source and book when writing these. I don’t remember off the top of my head. I’d have to do the same: look at the book or the source code. That’s why I wrote the book, and why it is open source 😉
The basic idea is that you have to send through a body that matches the shape of the normalizing query that was used with the request. If there isn’t one, then you’d have to supply that if you want any data to flow through in a meaningful way, though the middleware and remote are allowed to override that normalizing query.
Ok, that might help. It's just a REST api though, I don't use any normalizing features of fulcro, just a custom default-result-action
that will dispatch depending on the response type.
oh, well, then you should be reading the built-in one in detail. That’s a very interesting and sensitive area of the library
outgoing: EQL request (which defines the expected shape of the response incoming: map of data that must match EQL request OR must be handled by remote/middleware to make up an EQL request to use for merging
I get this error on server startup (`clojure -A:xtdb -M -m com.example.components.server`) unless I include shadow-cljs as a dep:
Syntax error (FileNotFoundException) compiling at (com/fulcrologic/rad/pathom_common.clj:1:1).
Could not locate com/wsscode/common/async_clj__init.class, com/wsscode/common/async_clj.clj or com/wsscode/common/async_clj.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
Is that normal? I thought I would not need shadow when running the server.I don't see how shadow-cljs has anything to do with it, but https://github.com/fulcrologic/fulcro-rad/blob/develop/deps.edn has pathom as deps only in dev profile, and that's needed for the version of async-clj that rad seems to rely on
I don't know about pathom3, but that error comes from a missing file, that is in pathom
Hmm, yeah, adding it did fix the error. So how did it work all this time locally without pathom 2 included, and why does it work with shadow in there? Anyway, thanks @U8ZQ1J1RR.
Not sure what exactly happens when shadow is "in there". Either something adds the file to classpath, or somehow com/fulcrologic/rad/pathom_common.clj is not used then
Or how is "locally" different from running clojure with the command line arguments you showed
Well, if I just include this alias to the command I showed, it works:
:shadow-cljs {:extra-deps
{thheller/shadow-cljs {:mvn/version "2.16.12"}
binaryage/devtools {:mvn/version "1.0.0"}}}
But otherwise I get the error.Some caching issue maybe :man-shrugging: I tried deleting ~/.m2/
and that didn't fix it.
Yeah, there can be flakiness with deps and cached classpath, especially with older versions of clojure tools
Okay, it works for now. I'll add back pathom back to :deps and leave the rest of the mysteries to resolve for another day 🙂 it works for now and I'll probably gain some insights to figure it out with a bit more time. Thanks again, @U8ZQ1J1RR.
No problem. The heuristic here would be to check what does the problematic project depend on (rad) or where could a file like that belong to (pretty much just google it, or search in github)
https://grep.app/search?q=common.async-clj
I see. So it's defined right https://github.com/wilkerlucio/pathom/blob/main/src/com/wsscode/common/async_clj.clj and RAD uses it by including it in the :dev
alias.
Yeah, this is definitely a pathom-related deps issue. Depends on which you intend to use. Both can be on the classpath at the same time. They use diff nses.
so, as long as you don’t mix them together, it’s fine. You can technically use them both at the same time, as long as you don’t try to use the artifacts of one with the other.
Any tips for getting fulcro-websockets working? I think I set both frontend and backend right but the client is just sending an infinite stream of requests like
GET
that respond with 200 OK
and 0 data and the browser console logs an infinite stream of
> DEBUG [taoensso.sente:215] - Bad package: (SyntaxError: Unexpected end of JSON input)
> sente.cljc:146
> Uncaught #error {:message "Invalid event", :data {:given :chsk/bad-package, :errors {:wrong-type {:expected :vector, :actual {:type Keyword :value :chsk/bad-package}}}}
and the WS tab of the browser does not show any communication.
The 200 ok seems to be returned by (fws/wrap-api websockets)
b/c if I remove it, I get 404 instead. Is the fws/wrap-api somehow set up wrong, returning an incorrect type of response?
My client just has (app/fulcro-app {:remotes {... :ws (fws/fulcro-websocket-remote {})}})
- not much to screw up here...Hey…the docs on the repo should be right…I’ve got a local app I, in fact, just set up with ws…here’s what I’ve got for the application (client-side):
(ns application
"Holds an atom that can be used to find the application from anywhere. DO NOT
require *anything* in this ns. It is meant to be used from any other ns, so
you do not get a circular reference. Initialized in `client.cljs`."
(:require
[com.fulcrologic.fulcro.application :as app]
[com.fulcrologic.fulcro.networking.http-remote :as net]
[com.fulcrologic.fulcro.networking.websocket-remote :as fws]
[com.fulcrologic.fulcro.rendering.multiple-roots-renderer :as mroot]
[com.fulcrologic.rad.application :as rad-app]
[taoensso.timbre :as log]))
(defmulti push-handler (fn [{:websocket/keys [topic]}] topic))
(defmethod push-handler :default [msg]
(log/info "Unhandled server push: " msg))
(defonce SPA
(app/fulcro-app
(merge
{:remotes
{:remote (fws/fulcro-websocket-remote
{:push-handler (fn [{:keys [topic msg]}]
(push-handler
(merge {:websocket/topic topic} msg)))})
:api (net/fulcro-http-remote
{:url "/api"
:request-middleware (rad-app/secured-request-middleware {})})}
:global-eql-transform (rad-app/global-eql-transform
(rad-app/elision-predicate
rad-app/default-network-blacklist))
:optimized-render! mroot/render!})))
this is server-side:
(defstate middleware
:start
(let [defaults-config (:ring.middleware/defaults-config config/config)]
(-> not-found-handler
(wrap-api "/api")
(fws/wrap-api websockets)
;; Fulcro support for integrated file uploads
(file-upload/wrap-mutation-file-uploads {})
;; RAD integration of forms with binary uploads
(blob/wrap-blob-service "/files" bs/file-blob-store)
(server/wrap-transit-params {})
(server/wrap-transit-response {})
(wrap-html-routes)
(wrap-defaults defaults-config))))
which is pretty close to stock templatewhere the websockets component is defined as:
(ns component.websocket (:require
[mount.core :refer [defstate]]
[marketplace.components.parser :refer [parser]]
[taoensso.sente.server-adapters.http-kit :refer [get-sch-adapter]]
[marketplace.components.websockets.client-tracking :as tracking]
[com.fulcrologic.fulcro.networking.websockets :as fws]
[com.fulcrologic.fulcro.networking.websocket-protocols :as wsp]))
(deftype ClientTracker []
wsp/WSListener
(client-added [this ws-net cid]
(swap! tracking/connected-clients conj cid))
(client-dropped [this ws-net cid]
(swap! tracking/connected-clients disj cid)))
(defstate websockets
:start
(let [ws (fws/start!
(fws/make-websockets
parser
{:http-server-adapter (get-sch-adapter)
:parser-accepts-env? true
:sente-options {:csrf-token-fn nil}}))]
(wsp/add-listener ws (->ClientTracker))
ws)
:stop
(fws/stop! websockets))
(defn broadcast! [topic msg]
(doseq [cid @tracking/connected-clients]
(wsp/push websockets cid topic msg)))
(comment
(broadcast! :BOO {:x 1}))
here's my server config in case it's useful: https://github.com/lgessler/glam/blob/master/src/main/glam/server/middleware.clj#L152 I don't remember details but I remember middleware ordering being tricky to get right somehow. Maybe take a look at that if you're out of ideas
thank you very much! I am 👀 into it...
I use Jetty 9. Do you as well?
I know jetty is supposed to be the better-maintained one, but I’ve had way more problems with it
also https://github.com/lgessler/glam/blob/master/src/main/glam/server/http_server.clj for me
Thanks! Will try to switch
It's the same to me. I'm on it.