Hi, i’m failing to understand some code.
#!/usr/bin/env lumo
(require '[cljs.pprint :as pp :refer [pprint]])
(def github (js/require "github"))
(def githubapi (github.))
(.. githubapi (authenticate #js {:type "netrc"}))
(-> (.. githubapi -users (getOrgs {}))
(.then #(:data (js->clj % :keywordize-keys true)))
(.then #(map :login %))
(.then #(println %)))
I wrote the above and when I run I get
(madedotcom MastodonC Callitech MissGuided)
But if I change the last line of the code
to a map it doesn’t work
(-> (.. githubapi -users (getOrgs {}))
(.then #(:data (js->clj % :keywordize-keys true)))
(.then #(map :login %))
(.then #(map println %)))
which npm package is that?
"github"?
yeah
uses promises (I dont’ know much about node or promises) I’m just playing with Lumo as a script env at the mo.
I get UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: ~/.netrc authentication type chosen but no credentials found for '<http://api.github.com|api.github.com>'
hmmm yeah you need a ~/.netrc to authenticate to github
how do I do that?
You’d have to create a personal access token in github and then setup the ~/.netrc file
Let me do it on a public method so you don’t have to faff.
got it to work
ah cool
replace the map
s with mapv
s
I tried doall
doall should work as well
alternatively, the last one could use run!
instead of map
it works for me then - I get one organization back
hmm weird
what does it print for you with run!
?
(doall (map println %))
also works for me
ah my bad
replace map with doall instead of wrapping it
been puzzling over that for a good whilst!
😞 and then 🙂
hehe yeah laziness gets everyone, now and then
btw not sure about the wisdom of those consecutive promises if the steps aren't async
although I've seen this frequently in node code, so not picking on you
hmmm
the whole github api is promised based
and I cant’ extract the values of promises (as I understand it)
what else can I do?
I mean you could use a single .then
step no?
ah yes
that map doesn’t actually print but calls other promises
which could be combined into a single .then
I kinda liked the monadic nature of multiple .thens but if that’s not good Clojure style I shall change 🙂
don't know about that, but it just seems pointless to me (in js as well as in cljs)
node programmers in general seem to be seeking asynchrony like the moth seeks the flame... I just don't understand why
I was wondering about a then->
threading thingy
interesting idea
although that could encourage the async step where it's not needed I suppose?
yeah
hmmm
I have to confess the async nature of the node github api has put me off somewhat.
all io in node is async, give or take
Seems as soon as I use it i’m trapped.
at least all network io for sure
agree, it's contagious
Was porting a script I use to clone all my repos across all orgs to Lumo as an experiment.
Those async steps which aren’t really needed.
Do they just resolve immeadiately?
i feel cljs macros could help mitigate the pain, with the right syntax
i.e how bad is it?
but not sure what that syntax would look like
Might have a play later 🙂 thanks for the help
Any thoughts on this style
#!/usr/bin/env lumo
(require '[cljs.pprint :as pp :refer [pprint]])
(def github (js/require "github"))
(def githubapi (github.))
(defn then->
"Promise threading"
[promise & callbacks]
(reduce (fn [promise callback] (.then promise callback))
promise
callbacks))
(.. githubapi (authenticate #js {:type "netrc"}))
(defn getReposForOrg
"Get all the repos for an Org"
[org]
(then-> (.. githubapi -repos (getForOrg #js {:org org}))
#(:data (js->clj % :keywordize-keys true))
#(map :ssh_url %)
#(pprint %)))
(defn getOrgs
"Get the organisations for an authenticated user"
[]
(then-> (.. githubapi -users (getOrgs {}))
#(:data (js->clj % :keywordize-keys true))
#(map :login %)))
(then-> (getOrgs)
#(mapv getReposForOrg %))
I wonder if it would be difficult to "promisify" callback style code by using a canary for where the callback would go?
obviously, the macro would essentially just generate that tree structure, but still
^ this will be in the next Lumo
@dominicm https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original
Bluebird had this, didn't get much use, it's a bit of a 80% solution
then->
still reads better imho, I like the above
hmmm I’ve written some macros in lumo repl
Struggling to debug.
macroexpand doesn’t seem to do anything?
@mattford not sure what problem you’re having but this post may help: http://blog.fikesfarm.com/posts/2015-09-07-messing-with-macros-at-the-repl.html
macros in self-hosted ClojureScript behave a little differently
ah I hadn’t appreciated that