This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-27
Channels
- # architecture (6)
- # beginners (36)
- # boot (4)
- # cider (74)
- # cljsrn (5)
- # clojure (87)
- # clojure-denver (2)
- # clojure-finland (2)
- # clojure-gamedev (5)
- # clojure-italy (10)
- # clojure-nl (1)
- # clojure-uk (45)
- # clojurescript (33)
- # code-reviews (5)
- # core-async (12)
- # cursive (17)
- # datascript (2)
- # datomic (71)
- # duct (4)
- # emacs (19)
- # figwheel (1)
- # fulcro (4)
- # garden (1)
- # hoplon (18)
- # jobs (5)
- # leiningen (2)
- # off-topic (73)
- # onyx (14)
- # overtone (2)
- # portkey (32)
- # re-frame (62)
- # reagent (46)
- # shadow-cljs (76)
- # spacemacs (2)
- # sql (14)
- # tools-deps (5)
- # yada (3)
is nesting atoms a code smell? trying to create a nested form with flexible fields - can add or remove fields, and each field has a value state.. using a single atom & cursors seemed like a good fit, but it made it difficult in another way (`track` - ing the value to auto-generate errors, couldn't think of a good way to reference the nested value)
but.. you'd have to check for an error when rendering.. I wanted the error to also update alongside updating the value
so I switched to
{:fields
[
{ :field-id etc....
:value (r/atom ~~)
:err (track value atom -> validate -> maybe error)
}
]
})
> but.. you'd have to check for an error when rendering.. what kind of error? where does it come from? also, do you mean that whatever gets rendered in the end depends on that error?
yes, each field also has validation attached - when the value is updated it gets validated eg. too long, by regex, whatever
i was originally nesting that information with the original data layout, and then calling it within the render function
rather, I'd like it to be called when the value is updated, and just the result passed down
i would keep the data that specifies the layout separate from the validation of the fields... are you using re-frame? it would be easy to setup some validation with interceptors on teh events that the form sends.
i'm developing it outside of re-frame so it can be dropped into larger projects. I've found that I don't like keeping temporary form values in the main app db; don't like sending events on every form update
the idea is you have a form schema, and some previous values.. the library will generate a "live" version of the values which can be: * rendered as fields which update the data using the library * serialized when all nested validation passes, return error if not * validated on serverside using the same schema
still playing around with what the "live" version of the data will look like. . a single big atom, or a bunch of nested atoms..
schema->form kind of thing? like https://mozilla-services.github.io/react-jsonschema-form/? + serverside
nice..
so for me there is the schema
and the data
The schema is a map
that contains data types and validations etc.. a spec of the possible shapes of the data.
The data from the form is in a single atom
that gets updated on changes and (optionally) validated using the spec in the schema
wouldn't this be a good fit for clojure spec?
yep similar to that, but also with nested fields, compound fields, and flexible fields
flexible fields have set types you can add -- eg. image, markdown, email -- and they can be re-ordered
compound fields are sets of fields which can be added to a flex field and validated together eg. a banner link would be a url / image url.. if the url isn't blank but the image is blank, that would be a compound error.
I've been using funcool.struct
for validation, spec might alternatively be part of it.. not sure yet.
https://github.com/alexanderkiel/phrase I'm just validating single fields as the UI happens, so this could easily be dropped in.
sounds good,
I would definitely have a map or if using spec a spec for the form schema
that defines the shape of the form and its elements. this is static and never changes, if something is optional or can contain a flexible number of items, that would be part of the definition of this schema. the validation functions can be here as well as they further define the possible shapes the data can have,
and the data/state of the form in a single atom whose that follows the schema and when it is updated, on a what or on swap!, check the path to what is being updated and run the validaton function for that path...? ... or if using spec, just check that the data conforms to the spec
yep, sounds like what i have - the form schema generates the live data.. just westling with how to do simultaneous value and error updates... a magic fn which does both, a large single atom watched which re-validates everything, nested atoms with nested tracks.. somehow pass a chan down which can take an update event w/ a path.. a global chan i can send an event to..
same here, love spec but still integrating it in my mindset > just westling with how to do simultaneous value and error updates... what do you mean by that. also, could you use cursors and when updating the data, get the validation function that resides at the same path in the schema and validate?
I mean, the error really is just a projection of the value.. so, I'd rather not update it manually, but rather, have it be automatically generated from the value
here is some conversation along those lines "Converting ValidationErrors to user friendly messages" https://github.com/plumatic/schema/issues/56
Can someone help me? I used gensym to generate keys for a list of items as below.
(->> blog-lists
(map #(identity `[:div {:key ~(:blog-id %)} ~(:blog-content %)])
(interpose [:hr {:key (str (gensym))}]))
And the Chrome console gave me the following error message.
Warning: Encountered two children with the same key, `G__7`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted β the behavior is unsupported and could change in a future version.
in div (created by shomiyamoto.views.blog_entries)
First of all, what should I do when I want to give identity-less components like [:hr]
unique keys so React doesn't give me warnings.maybe..
(for [{:keys [blog-id blog-content] :as b} blog-lists]
(when-not (= (first blog-lists) b)
^{:key [(:blog-id %) :hr]} [:hr])
^{:key (:blog-id %)}
[:div blog-content])
or forget the [:hr]
and use css for borders with a :first-child
disabling the top border
That's probably the best solution! Without your suggestion, I would have wasted my time somehow insisting to use gensym, this time with mapcat, which should work but not as idiomatic as your solution.
(map-indexed
(fn [idx {:keys [blog-id blog-content]}]
(when-not (= idx 0)
^{:key [(:blog-id %) :hr]} [:hr])
^{:key (:blog-id %)}
[:div blog-content])
blog-lists)
Got it. No point of generating random keys. Just need enumeration and separate first and rest.