Fork me on GitHub
#beginners
<
2017-10-11
>
athomasoriginal00:10:56

Which one of these would be preferred in ClojureScript

;; capture the dom element in a variable at the top of the namespace
(def elements (.querySelectorAll js/document ".elementName"))

;; create a getter function
(defn get-elements [] 
    (.querySelectorAll js/document ".elementName"))

seancorfield00:10:49

The def will only execute once, when that code is loaded. The defn will execute the selector query each time you call it.

seancorfield00:10:05

Seems like you'd want the function @tkjone?

athomasoriginal02:10:54

I suppose it might depend on the situation. In general, I started by always using def but then moved to defn as it felt more idiomatic

sundarj08:10:16

@tkjone if you only need to run it once def is fine

lepistane09:10:34

working with some api wanna do this

curl --user api-key: -XPUT --data-binary @-  << EOF 
if (rows.length > 10) {
  alarm('Too many rows');
}
EOF
{
  "success": true
}
how do i do that with clojure? i am using https://github.com/dakrone/clj-http but i am unable to find how to do binary-data only thing i found is byte-array in :mutipart for POST has anyone done this ?

danm10:10:17

I'm sure we've done that... Hmm. I think we created a ByteArrayOutputStream and dumped the body there, and set the header correctly. It was a while ago though, so I'm not sure

danm10:10:32

And I always get Input and Output mixed up with streams

joshkh10:10:26

i'm struggling a bit with core.async / channels. maybe someone can help? i have a collection of channels (representing web requests) and i want to take the first value from each channel and return the results in a collection. in other words, i want to wait for all channels to return a value before returning a final value. (this is cljs so i don't have access to <!!)

joshkh10:10:13

(go (js/console.log "finished" (<! (a/merge [chan-a chan-b chan-c])))) only returns the results from one of the channels

lepistane11:10:16

how does one recreate this

curl --user api-key: -XPUT --data-binary @-  << EOF 
if (rows.length > 10) {
  alarm('Too many rows');
}
EOF
{
  "success": true
}
using https://github.com/dakrone/clj-http#post ?

danm12:10:10

Is that backwards? That looks like it'll do a GET and save to disk, whereas I think @lepistane was wanting to read data from stdin and PUT it. The principle is still valid though. Just flip it round and use *in* instead of a file I guess?

mseddon14:10:26

ah, i see it's how java.lang.String.split works, hey ho. I will just nobble a "" on the end using my own function I guess

bherrmann14:10:09

(map first (re-seq #"(/|\w+)" "/foo/bar/")) ==> ("/" "foo" "/" "bar" "/")

mseddon14:10:47

@bherrmann ahh, interesting approach, thanks!

sundarj14:10:39

@mseddon

(clojure.string/split "/foo/bar/" #"/" -1)
["" "foo" "bar" ""]

ThadIsNOTFood14:10:06

I have a nested json data structure that isn't being decoded. Only the first level is being decoded and it leaves the maps coded as js json.

(let [sales-results (js->clj (.parse js/JSON (-> data :results :sales-results)) :keywordize-keys true)]
result:
[{"type":"SalesOrder","createdfrom":"","statusref":"pendingApproval"......
What have I done wrong?

manutter5114:10:30

You’re not doing anything wrong, that’s just the way js->clj is designed to work.

ThadIsNOTFood14:10:57

how do I make it recursive, I need the sub maps translated

danm14:10:20

Are the sub-maps double encoded?

danm14:10:30

Or is it just a multi-level structure?

manutter5114:10:54

Actually, I’m second-guessing myself now, I’m sure I read somewhere recently that js->clj is not recursive, but I can’t find the reference now

ThadIsNOTFood14:10:18

it is just a multi level structure, it is a vector of maps snippet before decoding

"[{\"type\":\"SalesOrd\",\"createdfrom\":\"\",\"statusref\":\"pendingApproval\"

danm14:10:17

Oh wait, cljs

danm14:10:30

I was going to say, we just use cheshire, but that's clj

ThadIsNOTFood14:10:04

yeah I'm not having the same problem on the back end 😉 maybe I should do the translation on the backend

manutter5114:10:16

Ok, I found the source of my mistake: I was remembering the docs for #js, not js->clj.

manutter5115:10:32

So yeah, I’d say js->clj should be recursive. What do you get with (.log js/console (.parse js/JSON ...))?

manutter5115:10:28

Actually, your approach+data seems to work for me:

cljs.user=> (def j "[{\"type\":\"SalesOrd\",\"createdfrom\":\"\",\"statusref\":\"pendingApproval\"}]")
#'cljs.user/j

cljs.user=> (.parse js/JSON j)
#js [#js {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}]

cljs.user=> (def p (.parse js/JSON j))
#'cljs.user/p

cljs.user=> p
#js [#js {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}]

cljs.user=> (js->clj p :keywordize-keys true)
[{:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}]

cljs.user=>

ThadIsNOTFood15:10:00

sorry had to run my son to school

ThadIsNOTFood15:10:53

hmm wonder if I am using an old version of something, I inherited the project from a teammate.

ThadIsNOTFood15:10:31

@manutter51 yeah when I work directly with the repl it works fine, I wonder what the difference on the browser is.

ThadIsNOTFood15:10:55

dev:cljs.user=> (def j "[{\"type\":\"SalesOrd\",\"createdfrom\":\"\",\"statusref\":\"pendingApproval\"},{\"type\":\"SalesOrd\",\"createdfrom\":\"\",\"statusref\":\"pendingApproval\"}]")
#'cljs.user/j
dev:cljs.user=> (.parse js/JSON j)
#js [#js {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"} #js {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}]
dev:cljs.user=> (def p (.parse js/JSON j))
#'cljs.user/p
dev:cljs.user=> p
#js [#js {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"} #js {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}]
dev:cljs.user=> (js->clj p :keywordize-keys true)
[{:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}
 {:type "SalesOrd", :createdfrom "", :statusref "pendingApproval"}]
dev:cljs.user=> 

manutter5116:10:12

I’d say try replacing the js->clj with .log js/console and see what data structure the JSON parse is giving you, you might be getting back something unexpected

ThadIsNOTFood16:10:10

yeah isn't behaving as I would expect

(defn translate-sales-results [sales-results]
  (let [j (.parse js/JSON sales-results)]
    (let [p (js->clj j :keywordize-keys true)]
      (println "#####translate: ")
      (println p)
      (.log js/console "#####translate!: ")
      (.log js/console p))

    ))
REPL:
#####translate: 
[{"type":"SalesOrd","createdfrom":"","statusref":"pendingApproval","tranid":"SO303","trandate":"10/10/2017"....
Safari console log
[Log] #####translate!:  (ui.js, line 1274)
[{"type":"SalesOrd","createdfrom":"","statusref":"pendingApproval","tranid":"SO303","trandate":"10/10/2017"....

ThadIsNOTFood16:10:51

on Safari console

[Log] #####j:  (ui.js, line 1278)
[{"type":"SalesOrd","createdfrom":"","statusref":"pendingApproval"...

ThadIsNOTFood16:10:31

not the

#js [ #js {...
that we would expect

manutter5116:10:32

Console won’t show you the #js, that’s a cljs thingy and console is JS only

manutter5116:10:35

it would be interesting to compare that to (prn ...) instead of (.log js/console ...) (but harder to read IMO

ThadIsNOTFood16:10:20

it should show that on the REPL though shouldn't it?

ThadIsNOTFood16:10:40

transit is failing as well 😞

ThadIsNOTFood16:10:12

Transit -> println

[{"type":"SalesOrd","createdfrom":"","statusref":"pendingApproval"...

manutter5116:10:52

You’re doing this in safari?

ThadIsNOTFood16:10:30

yeah I was having some problems with my Chrome installation that I haven't fixed yet

ThadIsNOTFood16:10:47

huh, looks like it actually thinks the whole thing is still a string...

manutter5116:10:43

Kinda stumped, but maybe workaround with (clojure.walk/walk js->clj parsed-json-data) as a temporary workaround

ThadIsNOTFood16:10:03

oh I think I have made progress.

manutter5116:10:13

oh wait, if it’s treating it all like a string still, yeah

mseddon20:10:19

Is there a clojure equivalent to Common Lisp shadowing-import? That is, I want to refer a symbol from another namespace that will clobber something already in clojure.core but I know what I am doing so I don't want clojure to warn about it.

seancorfield20:10:41

Look at (:refer-clojure :exclude [sym1 sym2]) @mseddon

seancorfield20:10:06

That will suppress the clojure.core symbols so you can refer in your own.

mseddon20:10:19

Aha, yes I see, that's what I am looking for, thanks!