This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-22
Channels
- # announcements (2)
- # beginners (42)
- # calva (2)
- # cider (13)
- # clara (2)
- # cljdoc (1)
- # cljs-dev (8)
- # clojure (118)
- # clojure-australia (1)
- # clojure-europe (3)
- # clojure-finland (2)
- # clojure-italy (42)
- # clojure-japan (1)
- # clojure-nl (2)
- # clojure-spec (26)
- # clojure-uk (58)
- # clojurescript (83)
- # cursive (6)
- # data-science (2)
- # datomic (13)
- # devcards (2)
- # duct (9)
- # figwheel-main (4)
- # fulcro (11)
- # graphql (51)
- # jobs (1)
- # juxt (14)
- # kaocha (1)
- # off-topic (24)
- # re-frame (65)
- # reagent (4)
- # reitit (19)
- # remote-jobs (8)
- # shadow-cljs (50)
- # specter (3)
- # speculative (1)
- # vim (5)
- # yada (50)
Hi! Quick question: how can I add a CSS class to an element based on a condition in Hiccup? I tried [:div.foo {:class (if error "has-error")}]
but it sets (if error "has-error")
as the class of the element :thinking_face: @weavejester
@hmaurer How are you using it?
user=> (use 'hiccup2.core)
nil
user=> (def error true)
#'user/error
user=> (str (html [:div.foo {:class (if error "has-error")}]))
"<div class=\"foo has-error\"></div>"
user=> (def error false)
#'user/error
user=> (str (html [:div.foo {:class (if error "has-error")}]))
"<div class=\"foo\"></div>"
It sounds like you're accidentally quoting your code.
@weavejester I was not quoting it I think, but i was on v1.0.5
of Hiccup; perhaps that explains it? Trying v2 now 🙂 Thanks for the prompt reply
It might have been an issue fixed since then.
I just tried it on v2; doesn’t seem to make a difference. Here is how I am using it: https://gist.github.com/hmaurer/5d52b8a5edb625b00e175b9a7404f904#file-render-fn-clj-L50
and in the REPL:
user=> (use 'hiccup2.core)
nil
user=> (def error true)
#'user/error
user=> (str (html [:div.foo {:class (if error "has-error")}]))
"<div class=\"foo if error has-error\"></div>"
Ah, it's been fixed in master but not been released.
@weavejester ah; I will just point my dependency to master then. Thanks! 🙂
Not sure you can without a deps.edn in the repo?
I'll release a 2.0.0-alpha2
Ah I don’t know, first time using deps.edn. I just tried and you are right, I can’t :face_with_rolling_eyes:
Given there are no transitive dependencies, you can use it from GitHub with deps.edn
-- you have to specify the manifest type as :deps
and it will silently ignore the lack of a deps.edn
file in the repo.
Ah, today I learned something 🙂
clj -Sdeps '{:deps {hiccup {:git/url "" :sha "8021043ae0eb64d1a31d87c0fa6071f44bc1c7f3" :deps/manifest :deps}}}'
@U04V70XH6 ah, TIL as well. Thanks!
2.0.0-alpha2 has just been uploaded to Clojars anyway, so you can do it either way.
@weavejester Brilliant; just updated the deps; it fixed my issues. Thank you 🙂 (for live support at 1am)
No problemo
No, looks like it was a bug that was only recently fixed. Specifically it's only an issue if you use the dot-notation and supply another class that's calculated dynamically.
@weavejester ah, I see, thank you!
Is there anyway, using clojure.zip to replace a node with two new nodes?
(let [btree [45 [10] [57]]
root-loc (zip/zipper vector? rest
(fn [[x _ _] children]
(vec (cons x children)))
btree)]
(-> root-loc
zip/down ;[10]
(replace-with [11] [12]) ; instead of zip/replace
zip/root))
;=> [45 [11] [12] [57]]
Using zip/replace
I can only swap out in this example [10]
with [[11] [12]]
, which is not what I want because I don't want to add depth.I can't really see any other way around this besides going up and replacing the children in the parent node.
I see I could replace and possibly insert left or right, will try that next.
the way a zipper works, you can think of replace as a mapping operation, you are a particular node, an you map (constantly replacement-value) over the value of that node, what you are talking about would be mapcat
in theory maybe possible, but there are kind of edge cases, like if are visiting node N, and you replace it with nodes N1 and N2, which are node are now visiting? you can make a choice, but there is no single "right" answer there
Yeah maybe my particular case warrants a new replace with function, like you said no right answer
I really want to split a node in two
I don't really care which node i'm visiting because i zip the tree right after
Combining zip/replace with insert-right works... since i don't really care if it goes left or right in my case:
(defn replace-with
[loc node1 node2]
(let [[x {r :r :as path}] loc]
(with-meta [node1 (assoc path :r (cons node2 r) :changed? true)] (meta loc))))
This seems to work
I mean, if you don't want to dig in to the internals of zippers and figure out how to mapcat
These are the originals:
(defn insert-right
[loc item]
(let [[node {r :r :as path}] loc]
(if (nil? path)
(throw (new Exception "Insert at top"))
(with-meta [node (assoc path :r (cons item r) :changed? true)] (meta loc)))))
(defn replace
[loc node]
(let [[_ path] loc]
(with-meta [node (assoc path :changed? true)] (meta loc))))
I was just hoping I maybe missed something but it helped talking to you lol
The only reason I didn't want to do it from the parent is because I did not want to go through at worst n many children to find and replace it with two new children
What is the easiest way to achieve the following: I want to split the sequence after the element for which a predicate is true.
split with will split before the element
not after
Like suppose you have [1 11 8 -3 9 33]
and you want [1 11 8 -3]
and [9 33]
, based on predicate neg?
.
Maybe combine split-with with (partition 2 1 ...)
Something like (map #(apply concat %1) (partition-all 2 (partition-by neg? [1 11 8 -3 9 33 -5 6 7])))
yes that's what I ended up with
looks like something that https://clojuredocs.org/clojure.core/split-with could be useful for
I'm facing a very weird problem with require
. For some reason, when I'm saying (require my-ns-var :refresh)
the changes are not applied to that namespace. I'm pretty confident my logic is solid but I'm just missing some intricate detail about require
here. Just for reference: this is about reloading changed Garden CSS declarations within my REPL
Problem manifests itself when I have structure main style-ns / page style-ns / component style-ns <- change to last one
I'm requiring the files in correct order, meaning that I first require namespaces which have no dependencies and from there I progress towards the main style-ns
If however I go and reload those namespace manually within REPL in that same order the changes are applied
:refresh is not a thing - you want :reload
you could also try :reload-all (which also reloads dependent namespaces)
Yeah, tried that. Only thing that changes is the CSS compilation time since requiring takes more time. No help
I don’t know anything about garden, but state has to live somewhere, typically in a var, so I’d investigate where Garden state is getting cached
Garden just takes a bunch of Clojure data structures in and spits out a string of CSS
But apparently I'm not missing something special require magic here that I should be aware of
not much other magic to know
Yeah. I actually also tried to use remove-ns
before requiring but that proved to cause all kinds of nasty problems
other places where state hides in the runtime are in multimethods (dispatch table) and protocols
Meaning, my old vars are left dangling and old references are still there for some reason
It's really strange since if I go and reload all namespace in order manually it works
I really need to dig in deeper into this at some point but I've wasted too much time already
Hi! I’ve encountered an issue when a protocol is reloaded causing the implementing objects to no longer satisfies?
the protocol.
Example:
(defprotocol A (foo [_]))
(def a (reify A (foo [_])))
(prn (satisfies? A a)) ;; => true
(defprotocol A (foo [_]))
(prn (satisfies? A a)) ;; => false
Is there any way to specify that the protocol object should not be recreated when reloading namespaces? Sort of like defonce
doesIn short, no
Thanks for your answers :slightly_smiling_face: It looks like this wasn't the cause of the problem after all, the protocol is only loaded once. The object that implements the protocol is loaded twice – why that would break things is very mysterious :man-shrugging: _edit: <--- I now realize this doesn't make that much sense in the context of my example, sorry :sweat_smile:_
my guess would be you are aot compiling and somewhere you are importing the class created by a defrecord without requiring the namespace that defines it, so the import is loading the old aot compiled version
I think you are onto something with regards to aot. I will post the minimum code that breaks lein uberjar
in thread.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; In protocol namespace
(ns protocol)
(defprotocol A
(foo [_]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; In implementation namespace
(ns implementation
(:require [protocol :as proto]))
(def a
(reify proto/A
(foo [_] ":)")))
(println "I get printed twice!")
(assert (satisfies? proto/A a) "I fail the second time")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; In our core namespace
(ns core
(:require [implementation]))
But this works fine in a fresh project though, so it must be something that's configured in my company's project
if you see that printed twice, I would look for a require with :reload or :reload-all
Unsure, but this happens when building the app on AWS as well. I'll try to do a lein clean
before uberjar
locally just in case
update: same error
We do have user.clj
and we use ring.middleware.reload/wrap-reload
, but these should only be enabled in dev
aot compilation must load the code, so if you load it first, then ask it to be compiled you will end up loading it twice (which breaks things)
That makes a lot of sense. Thanks 🙂 I will have to look more into this tomorrow as it is getting late.
hm. is there some kind of practical difference between seq
and lazyseq
that i'm missing?
they aren't similar much at all. check out the examples on https://www.conj.io/store/v1/org.clojure/clojure/1.9.0/clj/clojure.core/lazy-seq
seq is for consuming seqs from things that are seq'able, lazy-seq is for constructing lazy seqs recursively
Do any libraries exist where I can do collection transformations like (map, filter, reverse, rest, ect) but it keeps the type of collection
I know about mapv
and filterv
but more would be awesome.
I was thinking more of a library with heaps of sequence functions that would instead return vectors for example.
for clojure's built in datatypes other than seq, you can use (into (empty coll) (filter f) coll)
etc.