beginners 2026-08-05

I have put hours and hours into trying, in CLJS for browser, to capture keyboard key presses (keyup for now) (and having keyup events with certain keys trigger running functions), and I finally have a single line of code that halfway works: It captures keyup event and tries to print to the console, but it fails to identify the key. And even if I can solve that issue, I still am not clear on how I could get a line of JS interop code to include triggering calling of a CLJS function. Some background: I have read through and tried to understand what is going on in these 4 short programs, 3 CLJS and 1 JS, but it all mostly doesn't make sense to me. So many moving parts, and the 4 programs seem different in a lot of ways, including one of them confusingly mentioning 'channels'. https://github.com/brendonjohn/cljs-capture-input/blob/master/src/capture_input/core.cljs https://github.com/dtackett/clinp/blob/develop/src/clinp/core.cljs https://github.com/ulsa/movedot-cljs/blob/master/src/movedot_cljs/movedot.cljs https://github.com/ulsa/html5-canvas/blob/master/src/index.html I have read MDN articles on the topic, but they are not clear either because there are similar-sounding pages. Also they seem too piecemeal. I did find another source of code though, from a video, which is very simple (essentially a one-liner) but still includes some activity being triggered by a keyup detection. I am trying to follow it,

document.addEventListener("keyup", event => {
  console.log(`Key up = ${event.key}`);
});
but I was struggling to transcribe it from JS to CLJS. I have translated a few lines of code from JS to CLJS before, and I think I can add an event listener, but this bit of code is more complicated and I don't know how to in the same stroke add the additional parts of the code that make keyup events trigger things to happen (in this case reporting the keyup events and specific key labels to the JS console). My only hope was use of this JS-to-CLJS translator website I found, https://roman01la.github.io/javascript-to-clojurescript/ which suggested a CLJS equivalent to the JS code above. This CLJS-to-JS translator website I found, though, http://app.klipse.tech/ suggested that that CLJS code translates into JS code that is a bit different from the original. More to the point, that CLJS code,
(.addEventListener
  js/document
  "keyup"
  (fn [event] (.log js/console (str "Key down = $(event.key)"))))
doesn't quite work. The reports to the JS console include the literal text $(event.key) instead of the label of the key pressed. Make no mistake, I am ecstatic at having something that even partially works now, given the amount of time beforehand I was unable to make sense of all this and have anything work at all, but I would love any help • (1) to get at least this one line (statement) of code working (make it actually report the key label) and more importantly • (2) with how to alter that to make it trigger a function from elsewhere in the CLJS code. I tried replacing the (.log ...) part with a function call but the function was never actually called.

I think you should really start using LLMs for this sort of stuff. This wall of text took you longer to type than it'd take to ask an LLM to rewrite that JS fragment into CLJS. In JS, things like Key up = ${event.key}`` are string templates, this one is equivalent to (str "Key up = " (.-key event)) in CLJS. > I tried replacing the (.log ...) part with a function call but the function was never actually called. You need to show us what you tried, so we can help you understand what went wrong.

Update: • (1) After testing a bunch of things I finally tried this code and it worked (for actually reporting key labels). The issue had been the JS-to-CLJS translator website not completing the translation. I was trusting that that JS part was supposed to stay JS, but in fact it needed to be changed to CLJS.

(.addEventListener
  js/document
  "keyup"
  (fn [event] (.log js/console (str "Key up = " (.-key event))))
)
• (2) After testing this again, it turned out that even a simple function name in the (fn [event] _) form needed to be wrapped in parens. Glad I tried that.
(.addEventListener
  js/document
  "keyup"
  (fn [event] (celebrate-finally-capturing-a-dang-key-press-and-having-that-call-a-function))
)
Both issues solved! I finally have a real start on this. In fact for my program I don't think I need any of the extra complexity seen in the all example github programs linked to above. This might be all I need for now.

You really should be putting updates into threads - fewer notifications for other people and no chance of people thinking that it's a new thing, like I did when I replied to the messag above.

> it turned out that even a simple function name in the (fn [event] _) form needed to be wrapped in parens Ah, so this is another bit of plain syntax, in addition to interop and ns forms. ;)

I think you could also try asking in the #C03S1L9DN channel (next time), sometimes there's more people familiar with ClojureScript in there than here.

I'd say it's still more pertinent to #C053AK3F9 due to the nature of questions. Most of the problematic points aren't specific to CLJS in any way. And a person that's ready to answer people in #C053AK3F9 should already expect to have to deal with all sorts of questions, sometimes not even Clojure-related.

> You really should be putting updates into threads I specifically put my update not into a thread with the original post to prevent people from thinking that the problem in the original message was still a problem. (No click-through required to see.) I thought that especially appropriate considering there were no replies to the first post, and considering there had been no posts in #C053AK3F9 since my first post. I can absolutely put updates in threads going forward if that's the way people expect here, though. No problem.

> I think you could also try asking in the #C03S1L9DN channel (next time), sometimes there's more people familiar with ClojureScript in there than here. Good to know. Thanks! This is something I was confused about from the beginning and had to make a decision about, since these channels do not exist: #beginners-clojure #beginners-clojurescript

> I specifically put my update not into a thread with the original post to prevent people from thinking that the problem in the original message was still a problem. I see. A custom here is to use ✅ as a reaction under the original post to mark it as resolved. (As an aside, Zulip is nicer in this regard - resolving conversations is a built-in feature.)

The reason why there's just one #C053AK3F9 is that beginner questions tend to be all over the place. Your threads, for example, touch on CLJS, JS, CLJ, libraries, tooling, often combining many things in a single post. And nothing's wrong with that, that's expected here more than anywhere. And lots of beginner questions can't even fall into one single category.

Ah, OK. Checkmark is nice and clear. Having a single, undifferentiated beginner channel does seem to work, for the reasons you stated and because despite me not really knowing whether to post in #C053AK3F9 or #C03S1L9DN for beginner-level ClojureScript questions, I did end up opting for #C053AK3F9.