Fork me on GitHub
#clojurescript
<
2023-06-02
>
Colin (fosskers)06:06:24

I see a Quick start guide linked in this channel (2018?) and also just looked over the official Getting Started guide on the Clojure website, but are there some blessed paths for getting started with web programming in Clojure? From the grapevine I've heard everybody is quite pleased about "shadows" or something and having REPLs in your browsers in your REPLs (or was it the other way around)? /s I know my way around HTML and CSS and have done a decent amount of WASM in Rust, but I have no React experience. I'm also hearing whispers of HTMX these days and the notion of embracing server-side work. What's a gent to do?

p-himik06:06:35

> What's a gent to do? Well, what do you need to do? A personal blog is one thing, a data-heavy SPA is another.

Colin (fosskers)07:06:39

I will eventually be writing a web app that acts something like a dictionary. I suspect drawn input (from a mouse) from the user will also be required.

Colin (fosskers)07:06:21

As part of the output, there will be some (hopefully) interactive graphs (the node-and-edge kind).

Colin (fosskers)07:06:13

Is it basically assumed that the React wrapper are to be used?

p-himik07:06:23

You can write code without any wrappers but that would be similar to going with plain JS instead of JSX. There are really thing wrappers that make interop with React pretty much seamless. And there are more abstracting wrappers that focus on other things.

Colin (fosskers)07:06:58

If I were to go the React route, would learning it entirely through Clojure be good?

p-himik08:06:53

I did it that way but I'm hesitant to recommend it. If you enjoy reading source code as much as you enjoy reading prose, consider debugging minified JS bundles to be fun, don't get put off by 15 unrelated issues you know nothing about, then you're like me and I'd say "sure, go for it". But if not, then I don't know.

Colin (fosskers)08:06:19

😆 I think I'll "consider my options"

p-himik08:06:38

But to be fair, learning vanilla React to a degree where you can build great stuff with it is not that much of a task. So you can easily get started with some React quick start, get comfortable with it, and then switch to CLJS and some React wrapper.

👍 2
kennytilton14:06:08

"Is it basically assumed that the React wrapper are to be used?" I would say React wrappers indeed have been the community favorite for a long time, but: • Hoplon/Javelin is also a veteran and slick way to go, and is being refurbished as we speak; • on the newer side we have Biff with HTMX; • I have a Web/MX project which handles the DOM directly; • and to me the coolest way to do the Web is Flutter, so we get mobile and desktop at the same time, almost for free. Check out #C03A6GE8D32 or again one of my libs, Flutter/MX supported in the #CKCBP3QF9 channel; • and if you do go with React, #CRRJBCX7S offers a nice functional interface (no Hiccup), and #C073DKH9P is excellent and very propular. Have fun!

Colin (fosskers)00:06:46

Thanks for a breakdown of the options!

leif17:06:38

I'm noticing that js->clj is leaving some objects as javascript objects, rather than converting them to clojurescript ones:

> (js->clj <some-json-value>)
#object[Object]

leif17:06:57

When I look into it, it looks like js->clj returned the exact same object it was given.

p-himik17:06:11

That's expected for anything that's not a plain JS object and doesn't satisfy IEncodeClojure.

leif17:06:23

I see. The object has only flat data, so is there any way to convert the object to a 'plain js object'?

p-himik17:06:00

What does (identical? (type x) js/Object) say for that object?

p-himik17:06:25

You can always iterate over the kvs yourself - the impl of js->clj is trivial.

leif17:06:33

It gives false

leif17:06:09

But in the browser console:

> typeof(x)
'object'

p-himik17:06:40

Then it's not a plain object. :) It has a constructor and you can't convert those objects in general - you have to figure out what is suitable in your specific case. typeof is misleading:

=> typeof(new Date())
'object'

leif17:06:26

In clojurescript (type x) is undefined.

p-himik17:06:17

That is surprising. Does that object have a constructor field that's set to undefined?

p-himik17:06:51

type in CLJS is just this:

(defn type
  "Return x's constructor."
  [x]
  (when-not (nil? x)
    (.-constructor x)))
And plain objects have js/Object as their constructor.

leif17:06:37

Welp, Doing JSON.parse(JSON.stringify(x)) and passing that to clj->js works.

p-himik17:06:56

How did you create that object in the first place?

leif17:06:09

I got it from blockly's json export.

p-himik17:06:35

And how does it look in text? Assuming it's not private and not huge.

leif17:06:39

(Which gives you the json as an object rather than a string...for some reason...)

leif17:06:48

The object?

leif17:06:55

> And how does it look in text? Assuming it's not private and not huge.

leif17:06:00

Not sure what you mean by that.

p-himik17:06:20

Yeah, I thought Blockly's export gave you a string.

p-himik17:06:37

Is it something that one can easily reproduce on their own? Curios to poke around.

leif17:06:50

Oh, no, it used to, back when they exported as xml.

leif17:06:22

But it seems like their json export gives you an object.

p-himik18:06:07

Is the line with onJsonChange the one where the export is done?

leif18:06:23

That is correct.

leif18:06:36

In older versions it was onXmlChange

leif18:06:39

Which gave a string.

leif18:06:50

But here when I print it to the console, it prints a javascript object.

p-himik21:06:54

Ah, they're using Object.create(null). Seems like it ends up with something more plain than a plain JS object, heh. I'd iterate over such an object directly to create a CLJS data structure. So, if I were you, I'd just write my own js->clj that would not only handle this particular case but would also be somewhat faster because you would be able to exclude a bunch of checks from there.

leif21:06:26

Mmm...that makes sense.

leif21:06:36

Odd...I didn't even know that was possible. Thanks btw.

👍 2
p-himik21:06:36

Oh, and there's an issue for it already: https://clojure.atlassian.net/browse/CLJS-2408

leif21:06:59

Looking at the age of it, I doubt it will get closed any time soon...

leif21:06:57

> And, if you want, you can vote on it here to increase its priority: https://ask.clojure.org/index.php/5926/js-clj-does-not-work-on-objects-with-null-prototype?show=5926#q5926 Ah, didn't see your second link. Thanks. 🙂

p-himik21:06:22

There are a lot of things in the backlog, and without voting for it it won't get prioritized.

leif21:06:34

Yup, I get that.

leif21:06:52

Anyway, voted.