Fork me on GitHub
Endre Bakken Stovner07:05:57

I am getting the following errors from, the most important of which I guess is

react-dom.development.js:68 Warning: React has detected a change in the order of Hooks called by everclear.dag.core.graph_page. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: 

   Previous render            Next render
1. useState                   useState
2. useRef                     useRef
3. useEffect                  useEffect
4. undefined                  useState
Any hints on how to debug?


@endrebak85 hooks have very specific rules. you must move the useState call into the inner fn or remove that inner fn entirely


also your use of those hooks is incorrect. you definitely should not be calling set-graph as part of the render

Endre Bakken Stovner07:05:39

Hmm, I guess the set-graph can just be in a function of its own that listens to the sub since it does not need to add any hiccup, it just modifies an existing element. Thanks. Will try some more.


you are trying to mix 2 entirely different rendering models. so you must read up on refs in react and them use them in a useEffect hook to wire up the graph stuff


or go without hooks and just refs, that is fine too

Endre Bakken Stovner08:05:21

Thanks. I did not know I was mixing them ๐Ÿ™‚ Now I've gotten it to work with refs.


the when-let is a problem as well. if the subscribe returns nil on the first try it'll never update if it becomes available later

Endre Bakken Stovner08:05:04

Thanks. I was just copying the luminus template which uses the following:

(defn page []
  (if-let [page @(rf/subscribe [:common/page])]
I thought it was a way to postpone the showing page until the data was ready.


does that have the inner anon fn? I guess not?

Endre Bakken Stovner11:05:25

I am trying to translate the following code into ClojureScript (the javascript is a simplified version of

const reader = d3_dag.dagStratify()
const dag_data = await d3.json(``);
This is my attempt:
reader (d3-dag/dagStratify.)
data (->
      (d3/json "")
      (.then reader)) // failing line
I get the error:
Uncaught Error: can't stratify empty data
Am I doing something obviously wrong in my handling of or what?


On the js side you don't calling new on dagStratify(), so in cljs you dont need to use the . in (d3-dag/dagStratify.)

Endre Bakken Stovner11:05:18

Thanks, that seemed to do it ๐Ÿ™‚

Endre Bakken Stovner12:05:33

This is the first time I have to use go-blocks and the first time I've had to deal with promises, so I am a little confused. If I want to translate the following into a go-block, how would I do it?

const reader = d3_dag.dagStratify()
const dag_data = await d3.json(``);
I've gotten this far:
(let [reader (d3-dag/dagStratify)
          sg (d3-dag/sugiyama)
          dunno? (go
                   (let [data (<p! (d3/json ""))
                         dag-data (reader data)
                         layout (<p! (sg dag-data))]
I think everything but layout (<p! (sg dag-data)) is correct. But I am having a hard time translating this call:

Chris Lowe12:05:28

from the gist:

  .then(useArquint ? arquint() : sugiyama())

async function loadDag(source) {
  const [key, reader] = sources[source];
  const dag_data = await d3.json(``);
  return reader(dag_data);
It looks like loadData also returns a Promise (based on the immediate call to .then()). The last line of loadData is reader(dag_data) so your code equivalent of this line would need its own (<p!) call to yield the result:
  (let [data (<p! (d3/json ""))
        dag-data (reader data)         ;; try wrapping in (<p! ) 
        layout (<p! (sg dag-data))]    ;; not sure if call to sg returns a promise? 
โ€ฆor chaining then calls might be cleaner.

๐Ÿ‘ 3

@endrebak85 don't waste your time on a go block for this, just chain the promises

(-> (d3/json "")
    (.then reader)
    (.then (d3-dag/sugiyama)))

๐Ÿ‘ 3
๐Ÿ™ 3

though you probably want error handling

๐Ÿ™ 3

and then depending on how far away the error handling needs to be, or how many handlers there may need to be


you may or may not want to do this w/ promises


but if it's not involved I agree chaining is fine


I much prefer go + try/catch + ex-info + causes

Endre Bakken Stovner15:05:01

I want to call the .links function on the object in a promise. I think I've tried every variation of the below, but nothing works

(.then graph.links) ;; (-> graph (.then (.links)) ;; ...
What is the correct way to do it? Below the promise-wrapped graph object is shown. It has a .links method, but I do not know how to get at it.


(.then (fn [obj] (do-stuff-with (.-links obj))) or rather (.links obj), looks to be a function

๐Ÿ™ 3
Endre Bakken Stovner15:05:15

Thanks. In I'm trying to convert it is a function, but when I try to use it as a function, I get the error: Uncaught (in promise) TypeError: obj.links is not a function. Any ideas what might be wrong?


console.log the item and see if it resembles what you expect

Endre Bakken Stovner15:05:45

I have done so:

{dag: LayoutDagRoot, width: 5.83843708165997, height: 8}
dag: LayoutDagRoot
dagRoots: (6) [LayoutDagNode, LayoutDagNode, LayoutDagNode, LayoutDagNode, LayoutDagNode, LayoutDagNode]
links: ฦ’ links()
So it should have a link method AFAICS.


can you paste the exact code you are using to try to call it?

Endre Bakken Stovner15:05:17


(.data (-> graph (.then (fn [obj] (js/console.log obj) (.links obj)))))


that looks quite different that .data(dag.links()) above. and you're sure links: f links() is on the top level and not nested in the obj you are logging?


graph also probably isn't a promise? what is graph? maybe you just want (.data (.links graph))?


yeah from that code sample there's no promise stuff going on


would help to have your full code, seems like you are making a couple mistakes

Endre Bakken Stovner15:05:59

Rendering a DAG is about the only thing I need to do in JS so I have not started reading properly about JS/ClojureScript yet. I'd love to include a Clojure-project in my PhD, but I am working against a tight deadline, so I am just trying to get stuff to work quickly.


there's no use of then in the sample you are following. why did you introduce that

Endre Bakken Stovner15:05:43

Because I could not find a .link function and I assumed it was because it was wrapped in a promise.

Endre Bakken Stovner15:05:21

And if I try to log that graph, I am told it is a promise: [object Promise].


so their dag is passed in. not sure how they got it, but perhaps they are calling (.then dag draw).

Endre Bakken Stovner15:05:31

The data is loaded with d3.json which returns a promise so I guess whatever they do after that also happens in a promise.

Endre Bakken Stovner15:05:51

But yeah, everything happens within a .then: That sugiyama function is what contains all the calls.


so their function takes the value resolved from a promise, but you are passing that promise in. you'll need to correct that

Endre Bakken Stovner15:05:23

I thought once a promise always a promise. I looked for a way to unpack/deref a promise, I guess this is it:


no, you (.then render-graph). the variable you named dag is actually the dag promise, so the only way to get the actual dag is to .then it and access it async


There's also the <p! macro in cljs.core.async for 'awaiting' Promises AFAIK (tagged experimental though)

Endre Bakken Stovner16:05:50

Thanks. I should learn more about <p! too ๐Ÿ™‚


(defn render-graph [data]

(defn graph-page []
  (-> (d3/json "")
      (.then render-graph))
   [:h1 "hiya"]])


this is still widely incorrect regarding the react use but at least in render-graph you don't have to worry about promises at all anymore.

Endre Bakken Stovner16:05:10

Thanks all, now I am getting closer. I just need to find out how I'm mishandling react. Btw, this is for a project I'm hoping to publish in bioinformatics (or at least biorxiv) by the end of the year. I will discuss Clojure in it too. What channel would be most appropriate for asking about feedback on my discussion/summary of Clojure?


if it's a general "about clojure" type thing, probably off-topic. if you write an article there's an #news-and-articles channel as well

๐Ÿ™ 3
Endre Bakken Stovner16:05:03

I cannot find any documentation about the use of curlybraces below (taken from here:

({x, y}) => `translate(${x}, ${y})`)
What is the correct way to translate this? In a node repl, that function does not seem make sense, but I might be invoking it incorrectly:
> var f = ({x, y}) => x + y
> f(1, 2)


In JS that's destructuring a single object argument to get keys x and y from the object and bind them as local vars to the same names as the keys


So in JS you'd call f like this:


f({x: 123, y: 456})


cljs has clojure map destructuring in the argslist, but unfortunately (as @U05224H0W points out) you can't destructure a JS object in cljs in the argslist, you'll have to bind it to a local arg name and pull out those values yourself


an equivalent non-destructured JS implementation of f is


const f = (obj) => obj.x + obj.y

Endre Bakken Stovner09:05:27

Thanks. Weird that googling "anonymous function js curly braces" returned nothing relevant


really not specific to anonymous function in any way

๐Ÿ‘ 4

let {x, y} = obj; is also valid


this is destructuring for a JS obj, can't do that in CLJS. but (fn [obj] (let [x (.-x obj) y (.-y obj)] ...)) works

๐Ÿ™ 3
Nathan Tuggy19:05:42

Iโ€™m starting a REPL with clj -M --main cljs.main --repl and using Firefox (88.0.1 on Mac) as my default browser, but the REPL immediately freezes as soon as I try to evaluate anything at all, and I can only quit it by Ctrl-C (not Ctrl-D). Deps.edn only has ClojureScript 1.10.844, nothing else. This hang doesnโ€™t happen with Chrome, but whatโ€™s wrong with ClojureScript in Firefox?


Did you ever get this resolved?

Nathan Tuggy22:06:59

Not sure, and I definitely never figured out what the problem was. I can use shadow-cljs OK now.


@ntuggy just tried with 88 no issues


and 88.0.1 as well

Nathan Tuggy19:05:42

Thanks for checking. Any ideas on figuring out where the problem is? Nothing shows up in the browser console, even in Safe Mode. (Also, itโ€™s not just Firefox; I started with Pale Moon, a Firefox fork, and only switched thinking it might be some obscure compatibility bug.)


hrm I really don't know - something environmental for sure


if you just need/want to dev ClojureScript this doesn't seem essential


i.e. dev in Chrome - test all browsers (no REPL)