This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-18
Channels
- # announcements (17)
- # babashka (109)
- # beginners (212)
- # calva (1)
- # chlorine-clover (7)
- # cider (8)
- # clj-kondo (31)
- # cljsrn (2)
- # clojure (33)
- # clojure-dusseldorf (1)
- # clojure-finland (2)
- # clojure-france (22)
- # clojure-germany (1)
- # clojure-losangeles (1)
- # clojure-spec (6)
- # clojure-uk (19)
- # clojurescript (31)
- # conjure (41)
- # cryogen (1)
- # data-science (11)
- # datomic (6)
- # emacs (5)
- # exercism (8)
- # figwheel-main (2)
- # fulcro (57)
- # graalvm (15)
- # hoplon (15)
- # jobs-discuss (32)
- # kaocha (7)
- # off-topic (14)
- # pathom (2)
- # planck (9)
- # quil (1)
- # rum (5)
- # shadow-cljs (34)
- # spacemacs (33)
- # tools-deps (1)
- # xtdb (9)
Hey all, I'm working on a blog post that includes creating a fulcro form. I'd love to hear thoughts on whether this implementation is idiomatic from anyone who has time to take a look: https://gist.github.com/codonnell/1ea9b2edea542e1766f9631e94763140.
yeah seems correct, some things i would a little differently but they are cosmetic
👍 Thanks
like i usually call mark-complete on blur
also a subform example might be useful
to show the power of normalization
otherwise it might be unclear how this is all that useful
that example might be too involved for what you want to do, but it does highlight several useful aspects
in your blogs you could also link to the relevant parts of the book as a reference if someone wants more detail
I have done that a bit, but could definitely do it more. Good suggestion, thanks.
no problem, thanks for writing these by the way!
I'm not sure how to fit a subform into this application at the moment; I'll take some time to think about that.
i see
You're right that it would make for a better demonstration of the usefulness of form-state
yeah if form-state didn’t sub-form -> flat diff delta mapping, it would be waaay less useful
the flat diff delta is amazing, it’s so easy to write a generic function that can turn it into a DB transaction for any particular DB
RAD’s DB adapters do exactly that
and it’s only possible b/c fulcro stores app state in a global normalized way
I am trying to mark form as complete in :pre-merge
, where I have (and return) a data tree for component. Unfortunately mark-complete
function only works on normalized state map… is there some other way?
@roklenarcic You can just reach into the form config and set them…there should be a utility
I guess there should be mark-complete*
for inside mutatoins, mark-complete!
as a top-level call, and mark-complete
for data trees
yeah, I can try to copy the logic… currently I am hitting a wall guard-rails failing add-form-config's return type
which is weird since it’s return spec is `
(s/keys :req [::config])
which it generates by itselftimbre_support.cljs:80 ERROR com/fulcrologic/fulcro/algorithms/form_state.cljc:122 add-form-config's return type
-- Spec failed --------------------
{:app.model.sepa/full-name "",
^^
:app.model.sepa/address ...,
:app.model.sepa/iban ...,
:com.fulcrologic.fulcro.algorithms.form-state/config ...}
should satisfy
(partial app.model.sepa/max-str 140)
or value
{:app.model.sepa/full-name ...,
:app.model.sepa/address [],
^^
:app.model.sepa/iban ...,
:com.fulcrologic.fulcro.algorithms.form-state/config ...}
should satisfy
(<= 1 (count %) 7)
-- Relevant specs -------
:app.model.iban/iban:
(cljs.spec.alpha/and
cljs.core/string?
app.model.iban/correct-length?
app.model.iban/valid-checksum?)
:app.model.sepa/address:
(cljs.spec.alpha/coll-of
:app.model.sepa/address-part
:min-count
1
:kind
cljs.core/vector?
:max-count
7)
:app.model.sepa/full-name:
(cljs.core/partial app.model.sepa/max-str 140)
-- Spec failed --------------------
{:app.model.sepa/full-name ...,
:app.model.sepa/address ...,
:app.model.sepa/iban "",
^^
:com.fulcrologic.fulcro.algorithms.form-state/config ...}
should satisfy
correct-length?
-- Relevant specs -------
:app.model.iban/iban:
(cljs.spec.alpha/and
cljs.core/string?
app.model.iban/correct-length?
app.model.iban/valid-checksum?)
:app.model.sepa/address:
(cljs.spec.alpha/coll-of
:app.model.sepa/address-part
:min-count
1
:kind
cljs.core/vector?
:max-count
7)
:app.model.sepa/full-name:
(cljs.core/partial app.model.sepa/max-str 140)
-------------------------
Detected 2 errors
why does failing general specs on input data fail guardrails on return spec of add-form-config
, makes no sense…
I do not know anything about this but the :com.fulcrologic.fulcro.algorithms.merge/not-found
is a hint. Is something wrong with the state of the entity, i.e. the input data that feeds into add-form-config
? What and why? You require full-name
but somehow it is missing / Fulcro is unable to generate a prisitne state for it. Can you see anything there?
yeah but the error says there’s something wrong with add-form-config’s return type
Yes, because it contains the .../not-found
keyword where there should be a string. If you started with a valid entity - with valid data without "not found", it would have worked I assume.
When you fetch data from Pathom and ask for an attribute that it cannot resolve, it sets the value to this not-found key.
OK I now return ""
and that does not match the spec for that form element (at least 1 character is required)
and I still get an error… is the implication here that I cannot add form config to data that doesn’t validate on form field spec?
would be weird if that was true
Sorry, I have no idea about that. I was just guessing to try help you troubleshoot the problem.
@roklenarcic i’ve hit the same issue with guardrails validating my specs on add-form-config for whatever reason jfyi you can disable guardrails to throw exceptions on errors (so that it would just print them)
I’ll open an issue, it seems to be validating everything it can find…
@roklenarcic this is not specific to guardrails
It is a “feature” of spec that I’m still annoyed with and struggling to cope with when writing specs.
If you say map?
, then spec seems to check every key in the map…then again, I copied a lot of guardrails from ghostwheel, so perhaps that library does that? I don’t think that’s the case…I think it is spec, and there is nothing that can be done on our end other than, as @UDQ2UEPMY suggested, turn off throwing (which I turn off for dev, and on for tests).
unfortunately, this means you’ll get warnings from guardrails (or even exceptions) when you put a thing in a map and doesn’t fit the spec, even for a transient time period. On the one hand I see why, but on the other it prevents you from doing specs for intermediate helper functions that might use a key when in some intermediate state, or in the case of FUlcro the form-state config had to have its spec changes to be “this map of stuff, or an ident” so that it would die when seeing that key normalized.
ah crap
I’ll close the issue
I always forget about this totally stupid undocumented crap in spec
@tony.kay thanks for clarification, i thought that was the exclusive feature of s/keys
to check all the keys, didn’t know about map?
According to this, it does not do it for map?, at least not in this simple case
(s/def ::int integer?)
=> :com.example.client/int
(s/valid? map? {::int "I fail"})
=> true
(s/valid? (s/keys) {::int "I fail"})
=> false
This is Guardrails checking code that runs when enabled:
(defn run-check [args? {:keys [log-level vararg? throw? fn-name]} spec value]
(let [vargs? (and args? vararg?)
varg (if vargs? (last (seq value)) nil)
specable-args (if vargs?
(if (map? varg) (into (vec (butlast value)) (flatten (seq varg))) (into (vec (butlast value)) (seq varg)))
value)
valid-exception (atom nil)]
(try
(when-not (s/valid? spec specable-args)
(let [config (assoc log/*config* :output-fn output-fn)
problem (exp/expound-str spec specable-args)]
(log/log* config (or log-level :error) (str fn-name (if args? " argument list" " return type") "\n") problem)
(when throw?
(reset! valid-exception (ex-info problem {:fn-name (str fn-name)})))))
(catch #?(:cljs :default :clj Throwable) e
(log/error e "BUG: Internal error in expound or clojure spec.")))
(when @valid-exception
(throw @valid-exception)))
nil)
So I have no idea why valid?
for map?
in GR would be any diff from what you just did, yet I’ve seen it fail like @UDQ2UEPMY is saying, so not sure what is up. My assumption from my obsv. was that it was checking the keys…not sure what is going on now.
Works for me:
(quard/run-check false {:throw? true} map? {::int "I fail"})
=> nil
(quard/run-check false {:throw? true} (s/keys) {::int "I fail"})
Error: -- Spec failed --------------------
so something else is at play here...I have tried to replicate the form problem but failed. Any tips? I expected this to fail with a Spec error but it did not:
(comp/defsc NameComp [_ {::keys [name]}]
{:query [::name]}
(dom/p name))
(s/def ::name string?)
(fs/add-form-config NameComp {::name :not-found})
Tony: No problem with conform either:
(s/conform map? {::int "I fail"})
=> {:com.example.client/int "I fail"}
I use the one that comes with RAD, 0.2.176 @roklenarcic Could you try my code snippet ☝️ and see whether it fails for you?
@tony.kay I am online now for a while, if you want any assistance with https://github.com/fulcrologic/fulcro-rad/issues/32
@holyjak sorry, I just have bigger fish to fry. If you find something and want to send a PR fine, but I don’t want to discuss or even see issues like this for the time being. If I run into them myself I’ll fix them. If you want to patch something you see a fix for, great. otherwise, I’m sorry, I just don’t have the bandwidth for the distractions
Ok, got it. I will stick to the version of RAD that works then. I will try to dig into the code base but it will take me quite a while to be able to understand it somewhat :'( I'd love to send a PR but I am very far from having the knowledge to be able to make one.