Fork me on GitHub
#clojurescript
<
2020-04-22
>
Noel Llevares00:04:56

Is anyone using ClojureScript to target NodeJS apps? I don’t know Java so I’m more comfortable using ClojureScript for frontend and Node backend?

noisesmith00:04:36

it's definitely been done - using clojure is less complex than cljs as cljs is a clojure program

noisesmith00:04:44

there's self hosting cljs but it doesn't have the features you likely want

theeternalpulse00:04:07

Is there a way to specify npm script commands from a deps alias? Lets say I want to run a watcher to transpile something not related to cljs through npm upon running an alias.

charch01:04:05

Could someone offer some insight as to how I can get vim-fireplace to play nice with cljs files? I've tried starting a nrepl as follows using piggieback, but even though Fireplace connects to it, it complains about cljs. (not as seamless as the docs for fireplace would suggest, sadly). Putting the below as an alias in my ~/.clojure/deps.edn ,

:cider-cljs {:extra-deps {org.clojure/clojure {:mvn/version "1.10.1"}
                            org.clojure/clojurescript {:mvn/version "1.10.339"}
                            cider/cider-nrepl {:mvn/version "0.24.0"}
                            cider/piggieback {:mvn/version "0.4.1"}}
               :main-opts ["-m" "nrepl.cmdline" "--middleware"
                           "[cider.nrepl/cider-middleware,cider.piggieback/wrap-cljs-repl]"]}
and calling clj -A:cider-cljs, starts the nrepl. clj and cljc files are fine, but not cljs.

Chris McCormick01:04:41

@noelmartin I've done this a couple of times. Small servers using node's express web server and Postgres.

Noel Llevares01:04:51

Would you recommend it? What were the challenges? What were the good/bad things, if you don’t mind me asking?

Chris McCormick01:04:37

No problem! The challenges were the same as with nodejs servers in general - I usually find catching and handling errors in a robust way that doesn't break the server, to be a challenge. So I try to keep my backend server extremely lean, basically an authenticated data store.

Chris McCormick01:04:18

I would recommend it if you know and love the node VM & it's library ecosysstem. I would recommend using shadow-cljs to build both your client and server in a single monolithic repository.

Chris McCormick01:04:39

Getting live reloading of express routes working was also a bit tricky.

(defn reload! []
  (let [router app._router]
    (when router
      (print (str "Deleting " (-> app .-_router .-stack .-length) " routes"))
      (set! app._router nil)))
  (setup-routes app pg-pool)
  (println "Fresh routes loaded."))
As you can see I had to delete all routes and re-create them each time the code was hot swapped.

Noel Llevares02:04:45

Thank you. I would look into this.

Chris McCormick02:04:16

No worries, hit me up if you need any more info.

shivekkhurana06:04:28

Does cljs have an http library that supports parallel requests and caching? I'm currently building a wrapper on top of @roman01la's @r0man's cljs-http, but wondering if something exists already..

Roman Liutikov06:04:11

That's the other Roman 😂

😅 4
thumbnail06:04:51

Anyone knows how to fix https://nvd.nist.gov/vuln/detail/CVE-2020-8910 :thinking_face: ? NVD is reporting an issue with the bundled closure compiler, but no upstream fix seems available

Roman Liutikov10:04:36

Wrote a short guide on ClojureScript REPL workflow, feel free to add yours in comments https://gist.github.com/roman01la/b939e4f2341fc2f931e34a941aba4e15

👍 12
jrychter15:04:53

Thanks for this writeup. I always found the idea of saved-file reloading somewhat bizarre, and a step back from the times of Common Lisp. I always preferred to eval single forms, or load an entire file with C-c C-k.

jrychter15:04:26

I suspect many people who are praising auto-file-reloading have never used single-form evaluation from the editor.

Roman Liutikov15:04:36

I guess this workflow requires a habit to always reload your changes immediately, otherwise it's easy to miss something

jrychter11:04:04

I still have a suspicion that whole-file reloading became popular mostly because of people who haven't seen anything better. And it's true that it is a great improvement over re-loading the entire project.

Spaceman12:04:24

What's the idiomatic way to get the properties of a hiccup or reagent object? Say I have a [:div {:on-click foo}] and I want to access its on-click property?

Spaceman12:04:20

I could use (nth ... 1), but that seems inelegant

Chris McCormick12:04:47

maybe just as inelegant but what about (get-in obj [1 :on-click])

simongray12:04:02

How do I quote the return value of a function in ClojureScript? My function is returning some Hiccup data - including fns - but I want to print the pure data:

{:tabs
 [["1" [user/padded "One"]]
  ["4" [user/padded "Four"]]
  ["3" [user/padded "Three"]]
  ["2" [user/padded "Two"]]], 
 :i 2}
and not the default:
{:tabs
 [["1" [#object[user$padded] "One"]]
  ["4" [#object[user$padded] "Four"]]
  ["3" [#object[user$padded] "Three"]]
  ["2" [#object[user$padded] "Two"]]], 
 :i 2}
I thought about writing a function that recurs through a data structure, finding the fns and converting them, but I’m sure there is a simpler and more generic way to accomplish the same thing.

kimim13:04:52

I got something like #object[object Object] when use (GET http://aRestfulUrl). Can you help me how to convert the json to CLJS object? Thanks.

dnolen13:04:24

@simongray you can't quote functions, recursively handing them is probably going to be more practical

simongray13:04:02

Thanks. It’s not a big deal, just wanted to know if there was a more elegant way.

Vishal Gautam14:04:39

Add :keywordize-keys true, to convert key values to keywords

Spaceman15:04:37

Why does this return false? (= #(js/alert "hi") #(js/alert "hi"))

Spaceman15:04:43

I would expect it to return true

Spaceman15:04:07

because it's the same function, right?

Roman Liutikov15:04:00

no, they are two different functions

Roman Liutikov15:04:12

two different memory blocks let's say

Spaceman15:04:48

for my purpose, they should be equal. How do I test that kind of equality? Say Dom-behavior equality?

Roman Liutikov15:04:05

put it into a var

Roman Liutikov15:04:15

then (= f f) will be true

Spaceman15:04:25

what do you mean exactly?

Roman Liutikov15:04:44

(let [f #(js/alert "hi")]
  (= f f))

Roman Liutikov15:04:54

those are usual JavaScript functions, so equality semantics is the same, how is that you are expecting them to be equal?

dpsutton15:04:10

even? and #(zero? (mod % 2)) are equivalent but convincing a computer of that is turing prize quality work

Spaceman17:04:15

How can I add a js file in my shadow build process? It's a postcss.config.js file in my root directory

Spaceman17:04:41

and I want to build my shadow app with the postcss

Patrick Truong18:04:23

Hello Clojurians, I have a quick question regarding Reagent/Hiccup syntax. I was working through a basic Reagent + Tailwindcss example (https://github.com/mrmcc3/tailwind-cljs-example/tree/master/shadow-cljs) and noticed in the app.cljs file the author used this notation to render a vector of classes without string notation:  `[:div {:class '[max-w-3x mx-auto pt-12]}`. I messed around with it and found that it this notation (`'[max-w-3x mx-auto]` ) is equivalent to just writing the string: `"max-w-3x mx-auto"` . Is this standard Clojure syntactic sugar or some Hiccup magic? I can’t seem to find any documentation on this use of the single quote as the docs (https://clojuredocs.org/clojure.core/quote or https://clojure.org/guides/weird_characters#_quote) appear to be talking about delayed eval. Thanks for the help everyone 🙂

noisesmith18:04:40

what ' does is prevent evaluation, in this context it creates a vector of symbols. Hiccup then has a special action for a vector of symbols

lukasz18:04:33

Also is Reagent helping you - it accepts strings and seq of classes , including a plain vector: ["max-w-3x" "pt-12"] which means you can do stuff like [(when active? "text-bold") "text-red-600"]

lukasz18:04:50

rather than join strings of class names

Patrick Truong18:04:37

Awesome! Thanks for clearing that up. Is there a style preference to explicitly using strings (`["class-1" "class-2"]`) vs what this author did of just writing them as symbols (`'[class-1 class-2]`)?

lukasz19:04:40

I only dabble in clojurescript but I've seen strings used for classes in most examples, I don't recall seeing quoted lists - the only convenience is that you don't have to use quotes I suppose. Maybe others can weigh in

👍 4
Spaceman18:04:39

How do I use reframe in the repl? In my project files subscribe and dispatch works, but in the connected shadow-cljs repl, the dispatches and the subscribes are all returning nil

Spaceman18:04:28

also the subscribe isn't working in my test file

Spaceman20:04:27

I've created a macro:

(defmacro defelem [name element]
  `(ws/defcard ~name
    (ct.react/react-card
     (r/as-element
      ~element
      )
     )
    )
  )
But when I run it in the repl, I get the error TypeError: Cannot set property 'defelem' of undefined. Why is this and what's the fix?

lilactown20:04:39

in order to get help, you should always provide two pieces of info: • what you’re trying to do • what you’ve tried in this case, we don’t know what file you’ve created defelem in, how you’re trying to use defelem, so the error might be that, or it might be in your macro, we don’t know. there’s a lot of context missing, so we can’t tell you why it is or how to fix it

Spaceman20:04:35

I'm using #workspaces which has a defcard macro for creating cards, which is great, and so I might do:

(ws/defcard tw-card
  (ct.react/react-card
   (r/as-element
      [:div "hi"] 
    
    )
   )
  )
to show a div with "hi" in it. However, the first three lines almost never change for me, so I would like to create a macro that lets me do: (defelem tw-card [:div "hi"]). This was my attempt:

Spaceman20:04:41

(defmacro defelem [name element]
  `(ws/defcard ~name
    (ct.react/react-card
     (r/as-element
      ~element
      )
     )
    )
  )

Spaceman20:04:58

And to test it, I tried running it in the repl but got that error.

Spaceman20:04:05

In my shadow project itself, when I use the macro like so: (defelem mycard [:div "hi"]) I get a warning that

(defelem mycard [:div "hi"])
----------------^---------------------------------------------------------------
Use of undeclared Var vendo.workspaces.cards/mycard

thheller20:04:24

did you follow https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html? macros are written and clojure and need to follow certain rules to be available properly

Spaceman21:04:35

Has anyone used Firebase for backend? Is it useful enough to warrant not writing a server in clojure? If you have, what did and what did you not like about it?

Aron21:04:44

I wouldn't say so

Aron21:04:00

I have tried once but I couldn't even figure out how to have a local dev env

Spaceman23:04:09

is there a criterium like alternative for cljs?

Rucy23:04:28

I did use firebase for a stupid project, and it...worked as expected? not something I'd use for a large project, for sure, but it gets the job done for my simple crud

Spaceman23:04:12

why would you not use it for a large project?

Rucy23:04:37

it abstracts too much stuff for my liking, leaving you hostage to google

Spaceman00:04:03

can you give an example?