Fork me on GitHub

Sorry I am asking again: > Can you share your experience about server side rendering for cljs? Especially for re-frame. What is the status of it in cljs? Can we do server side rendering in cljs or it doesn’t really work like expected?

Roman Liutikov07:10:37

You can run it in node, general suggestions regarding SSR on node should apply to cljs as well.


I’d imagine all the approaches from running react in node would apply here too.


I’m not sure if reagents data layer runs on the jvm.


Hiccup is fine of course, but the react part clearly not.


It’s a pain. React is a js library, so you have to abstract all of the places where you depend on it to get it running in the jvm. Or, do something like run nashorn, which is pretty gross.


considering I run it on node how will it work about choose which part of SPA i want to pre-render and which not?


I was thinking about nginx module to pre-render or something like that. Will it be possible instead of node? For some reason I don’t like use node 🙂


But the question is: are we talking about theory or somebody achieve it in practice in cljs?


Theory in this case, but I’ve been doing ssr js since 2013.


any idea who know the answer?


*from practice


I think I saw a Leiningen template - might be worth seeing if there’s something to use as inspiration there. Sorry can’t give more direct tips! Would be interested too.


I’d look at rum that does SSR out of the box (I wish reagent did too but alas 😕 I assume you saw this )


(I’d avoid the nashorn section given it’s been deprecated)


something that could work well would be + graalvm since all the state depends on the parameters although I havent tried personally. If you go down that route I’d be interested to know what happens 🙂 @U0WL6FA77


thanks, I will check it

Robert Brotherus07:10:34

Is it ok in re-frame subscription to call another subscription? I have a subscription whose input-value depends on another subscription and I have implemented this as:

(rf/reg-sub ::field-str-value
            :<- [::data-path]
            (fn [data-path _] @(rf/subscribe [:field-string-value data-path])))
This style seems to work ok, but is there some problem with this or some more idiomatic way to write same thing? @danielcompton?

Robert Brotherus07:10:28

Googling about this leads me always to but this is described as "out of date" so leaves me uncertain


@UM54X8VTM the re-frame docs have some nice docs with examples which explain how to use a sub as input to another sub:

Robert Brotherus08:10:30

Thank you @U0524B4UW . I am aware of examples like

  (fn [query-v _]
    (subscribe [:sorted-todos]))
  (fn [sorted-todos query-v _]
    (vals sorted-todos)))
In fact my own example above uses signal-sunscription with the syntactic sugar :<- [::data-path]. However, in my case the latter subscription takes input parameter that is returned by the first subscription [::data-path] and I do not find example showing how to do that in any other way than I have written


oops, i didn't read closesly enough - i see what you mean - and i don't know the answer 😬

David Pham12:10:10

Usually, re-frame docs recommends to to write the function outside the subscriptions and to reuse it.

David Pham12:10:16

I know it is a pain, but you have no guarantee that subscriptions inside subscriptions are realized so you could get some unexpected behavior due to asynchronous code (I guess).

Robert Brotherus13:10:47

Good idea @UEQGQ6XH7 🙂 I am indeed been feeling bit uneasy about possible async problems on sub calling sub. I extracted now util/field-string-value which is used from 2 subscriptions:

(rf/reg-sub :field-string-value
            (fn [db [_ data-path]] (util/field-string-value db data-path)))

(rf/reg-sub ::field-str-value
            :<- [::data-path]
            (fn [data-path _] (util/field-string-value db data-path)))
This avoids calling subscription from the lower subscription. But the util/field-string-value function depends on db which is not available in the lower subscription since it takes [::data-path] as input signals.

David Pham13:10:48

This is good, usually how most Clojure I read deal with it (think of db as connection$

David Pham13:10:13

You should still avoid clever tricks like

David Pham13:10:20

According to re-frame docs

Robert Brotherus13:10:41

But this does not work yet, since db is not available in the latter subscription.

Robert Brotherus13:10:59

I can make it work by making identity-db sub:

(rf/reg-sub ::appdb (fn [db _] db))

(rf/reg-sub ::field-str-value
            :<- [::appdb]
            :<- [::data-path]
            (fn [[db data-path] _] (util/field-string-value db data-path)))

Robert Brotherus13:10:09

Perhaps this is how I will roll...


I think that would be the preferred approach if you have to use the sub in multiple places.

Robert Brotherus16:10:41

Thanks @U2FRKM4TW I'll look into reg-sub-raw also


I’d go with reg-sub-raw and subscribe as much as you want in the reaction :)

👍 4


(defn add "Add Two numbers" [a b ] (+ a b))
=> nil
(defn add  [a b ] (+ a b))
=> #'io.example/add
Does anyone know why using the docstring in the first line returns nil but if I take out the docstring the var is returned?

Kailash K19:10:31

hmm, that’s strange.

user=> (defn add "bla" [a b] (+ a b))

Kailash K19:10:55

it isn’t nil ^


Are you using the cljs repl?

Kailash K19:10:44

ah my bad; sorry!


🙂 I hope it does work on the cljs repl for you - then i'd know something was wrong with my setup

Kailash K19:10:48

dev:cljs.user=> (defn add "bla" [a b] (+ a b))


I started a cljs repl using the following command and did not get nil: clj -Sdeps "{:deps {org.clojure/clojurescript {:mvn/version \"1.10.520\"}}}" -m cljs.main --repl-env node


great, thanks for the sanity check - I guess I'll have to figure out how I hosed my REPL 🙂

👍 4

Anyone have any ideas of what could cause something like that? I'm using shadow-cljs and I've restarted everything and the behavior persists


I don't know, but maybe comparing the output between (source defn) in a REPL started with the command I gave above, vs. the REPL where you see a different behavior, might give a clue.


awesome, that's a great idea -let me give it a try


Odd, defn, def and let all are nil - println and clj->js are vars with functions


Looks like it's a shadow-cljs issue when running in node - browser appears to be fine.


fixed in 2.8.61


Hi, new to cljs. Could someone explain to me why the following doesn't change the input value? When I print the value to the console I see it does change 1 letter only:

(defn home []
  (let [name (rf/subscribe [::subs/name])
        val (reagent/atom "name")]
     [:h1 "Hello " @val " welcome to my first ClojureScript App!"]
     [:input {:value @val
              :on-change #(reset! val (-> % .-target .-value))}]]))


hey @itaied. The answer to your question can possibly be inferred by reading this doc:


the TL;DR is that because you are creating a reagent atom inside of your home component, you’ll want to use a “form 2” component


so you will, instead of returning the hiccup [:div ...], return a new function that subsequently returns the hiccup


mm ok ill read that, thanks! I was just reading the docs of re-frame so didn't get to that yet


hello! i am using lein doo and humane-test-output and seeing test output getting cut off. Does ring any bells for anyone? 🙂


same happens if i dont require humane-test-output, btw


i see printout of the

actual: (not (=  <redacted a lot of data>  [:Suffix
Subprocess failed


it’s cut off mid-form