Fork me on GitHub
#clojurescript
<
2022-10-09
>
Joe Dumont02:10:51

Hi all. I'm trying to debug some code that compiles and runs without error, but seems to skip over the execution of the get-sample function. If I run each part in the repl it works as intended. I suspect it's an async issue, but I'm unsure how best to approach it.

(defn get-sample
  "Adds nearest sample buffer to array with distance to requested note"
  [{:keys [instrument note-and-octave]}]
  (p/let [[requested-note requested-octave] (convert-note-and-octave note-and-octave)
          sample (get-nearest-sample {:note requested-note :octave requested-octave :instrument instrument})
          distance (get-note-distance requested-note requested-octave (:note sample) (:octave sample))
          buffer (fetch-sample (:file sample))]
    (prn (str "fetching " requested-note requested-octave))
    (when (not (instrument @samples)) (swap! samples assoc instrument []))
    (swap! samples assoc instrument (conj (instrument @samples)
                                          {:buffer buffer
                                           :note requested-note
                                           :octave requested-octave
                                           :distance distance}))
    (prn samples)))

(defn load-samples
  [{:keys [instrument notes set-state callback]}]
  (hooks/use-effect
   []
   (p/do
     (prn "starting do block")
     (prn notes)
     ;;(p/map #(get-sample {:instrument instrument :note-and-octave %}) (p/resolved notes))
     (try (map #(get-sample {:instrument instrument :note-and-octave %}) notes)
          (catch js/Error e (js/console.log (.-stack e))))
     (prn "finished get-sample")
     (set-state true)
     (callback))))
When load-samples is called the print statements run before and after the try/catch , but mapping over the notes with get-sample does not run at all and does not produce an error. If I run the same map statement in the repl, it executes as intended. I've tried using p/map that's commented out as well as running it outside the p/do block. The use-effect is React in case that raises suspicion. Thanks for your thoughts.

Joe Dumont02:10:37

For similar but functional code, I successfully use:

(defn init-sample
  [url]
  (-> (js/fetch url)
      (p/then #(.arrayBuffer %))
      (p/then #(.decodeAudioData audio-context %))))

(defn load-sample
  [sample set-state callback]
  (hooks/use-effect
   []
   (p/let [audiobuffer (init-sample (:url sample))]
     (swap! samples assoc (keyword (:name sample)) audiobuffer)
     (set-state true)
     (callback))))

dpsutton02:10:51

Map returns a lazy sequence. Nothing is forcing the realization of that sequence so nothing happens

dpsutton02:10:27

❯ clj -A:cljs -M -m cljs.main -re node -r
ClojureScript 1.10.773
cljs.user=> (doc map)
-------------------------
cljs.core/map
([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
  Returns a lazy sequence consisting of the result of applying f to
  the set of first items of each coll, followed by applying f to the
  set of second items in each coll, until any one of the colls is
  exhausted.  Any remaining items in other colls are ignored. Function
  f should accept number-of-colls arguments. Returns a transducer when
  no collection is provided.

nil

dpsutton02:10:38

> Returns a lazy sequence

Joe Dumont02:10:15

Of course. Thank you!

Joe Dumont02:10:45

For completeness for my future self or someone else, doseq can be used instead:

(defn load-samples
  [{:keys [instrument notes set-state callback]}]
  (hooks/use-effect
   []
   (doseq [n notes]
     (get-sample {:instrument instrument :note-and-octave n}))
   (set-state true)
   (callback)))

dpsutton02:10:56

Change your swap! to an update!

🙏 1
Joe Dumont03:10:23

Aha, yes. Thanks for the multiple tips.

Dallas Surewood05:10:35

When using deps in shadow-cljs, it doesn't seem like I can list multiple aliases. For instance, I can list an alias defined in deps.edn to use, but if I list another one, then they both don't work. Is this a bug?

thheller06:10:04

how did you set them? :deps {:aliases [:foo :bar]} should be fine

Dallas Surewood06:10:27

Exactly that. Doesn't work. Also, how do I alias the main deps defined in deps.edn? Not just the ones under an alias?

Dallas Surewood06:10:42

Seems :deps true is the only way to include those

thheller06:10:46

not really sure what you mean. :deps true activates no aliases

thheller06:10:59

dunno what your aliases look like

thheller06:10:08

maybe you use :override-deps instead of :extra-deps?

Dallas Surewood06:10:05

Hmm I got it working now and I'm not sure why, but thank you for replying!

Dallas Surewood06:10:56

If you don't mind me asking thheller, what is your workflow when using both clojure/clojurescript? I've been trying to set up easy transitions between clj and cljs repls, and I can't get it working

thheller06:10:56

I barely use the CLJS repls and just switch to it manually when I need to

thheller06:10:26

hot-reload takes care of updating code and stuff, so no need for REPL eval most of the time

Dallas Surewood07:10:07

So you're basically doing shadow-cljs watch app and then ignoring it and only working from the clojure repl?

Dallas Surewood07:10:49

One thing I've found difficult with that is Calva isn't switching to cljs when I'm editing cljs files, so there's no autocomplete

Dallas Surewood07:10:55

Idk if you use Calva

thheller08:10:03

I use Cursive, which doesn't auto-complete over the REPL. don't know anything about calva

Ben Lieberman14:10:06

I use Calva/VSCode on Windows and my REPL switches to cljs mode if I run (shadow/watch :app) from my REPL that I start in powershell