This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-28
Channels
- # aws (1)
- # beginners (30)
- # boot (7)
- # cider (52)
- # clara (91)
- # cljs-dev (33)
- # cljsjs (1)
- # clojure (447)
- # clojure-brasil (3)
- # clojure-dev (16)
- # clojure-dusseldorf (5)
- # clojure-filipino (1)
- # clojure-italy (29)
- # clojure-sanfrancisco (5)
- # clojure-spec (62)
- # clojure-uk (37)
- # clojurescript (145)
- # clojurewerkz (1)
- # code-reviews (12)
- # community-development (157)
- # cursive (5)
- # datascript (1)
- # datomic (27)
- # editors (42)
- # emacs (5)
- # fulcro (31)
- # hoplon (2)
- # jobs (2)
- # keechma (1)
- # lumo (31)
- # off-topic (2)
- # om (1)
- # onyx (13)
- # parinfer (8)
- # re-frame (13)
- # reagent (32)
- # remote-jobs (4)
- # shadow-cljs (103)
- # spacemacs (15)
- # specter (10)
- # sql (1)
- # tools-deps (35)
- # unrepl (13)
Hello! I am looking for a way to give free pass empty string values when provided as optional
(s/def ::item (s/keys :req-un [::id] :opt-un [::url]))
I could check for url, but if empty string, since it is in opt-un, let it be valid
(but if was in :req-un, then should apply full ::url spec)
is there a way to achieve that?
It does work for nil but I’d like it to work for “” too
thanks!
@leontalbot I think what I'd do there is use :opt/url
as the :opt-un
key and define it as a spec like
(s/def :opt/url (s/or :url ::url :empty empty?))
which will allow it to be the full ::url
string spec or nil
or ""
(or however you want empty values to be spec'd... maybe #{nil ""}
)
cool! Thanks @seancorfield. Is this good too to you:
(defn valid-map?
“dissoc keys with empty vals to let optional keys pass, then validate...”
[spec m]
(s/valid? spec (apply dissoc m (for [[k v] m :when (#{“” nil} v)] k))))
(valid-map? ::my-spec-map my-map)
probably less general
@leontalbot I wouldn't use that approach because now you have a custom function, not just a spec. You can't conform
or explain
with that approach.
It also wouldn't work for specs that have keys whose values can be nil
or ""
but are still required.
FWIW, we have exactly this situation at work and the approach I suggested is basically what we do.
Thank you so much @seancorfield!
Spec is pretty flexible and powerful -- and the ability to use multiple qualified keywords for "similar" unqualified keys
specs lets you deal with a lot of context.
Another aspect to consider is having different versions of specs at different "layers" in your application. For example, we have API-level specs (which deal with strings mostly) and we have domain-level specs (and we have a few DB-level specs as well).
makes sense
and one last question:
why :opt/url
and not :url/opt
?
thanks!
Yeah I guess this is to map this hierarchy:
(s/keys :req-un [::id] :opt-un [::url]))
yeah…
Wanted to get end-user error message from spec. Useful for webform field validation.
Found Phrase library.
Seemed a bit overkill though. As I just wanted is attach an error text to a spec.
(s/explain (st/spec pos-int? {:reason “positive”}) -1)
; val: -1 fails predicate: pos-int?, positive
(s/explain-data (st/spec pos-int? {:reason “positive”}) -1)
; #:clojure.spec.alpha{:problems [{:path [], :pred pos-int?, :val -1, :via [], :in [], :reason “positive”}]}
Maybe use the :reason field accessible with explain?
Wanted to know what you would do for form validation, thanks!
theres https://github.com/bhb/expound as well which might be helpful
@leontalbot Would this work?
(expound/def :user/name string? "should be a valid name")
(defn msg [spec val]
(if (s/valid? spec val)
nil
(expound/error-message spec)))
(msg :user/name "John") ; => nil
(msg :user/name :John) ; => "should be a valid name"
Hey! Thanks for answering @bbrinck! Fantastic! Thanks!
Ok! Nice lib btw!
@bbrinck Sometimes I get an error message from expound when it complains about not being able to render an error (exact error message I don’t have handy). Wouldn’t it be better in that case to print the vanilla spec error instead of only the expound error?
@borkdude Is this a bug in expound? Or a case where your spec has conformers, perhaps?
Gotcha. Yeah, in that case, it might very well make sense to just print the default error. Let me think about that. Thanks for the idea!
Although if you’re using conformers, the vanilla spec error may not be very helpful either 🙂
Usually when I run into this, I turn off expound, re-run the code, inspect the error, fix it, and enable expound again.
@bbrinck FWIW, that was why we tried and then stopped using Expound -- we have several conformers in our specs.
@seancorfield Would it work in your case to just fallback to s/explain
?
Depending on how many conformers you have, I guess at some point you would rarely see an expound error
So the fix @borkdude suggested is a good idea, but it’s mostly useful for projects that have a relatively small number of conformers compared to the total usage of spec
@seancorfield FWIW, apparently pinpointer works with conformed values
@bbrinck Well, the main cases where we wanted Expound's better messages were all conformer-specs, so we just fell back to explain
ourselves 🙂