Fork me on GitHub
#reagent
<
2018-06-12
>
kwladyka17:06:01

[:input
{:name "important-name"
:error? (foo)}]
What is the easiest way to get name of the input in foo in error? ? Probably some js code?

kwladyka18:06:17

I have deep reason to do it in that way. I am trying to write module to make simpler code for form in SPA.

justinlee18:06:06

it’s a little hard to understand what you’re trying to do. why not (let [name "important-name"] [:input { use name here }])

kwladyka18:06:45

I need to do somethig like that:

(defn show-error? [...]
(let [name (get-name-from-input)]
...))

kwladyka18:06:35

I can write everywhere (show-error? :email), (show-error? :password), but probably I can make it simpler by get this :name attribute from input

justinlee18:06:59

that’s going to be awkward. why don’t you just write a utility that generates the form/input directly instead of trying to decorate an already existing one? if you are sure that you’re going to be passed a hiccup, then you can probably do (get-in form 1 :name) but that is not idiomatic reagent code

justinlee18:06:54

for example, I have a (defn input [] ...) that helps with generating inputs

kwladyka18:06:33

Making my own input will limit customisation of code. For example this is my current input:

[mui/text-field
            {:on-change value->atom
             :on-blur name->atom
             :error email-error?
             :helper-text (if email-error?
                            (:email @names->error)
                            " ")
             :full-width true
             :auto-focus true
             :margin "normal"
             :name "email"
             :label "Email"}]

kwladyka18:06:17

At least it is idea which I am testing

kwladyka18:06:21

Not sure it is good or not

justinlee18:06:15

well as I said, you can pass hiccup to the show-error? function and then just query it. it is a normal cljs datastructure like any other

kwladyka18:06:40

not sure what you mean

kwladyka18:06:55

how can i read it from email-error?

kwladyka18:06:44

if it would be function

justinlee18:06:58

you’d have to either pass the hiccup directly to email-error? or invoke a function directly like [show-error? [mui/text-field …]] or [show-error? (make-text-field ...)]

justinlee18:06:05

it really isn’t a good idea

justinlee18:06:14

it won’t work with form-2 components

kwladyka18:06:43

I wanted avoid it

justinlee18:06:00

you need to factor the data that is common to your decorator and the underlying elements

justinlee18:06:16

trying to extract it from an already formed component is not going to go well

kwladyka18:06:26

No way to read input name in js?

justinlee18:06:48

uh sure at runtime after the component mounts

kwladyka18:06:24

ok so maybe it is bad direction

kwladyka18:06:29

I will find another way

kwladyka18:06:00

I can write (show-error? :email) for now

kwladyka19:06:46

For now I decided to do it in that way:

(let [specs->msg {::sc/email "Typo? It doesn't look valid."
                    ::sc/password "Password is required."}
        names->spec {:email ::sc/email
                     :password ::sc/password}
        names->value (r/atom {:email ""
                              :password ""})
        form (form/init-form names->value names->spec specs->msg)
        value->form (form/fn-value->form form)
        name->touched (form/fn-name->touched form)
        form-valid? (form/form-valid? form)]
...)

kwladyka19:06:23

it is still in progress

kwladyka19:06:18

Does it look promising?

kwladyka19:06:27

in spec-msg can be whatever spec :via will return. So also deeper spec problems

kwladyka19:06:52

Is there any module like that already?

kwladyka19:06:35

Example input:

kwladyka19:06:39

[mui/text-field
            {:on-change value->form
             :on-blur name->touched
             :error email-error?
             :helper-text (if email-error?
                            (form/get-error form :email)
                            " ")
             :full-width true
             :auto-focus true
             :margin "normal"
             :name "email"
             :label "Email"}]

Bravi21:06:28

thanks, I ended up doing this

(defn- focused-input
  [_ on-change]
  (r/create-class
   {:component-did-mount
    #(.focus (r/dom-node %))

    :reagent-render
    (fn [value]
      [:input.no-border.overlay-search.bg-transparent
       {:id          :overlay-search
        :value       value
        :on-change   on-search
        :placeholder "Search..."}])}))

justinlee21:06:47

hm yea i guess you can do it that way. i never thought about using r/dom-node

Bravi21:06:03

how do you usually do it then?

Bravi21:06:06

using refs?

justinlee21:06:02

yea. and you have to if you want to get a ref to anything except for the top-level node

Bravi21:06:14

yeah yeah

Bravi21:06:16

I mean I would have done it with refs as well, but since it’s just the root dom node I’m interested in, I think this makes more sense

justinlee21:06:25

yes i agree. it’s cleaner

Bravi21:06:57

I really like the new with-let form

Bravi21:06:07

so much simpler

Bravi21:06:27

even thought there’s not much taken away, it seems more clojure-y

justinlee21:06:54

someone was saying that it behaves weirdly with code reloading

justinlee21:06:37

though that conversation involved a finally clause and i was wondering if that was the issue

Bravi22:06:20

I do use finally as well, but seems to be working fine. I’m using shadow-cljs though, not sure if that would change anything

justinlee22:06:37

i may experiment with it

Bravi22:06:34

another question if I may - in the docs of rswap! vs swap!, it says that rswap! returns nil and that this is useful. and there’s an event emitter example. I would’ve thought that it’s possible to create the same event emitter using swap! too

Bravi22:06:16

or am I missing something 😕

justinlee22:06:26

i never fully grokked that. i think it’s a minor ergonomic thing: because swap! returns the value that was swapped in, you can’t do a one-liner that returns nil.

justinlee22:06:00

there’s also something about recursion there that i don’t understand