beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
2021-05-10T00:39:30.448500Z

Hi, I have the following ClojureScript code to get the set of all loaded fonts:

(->> js/document .-fonts .entries (map #(.-family (first %))) set)
.entries returns JS iterator object. It works perfectly fine in Chrome, but I am getting the following error on iOS Safari:
Execution error (Error) at (<cljs repl>:1).
[object FontFace] is not ISeqable
Of course I can rewrite it directly using JS interop. But is this a bug in ClojureScript compiler? Or is there some other idiomatic way to write this code?

dpsutton 2021-05-10T01:04:47.450400Z

I’d look at documentation and the stack trace. My guess is that family is returning a single fontface either due to differences in how the browser works or different fonts loaded in the browsers

2021-05-10T01:10:43.450900Z

ok, so I checked further and the error is unrelated to JS iterator object

2021-05-10T01:11:11.451600Z

for whatever reason Chrome returns an array with two FontFace (hence using first), but Safari returns just a single FontFace

dpsutton 2021-05-10T01:12:47.452200Z

From which call? Fonts or family?

2021-05-10T01:18:12.452900Z

each value returned by iterator is array of two font-faces

2021-05-10T01:18:39.453500Z

in the end, I tested the map solution and it does not work in FF, screw this browser stuff ...

2021-05-10T01:18:59.453900Z

but I ended up with this code which seems to work everywhere

(defn- find-all-loaded-fonts
  "Iterates through all loaded fonts and construct a set of their font families."
  []
  (reduce (fn [[fonts it] _]
            (let [next (.next it)]
              (if (.-done next)
                (reduced fonts)
                (let [next-value (.-value next)
                      next-font (if (instance? js/FontFace next-value)
                                  (.-family next-value)     ; For Safari
                                  (-> next-value first .-family))] ; For Chrome
                  [(conj fonts next-font) it]))))
          [#{} (->> js/document .-fonts .entries)] (range)))

Ale 2021-05-10T04:38:46.454200Z

you are welcome, thanks for all the help ^_^

West 2021-05-10T05:13:34.461Z

I’m in the process of switching over to CircleCI for deploying my site to my raspberry pi. I’m using it as it seems to be a tad more flexible than gitlab CI. The trouble I’m having is getting ssh to work. Now usually I would do something like ssh-copy-id on my main machine so I can log in. Now CircleCI instructs to take the private key and add it via project settings -> SSH Keys -> Additional SSH Keys -> Add SSH Key. Then in the yaml put add_ssh_keys as one of the steps in my deployment job. Great in theory, but it doesn’t work. Am I missing something important? Maybe another helpful detail is, I’ll ultimately use rsync to transfer over the files over SSH. I did some searching and apparently there are problems with scp, which I used before. I tested rsync from my laptop, and it seems to transfer everything over just fine.

heyarne 2021-05-10T08:13:58.463800Z

how can I add additional dependencies when using cloure -M:…? I am habitually trying out libraries using a nice repl (i.e. rebel-readline), for which i have the following alias defined:

{:rebel
 {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.4"}}
  :main-opts ["-m" "rebel-readline.main"]}}
This lets me try out datahike for example via clojure -A:rebel -Sdeps '{:deps {io.replikativ/datahike {:mvn/version "0.3.6"}}}'. However, there's a deprecation warning that :main-opts shouldn't be used with clojure -A, clojure -M should be used instead. When using clojure -M:rebel , rebel-readline gets started lilke before, but (require '[datahike.api :as d]) fails because it can't find the dependency

alexmiller 2021-05-10T11:04:33.466100Z

The latter should be correct, but you need to make sure to put -Sdeps before -M

1👍
alexmiller 2021-05-10T11:04:42.466500Z

Otherwise it becomes args to main

popeye 2021-05-10T13:32:09.468200Z

I have output string below {\"email\":\"<mailto:popeye@gmail.com|popeye@gmail.com>\",\"user\":\"popeye\",\"domain\":\"<http://gmail.com|gmail.com><mailto:popeye@gmail.com|popeye@gmail.com>\",\"user\":\"popeye\",\"domain\":\"<http://gmail.com|gmail.com>\",\"status\":\"valid\",\"reason\":\"The email address is valid.\",\"disposable\":false} how can i get the values from email and status

2021-05-10T13:35:02.468600Z

How should the result look like?

2021-05-10T13:36:08.469200Z

Use Clojure data json

2✅
2021-05-10T13:38:46.471900Z

(Json/read-str “{\”a”\”:1,\”b\”:2} Output would be like —> {“a” 1, ”b” 2}

2021-05-10T13:44:00.472500Z

(get map key)

popeye 2021-05-10T13:51:10.472600Z

@delaguardo like below

popeye 2021-05-10T13:51:11.472800Z

{"email":"<mailto:name@example.com|name@example.com>" "user":"name" "domain":"http://example.com" "status":"invalid" "reason":"No mail server for <mailto:name@example.com|name@example.com>" "disposable":false }

2021-05-10T13:52:08.473Z

then just read that string using any json reader. most likely they will return a map like you just describe

popeye 2021-05-10T13:52:21.473200Z

will try

2021-05-10T13:52:40.473400Z

clojure data.json I guess should be the first one to try

1✅
2021-05-10T14:25:29.475700Z

So I’m going through Clojure for the Brave and True, and I was wondering if there was some way that I could use the REPL to see what the value is of each of the symbols when I run it? Sometimes it’s hard to understand what’s going on, but I think it would be easier if I could tell what each “part” and “remaining” is and see how it’s executed.

2021-05-11T13:27:19.019600Z

Thank you! This is all super helpful

2021-05-11T13:27:26.019800Z

I’ll play around with these

2021-05-10T14:33:48.475900Z

you might look at the Scope Capture tool: https://github.com/vvvvalvalval/scope-capture

2021-05-10T14:34:43.476300Z

you could also step through it with a debugger

tvirolai 2021-05-10T14:36:25.476500Z

A simple way would be to declare an atom outside the function scope and store the intermediate values there.

1➕
2021-05-10T14:37:56.476800Z

there's also tap&gt;. and also inline def (although that will get stomped on successive executions)

2021-05-10T14:39:24.477Z

or! just println

NoahTheDuke 2021-05-10T14:51:09.477200Z

tap&gt; is good for that

Endre Bakken Stovner 2021-05-10T15:02:52.478300Z

Did not work. I remember reading about this in some book about Clojure web programming - will find the answer 🙂

Endre Bakken Stovner 2021-05-10T15:03:00.478500Z

Thanks btw

FHE 2021-05-10T18:07:53.492200Z

Hi. Does anyone know where you are supposed to point the javascript line in index.html for a webapp if you are using a build tool that has multiple kinds of output? Maybe the multiple possible build targets (I'm most concerned with dev vs production for now, but mobile later) are supposed to have the same target folder for their JS output? I am trying to get a bare minimum webapp built with shadow-cljs (on WSL2 Ubuntu 20.04 if that matters). So far I installed ClojureScript and npm and shadow-cljs, and I have created a project folder and in it run

npx create-cljs-project my-project
(as mentioned in https://shadow-cljs.github.io/docs/UsersGuide.html#_standalone_via_code_npm_code ). I'm having real trouble trying to follow the shadow-cljs User Guide beyond that, but I did, after poring through the giant file structure the command above creates, find out none of that contains the absolute basics of a webapp (index.html and maybe some CSS), so I manually created a 'public' folder with index.html in it, and 'css' and 'js' subfolders.

2021-05-11T11:27:13.018800Z

A desk top app? I think you should have an idea of how you want to produce it first e.g are you doing to use electron?

2021-05-11T11:29:35.019Z

Most web development targets the browser, so that's what I assumed you were doing

FHE 2021-05-11T11:45:07.019200Z

I am targetting the browser at first, to try to get something together (I think Reagent+Hiccup are called for for that but I just want to do some hot reload magic first). ...then I would like to try getting the same app runing stand-alone on desktop (not sure if I should look into cljc files (and branching with some Clojure code) or just node (shadow-cljs with a different target?)). ...and later also mobile (Reagent needed? and an extra piece ReactNative? Alternatively I've heard of NativeScript but that was a long while ago).

Elliot Stern 2021-05-10T19:14:10.493100Z

Is there a more idiomatic way to write (if f (f x) nil) ?

localshred 2021-05-10T19:15:44.493300Z

(when f (f x))?

5👍2
Henri Schmidt 2021-05-10T19:42:08.493500Z

(if f (f x))

1
2021-05-10T20:25:11.494500Z

From the quick start docs https://github.com/thheller/shadow-cljs#quick-start Given a shadow-cljs.edn with the following data:

{...
 :builds
 {:frontend
  {:target :browser
   :modules {:main {:init-fn <http://acme.frontend.app/init|acme.frontend.app/init>}}
   }}}
> This config tells the compiler to call `(http://acme.frontend.app/init)` when the generated JS code is loaded. Since no `:output-dir` is configured the default `public/js` is used. So in your root directory, when you run npx shadow-cljs watch frontend it will target the browser and create a js code bundle based on the keyword you supply to the module hashmap. In this case :main becomes main.js (or thats what i recall) so you should have a public/js/main.js Now thats a development built (not minified, optimized, etc..) so likely you want to create a production build to. That and more is covered here in official guide: https://shadow-cljs.github.io/docs/UsersGuide.html#release

2021-05-10T20:26:22.494800Z

err also try #shadow-cljs for other shadow-cljs related questions.

FHE 2021-05-10T21:22:11.495100Z

@drewverlee Thanks. I'll re-read that tonight when I get at this again. 🙂 I thought of posting my question in the shadow-cljs channel, by the way, but I thought it might be more of a general question.