Required namespace "react" never defined
i am trying to build an application that is using reagent and i am getting this error. it is literally just the figwheel template for reagent
In Andy's example, the PersistentArrayMap
is used so it preserves insertion order but the same holds for PersistentHashMap
:
(def m1h (-> (hash-map :very-first -1) (assoc 0 :added-first) (assoc 92612215 :added-second)))
(keys m1h)
;; => (0 92612215 :very-first)
(def m2h (-> (hash-map :very-first -1) (assoc 92612215 :added-first) (assoc 0 :added-second)))
(keys m2h)
;; => (92612215 0 :very-first)
lein cljsbuild once min does not work at all, always results in depedency errors here
created the project with lein new figwheel appname -- --reagent
@dan.yb.tobias When you run lein new figwheel appname -- --reagent
, it says you need to run npm install
-- did you do that?
(which means you need npm
itself installed)
ah somehow i missed it, ill give it a try ty
@seancorfield still errored out
(same error)
Jan 04, 2021 9:02:27 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 4 error(s), 0 warning(s)
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/core.js line 5 : 0
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react_dom" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/dom.js line 5 : 0
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/impl/component.js line 6 : 0
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/impl/template.js
using lein new reagent-frontend reagent-sample +shadow-cljs
to make the app works but i like the other one since it's easier to remember :^)
I can repro your problem (but I don't have npm
installed which is why I wanted to check you had run that step).
I recently started playing with ClojureScript and I used the figwheel-main
template, not the figwheel
one.
But then I'm using the Clojure CLI, not leiningen (except for helping beginners with lein
🙂 )
haha yeah I am trying to learn but i am constantly having issues
I got the impression that figwheel-main had superseded plain ol' figwheel...
@seancorfield that’s definitely the case
so i should try the same thing but with figwheel-main ok
Ah, yes, sorry I didn't force the use of PersistentHashMap, but the example I had written up earlier did do so, as jumar's example does.
Hey. I’m learning CLJS by working on a little project, and I have a question about a good and idiomatic approach to a fairly simple problem. For context, I mostly work as a JS/React dev.
What I want to do: write a function that takes a collection, makes an HTTP request based on each value in the collection, and when they’re all complete, returns the results.
I’ve done this before in JS; inside of a call to Promise.all
, my code maps over the input array, uses await
to wait for the HTTP response, and then does some simple operations based on the response and returns the resulting output.
What’s a good way to do it in CLJS? I’m reading about core.async
and find it comprehensible enough, but it’s a lot to absorb, and I’m curious how a proficient Clojure(script) developer would typically do this. 😅
(Sure, I could use JS interop to use the promises that I’m familiar with, but that seems like it might defeat the point)
I think the bit that I’m finding hardest to figure out is how to wait until all the requests have returned before returning the final output 😕
These resources might help you https://funcool.github.io/promesa/latest/user-guide.html https://clojurescript.org/guides/promise-interop
@thomas.armstrong I'm just starting to (re-)learn cljs so I'll be interested to hear what people suggest. I'd be able to do this in Clojure on the JVM without having to think about it much, since multi-threading is so common, but cljs is an unknown for me...
@thomas.armstrong I would use core.async for that, yes
So, for anyone who’s curious about where I ended up on this, I went pretty far down the rabbit hole learning about core.async, watched Tim Baldridge’s 2013 talk, and I feel like I understand it all a bit better now. For context, my goal is to take some geographic coordinates, and a collection of dates, make API requests to retrieve sunset and sunrise times for the specified location for all of those dates, and then calculate some angles based on those times (that part not finished yet). Here’s my solution to making all the async requests and combining them into a single map:
(defn <get-times-for-date [lat long date]
(let [build-result (fn [times]
{date times})]
(go
(-> (http/get "<https://api.sunrise-sunset.org/json>"
{:query-params {"lat" lat "lng" long "date" date}
:with-credentials? false})
<!
:body
:results
(select-keys [:sunset :sunrise])
build-result))))
;; Still need to do the actual angle calculation
(defn <get-angles [lat long]
(go
(let [times (->> (mapv (partial <get-times-for-date lat long) dates)
(a/map merge)
<!)]
(println times))))
How would you do it with core.async in clojure? As I understand it so far, the main difference in CLJS is that only the (go ...)
versions of the core.async functions are available, since the JS runtime is only ever single-threaded.
Mmm. I understand that core.async is pretty much a given, since javascript HTTP requests are asynchronous by nature. How would you wait for all HTTP requests to complete before returning the result?
(a/go
;initiate requests (replace (a/timeout... ) with a function that makes an HTTP request and returns a channel
(let [resp-channel-1 (a/timeout (rand 1000))
resp-channel-2 (a/timeout (rand 1000))
;wait for response
resp-1 (a/<! resp-channel-1)
resp-2 (a/<! resp-channel-2)]
(println resp-1 resp-2)))
(:require [cljs.core.async :as a])
I wouldn't use core.async
for this in Clojure - I'd just use threads directly on the JVM, either via pmap
(sledgehammer), future
, or more likely an executor / thread pool -- depending on the likely size of the collection.
Ohhh :thinking_face: You’d create a separate channel for each request? I’d been thinking more along the lines of creating a single channel, putting each response as it arrived, and then consuming from it .
One thing I’m gonna say though: even though this core.async “fun” 🙂 can get pretty elaborate, I’ve established over the years that it’s better to minimize the amount of concurrent HTTP requests you’re making (if possible); now, if you’re calling different services and not a service that you control, you might have no choice
@raspasov So, for a collection of URLs, you'd map
over the collection to call async http fns that returned channels, then you'd map
over the channels to take the values? Or use alts!
over the collection of channels? (looping until you had all the values back?)
(again, I guess it depends on how many HTTP requests you'd end up making?)
Ah, gotcha. Sounds like a different world to JS 😄
Unfortunately core.async doesn’t allow you to (map a-fn coll)
The JVM is very different. I've done almost zero JS stuff in my life. I've spent decades working on the JVM.
So some imperative-flavored looping can be involved…
Basically you can’t (map <! seq-of-channels)… you’re probably aware of that, it’s the same in Clojure
> it’s better to minimize the amount of concurrent HTTP requests you’re making For sure. Unfortunately, the API I’m calling only accepts one parameter per request, and the number of requests will be small (< 20)
But you can map
a function over a collection that would produce a sequence of channels.
@seancorfield right
@thomas.armstrong right, so I just showed manually doing it over two channels,
So let’s see for many…
You could map
a blocking take over the channels 🙂 since you need to wait for them all to complete anyway.
@thomas.armstrong What do you need to do with the HTTP results once you get them? Do you just want a collection of results or are you handing them off for further processing?
@raspasov Yeah, much appreciated; I can see how that would would work. I guess the thing I’m most curious about now, in terms of the approach that an experienced CLJS dev might take, is: why many channels instead of one channel? I’m new to the whole concept of channels, so still trying to build a mental model.
@seancorfield yes 🙂 that is a nice one in JVM Clojure
@seancorfield Not much. A little extra processing per result, but just on the level of extracting some values from the response and then doing some simple arithmetic.
@raspasov Ah, there is no blocking take in cljs?
No (thread…), (<!!… etc
@thomas.armstrong there’s so many ways you can approach this; and to be fair, there’s no perfect solution, it depends on what you’re trying to achieve; you can have one long-lived channel that processes all requests; you can put channels on that channel and have one (go (loop []… (recur)) for the whole application that takes channels off the main channel, waits for a response and does something with it
channels on channels is pretty neat… I’ve used it; but if you can avoid having long-lived global channels, I’d prefer it; less “state” to manage
Haha... this is why my cljs learning journey will be painful: I'm so used to a multi-threaded environment!
@raspasov > there’s so many ways you can approach this Yeah, that’s my dilemma. So much power, so little understanding (right now) of how to use it 😅
Thanks for the responses. You’ve given me a starting point, I think.
(comment
;This takes at most ~2000 ms to execute
(let [process-seq-of-channels
(fn [chans]
(a/go
(loop [chans chans]
(if-not (empty? chans)
(let [ch (first chans)
resp (a/<! ch)]
(println resp)
(recur (rest chans)))
(println :done)))))
fake-http!
(fn [req idx]
(let [resp-ch (a/chan 1)]
;TODO Do HTTP request!!!
(a/go
(a/<! (a/timeout (rand-int 2000)))
(a/put! resp-ch {:resp req :idx idx}))
;TODO end
;return channel
resp-ch))]
(a/go
;initiate requests, replace fake-http! with a function that makes an HTTP request and returns a channel
;MUST use (doall...) to send the requests right away!
(let [resp-chans (doall (map fake-http! (repeat 10 {:req 1}) (range 10)))]
(println :starting)
(process-seq-of-channels resp-chans)))))
I also really like this library https://github.com/jamesmacaulay/cljs-promises , it’s old, there’s more fancy ones nowadays, but this approach has never let me down… basically it allows to extend JS promises to return (let [[val error?] (<! a-promise)])
Core.async is not the most beginner friendly thing; errors can be confusing, etc; some people try to avoid it but I do like it; the trade-off is worth it for many of my use cases; it allows to easily synchronize not only HTTP requests but many different events in your application; for example I’m working on a React Native app, and using TensorFlow Lite; I need to wait for the library itself to initialize (doesn’t happen on application launch), and then some ML models to load before I proceed with different setup fns; so core.async is a great tool for that; Look at (promise-chan), useful for such cases
So above I showed a case where you launch-off multiple requests at the same time; that works nice for a demo and a one-off; in a long-lived application, I often find it desirable to have one global channel that processes responses one by one; Sometimes being able to reason about the sequence of incoming responses might be desirable (in situations around login, user setup etc); otherwise, the less you care about the sequence in which responses are being received, the better
In my experience, for ClojureScript, simply using (defonce a-global-channel) is enough… alternatively you can use https://github.com/stuartsierra/component
But I’d start with defonce…
@raspasov For the fake-http!
function, instead of declaring a channel and returning it, could you just have the go
block return the hash map (since go
blocks automatically return a channel that, when taken, returns the last value in the go
block?
Also, for doall
-`map`, why not use mapv
instead which is eager?
Yes, you can; I just wanted to complete each channel with a random timeout
@seancorfield mapv works as well 👍
I just wanted to point it out, because it tripped me even after years of doing this 🙂
I just wrote (map …) and I’m like “why is this taking longer than 2 seconds” Lol
js/Promise.all
would be the no-lib way to 'wait' for a bunch of stuff to be ready.
in recent projects I've been happily using promesa lib which adds some nice sugar over js promises, (including as-if-sync macros like core.async). also worth mentioning, promesa works with https://github.com/juxt/clip (replacement for component lib) so you can have a system with async components
@seancorfield I see what you mean…
Improved fake-http!:
(comment
;This takes at most ~2000 ms to execute
(let [process-seq-of-channels
(fn [chans]
(a/go
(loop [chans chans]
(if-not (empty? chans)
(let [ch (first chans)
resp (a/<! ch)]
(println resp)
(recur (rest chans)))
(println :done)))))
fake-http!
(fn [req idx]
(a/go
(a/<! (a/timeout (rand-int 2000)))
{:resp req :idx idx}))]
(a/go
;initiate requests, replace fake-http! with a function that makes an HTTP request and returns a channel
;MUST use (doall...) to send the requests right away!
(let [resp-chans (doall (map fake-http! (repeat 10 {:req 1}) (range 10)))]
(println :starting)
(process-seq-of-channels resp-chans)))))
It has become a habit for me to sometimes make things around core.async extra verbose 🙂 It helps for debugging, (timbre/spy …) saves the day in many cases; But this is a good simplification
@henryw374 Yeah, it would’ve been easiest to fall back to JS, but I wanted to learn the “Clojure” way to do it 😅
@seancorfield @thomas.armstrong actually I just realized there’s also (pipeline …) in core.async in CLJS which is pretty cool… I’ve used it in JVM Clojure and it is really good; it can provide a more managed approach vs. the “manual one-off” I’m showing above; definitely worth checking out
@thomas.armstrong But it requires familiarity with transducers
@raspasov I think I’ll have to bookmark it for later. Feeling like I’ve got a lot to chew on here already 😄
@thomas.armstrong for sure
Are there separate docs for clojurescript core.async
vs the clojure version? I know there are differences, but all I seem to find are the docs for the JVM version.
@thomas.armstrong one last word of caution; assuming you’re moderately familiar with JavaScript, and you don’t need crazy backward compatibility, I’d avoid most CLJS HTTP libraries and just directly call the browser/JS HTTP APIs that return promises or callbacks
@thomas.armstrong I believe the docs are mostly the same
Mmm. The lack of <!!
etc tripped me up a little bit until I understood what was going on.
As far as (go…) stuff, it should all be the same; CLJS core.async is a subset of JVM core.async (of sorts)
Yes, only single ! in CLJS and no (thread…)
Otherwise, it should be the same
Ok calling it a night, have fun! 🙂
Thanks again. Very much appreciated!
I feel like it is something easy, but I can't manage to make it work I want to use the elements of a vector as arguments for my function
(assoc {} :a 4 :b 3)
(def argvec [:a 4 :b 3])
(assoc {} argvec)??
I think you are looking for apply
(apply assoc {} argvec)
For some reason I thought that I will get back this ({:a 4}, {:b 3})
I was sure I tested that 😄
Thank you
What's the proper way to round a float to up to x decimal points, removing any trailing zeros (non-significant digits)? clojure.core/format
satisfies the first requirement but not the second
e.g. assuming the same syntax as format, this is the behaviour I'm expecting:
(my-format "%.4f" 0.0001557)
-> 0.0001
(same behaviour as format)
(my-format "%.3f" 0.00001)
-> 0
(`0.0` is also fine, but not format's 0.000
)
(my-format "%.8f" 0.1)
-> 0.1
(format outputs 0.10000000
here)
The use case is creating an automated report so the output should ideally return a value, e.g. satisfy the string?
predicate, rather than print the result. This could probably be done with cl-format but it doesn't seem like a good fit unless it can return a value rather than print to stdout
DecimalFormat from java interop might also be useful
(fn format-decimal [d]
(some->> d
(.format (doto (DecimalFormat. "0.0###")
(.setRoundingMode RoundingMode/DOWN)))))
Oh nice, that seems to be exactly what I was looking for! Couldn't for the life of me figure out how to make it work, so thanks a lot @dstephens! 🙂
cl-format
returns a string if you pass nil
as the first argument.
You're obviously right, don't know how I missed that :man-facepalming: Thanks!
Welcome. There's also with-out-str
, which you might find useful with functions that print to stdout, but you obviously don't need it here.
quick question: i have a list of predicates, and a sequence of items. i want to remove all items from the sequence where at least one of the predicates is true. i'm looking for the counter-point to every-pred
, something like any-pred
. does that exist?
ope, looking at the every-pred
source, i see some-fn
directly below it. i think that's what i'm looking for
Yeah, it's some-fn
: (remove (some-fn odd? neg?) [3 -2 4])
.
thank you
Why is partial arguably better than an anon function?
;; good
(map #(+ 5 %) (range 1 10))
;; (arguably) better
(map (partial + 5) (range 1 10))
From: https://guide.clojure.style/#partialI'd argue it's not better :)
so maybe we should all just agree that it's arguable :)
partial is very rigid, you can't use it unless you are giving arguments in order. If you want to give a function the second argument instead of the first, you are stuck using anon functions. It's only a small step to just not use partial at all.
style is fundamentally subjective. if you're inclined to look through it, allow yourself to be convinced or not. they are arguments about which style is better and up to you to find them convincing.
I'd definitely use (partial + 5)
instead of #(apply + 5 %&)
, I'd hope most would agree
in general I like when I can replace apply in anon-fn with partial
There are some differences to consider: https://clojuredocs.org/clojure.core/partial#example-5f283b00e4b0b1e3652d7331
Rich considers anonymous functions to be more idiomatic in Clojure than partial
Thanks for the insight, I would not have seen the connection from apply and partial
too many arguments in programming : P
when i run lein uberjar it gives me this warning -> Warning: The Main-Class specified does not exist within the jar. I used to make a uberjar with this project often, but not lately.
I wonder what changed
i have :main and :aot in the project.clj file.
Leiningen 2.9.4 on Java 14.0.2 OpenJDK
and :gen-class of course
i don't see any classes anywhere, it isn't compiling anything, everything runs in cider ok
@codeperfect a project doesn't need a compiled main in order to run, but if you don't create one for your uberjar, you'll need to provide java with some other entry point
a popular choice is to skip aot-compiling and to pass your ns name as an arg to clojure.main
if you have :aot
set, make sure that the :main
and aot options agree(?)
i used a backup repository with an identical project.clj file and lein uberjar works there...
strange
in that case check your lein versions, and try running lein clean
and see if that changes the result
lein versiona are the same i did lein clean, what lein uberjar does is doing is putting the entire project directory tree into the standalone jar file, all the source code
that's the normal behavior
unless you explicitly ask for the source not to be included in the jar
in fact a lot of standard tooling breaks if the libraries you use are not packaged that way
but there are no class files of my code, and i don't know why it isn't compiling
OK, the problem can be subdivided - uberjar is a supertask that calls the compile
task if your project is configured to be compiled, you can try running lein compile
as a task on its own and at least verify that works
the likely issue here is that the config that causes compilation is erroneous
either it doesn't compile, doesn't compile to the expected output location, or isn't being configured to compile
also it might be good to move this conversation to #leiningen as it's definitely a lein / lein config issue
lein compile creates the classes, but lein uberjar still isn't putting them in the jar, maybe i'd rather have a nice cup of tea and watch tv
i do get a warning about ring -> Warning: parse-version not declared dynamic....(ring/util/parsing.clj:5)
eh, some cookies with my tea
if the classes are being created but are not showing up in your jar, make sure your target directory agrees with your uberjar classpath
at this point it's probably easier to just look at the project.clj
ah, the project.clj is different now, somehow ':prep-tasks ^:replace []' was put in there, i haven't used lein uberjar for months, working now 🙂
yeah, it's a good practice to attempt to make an uberjar at least as often as you modify project.clj to head off subtle things like this
(similar practice is recommended with optimized cljs compilation)
Hi, I'm wondering how can I short circuit a for loop in Clojure? I'm iterating an integer vector twice checking for specific sum, but would like to stop once I find a first match. How would one do that?
This is my currenct code:
(defn find-all-sums-to-2020 [expenses]
(for [x expenses, y (rest expenses)
:let [sum (+ x y)]
:when (= sum 2020)]
[x y]))
(defn find-sum-to-2020 [expenses]
(first (find-all-sums-to-2020 expenses)))
@diego559 for is not a loop, but it is lazy, you can just stop consuming it
there's also the `:until` :while
arg
what you are doing there is the normal way to stop it early
So (first) function will evaluate only the first result and therefore stop the inner for from continuing, is that what you are saying?
right, more precisely it never asks the inner for another value, so the value isn't calculated
that's how laziness works - you don't stop it from the outside, you just never force it to execute, so it doesn't
Great, thank you
the distinction becomes important when you have chunking (so asking for one item might make it decide to calculate 32 items) - you aren't forcing it to stop, you're asking it to calculate
Hey all, I wrote a program to ping and get an async response from a server via a single function. It was just a test and I'm wondering if I can get feedback on design patterns, idioms, if there is a much better way to do this. Also, specifically on line 61, how can I run the load-foo calls in parallel, and then print responses, without having the program exit? https://gist.github.com/jaybutera/dabbcda1e89c8ffed33773d73b420907#file-main-clj-L60