Fork me on GitHub
#clojurescript
<
2022-03-04
>
Benjamin09:03:17

.. doesn't work inside async go macros right? Is there some blog post about why this is and similar rooky pitfalls?

p-himik14:03:13

What behavior do you observe that makes you think that .. doesn't work?

Philipp15:03:16

Hello, I'm trying to get started with Paper.js, but I'm having difficulties reconstructing the basic example from http://paperjs.org/tutorials/getting-started/using-javascript-directly/ in cljs. I'm using shadow-cljs, installed Paper via npm and requiring it as ["paper" :as paper]. I seem to have access to the Paper instance, and can install its methods in the global window object, as described in the Paper documentation. However, creating e.g. a Rectangle does not paint anything, and properties of that rectangle instance (like strokeColor) are undefined. Here's what I'm doing basically:

(defn main
  []
  (.install paper js/window)
  (set! (.-onload js/window
                  (fn []
                    (.setup paper "canvas")
                    (let [paper (.-paper js/window)
                          path (.-Path paper)
                          rect (.-Rectangle path)
                          element (rect. [75 75] [100 100])]
                      (.log js/console (.-strokeColor element))))))) ; undefined

p-himik16:03:31

> The most straight forward approach is to copy over all fields from the paper object into the global scope That's one of the worst advice one could give. Don't do it, never assign fields to js/window if you can help it. Especially not in CLJS where you can't access fields in window without mentioning window, as you can do in JS. With that being said, your code queries the stroke color. But the code in the documentation sets it. So what happens if you set it to some value?

Philipp16:03:04

Hm, right, that was oversimplified and introduced another error, sorry. So when I set it to "black", it then logs "black". That object exists and I can log it as well, but it's not being drawn.

p-himik16:03:47

Did you replicate the JS example word-for-word? Does it produce any errors in the JS console?

Philipp16:03:05

Yes, I did. And yes, it produces an Uncaught TypeError for some function call in Paper.js. The same error is generated when I write the example in javascript though, so I think that this is unrelated (it's working from javascript).

Philipp13:03:03

I found what I was doing wrong. I have to refer to Path as a namespace, not an attribute, so paper/Path instead of (.-Path paper). Working now. Thank you @U2FRKM4TW

👍 1
p-himik13:03:10

I'm surprised that (.-Path paper) didn't work though. Wonder what's the difference.

Philipp14:03:47

Well I jumped to the conclusion too quick again. The mistake was not the usage of paper but the usage of Rectangle, which is a function not a constructor as I thought. I had changed the usage of both Path and Rectangle and assumed wrongly that the issue was with Path earlier. You’re absolutely right @U2FRKM4TW it doesn't make a difference. Thanks for making me double check, makes more sense now

p-himik15:03:51

Right, thanks for letting me know. And just in case - you should definitely prefer using paper/Path.

fadrian16:03:09

I'm attempting to build a list of re-com h-box components containing some text and some edit buttons that represent a list of items in my data structure. However, when I attempt to do this, the render for the edit buttons throws an error:

Uncaught Error: No value supplied for key: [#object[re_com$buttons$md_icon_button] :md-icon-name "zmdi-delete"]
From what I gather on the net, if my elements were in <LI>s wrapped in a <UL>, I'd simply need to do something like this in my hiccup:
[:ul [:li {:key 1} ... ] [:li {:key 2} ... ] ...]
However, when I try to do this with re-com v- and h-box components:
[v-box :children [[h-box {:key 1} :children [ ... ]] [h-box {:key 2} :children [ ... ]] ... ]]
hiccup doesn't seem to recognize the maps as element attributes. Is there any way to make hiccup recognize attribute values on non-html components, or should I eschew using re-com h- and v-box components to structure lists, instead using html tags and attributes to structure the layout?

p-himik18:03:10

The "No value supplied for key" means that you're trying to construct a map in run time but you provide an odd number of forms for that, so the last key ends up being without a value. In this case, re-com components all have signature like [& {:keys [...]}] - that's where that map is constructed. You can't just add {:key 1} to it and expect it to work. Instead, since you're using Reagent, you can assign keys via metadata - just replace [h-box {:key 1} ...] with ^{:key 1} [h-box ...]. Also note that static keys like that make no sense - you can just omit them. Keys are necessary only in a very narrow scope.

fadrian19:03:07

Thanks for that. I know that the key: in React is mainly for performance issues. I may have up to a couple hundred steps in the list that need to be edited, removed, etc. I figured that the cljs :key would help prevent too much re-drawing on edits toward the top of the list.

p-himik19:03:50

It would, right - given that that key is not a constant that you decide yourself and not a plain index but rather a proper ID of the element.

fadrian20:03:05

The key is associated with the element. I just put in constants in the example code to cut down on its size.

fadrian20:03:29

Thanks for your help again. I think I'm getting the hang of this stuff now. It's just the odd error here and there that hangs me up occasionally. Thanks again.

👍 1