Fork me on GitHub
#untangled
<
2017-02-20
>
nha18:02:38

I am not sure I can test if an om component implements a protocol in Clojure (asked in #om too). So this line is blocking me right now: https://github.com/untangled-web/om-css/blob/master/src/om_css/core.cljc#L67

tony.kay18:02:33

So defui in clj land adds the "protocol" things to metadata

tony.kay18:02:40

just a sec...

tony.kay18:02:07

this is why we need functions like get-initial-state. We can call the protocol ones in cljs, but not in clj because js allows his macro to hack them into place

tony.kay18:02:41

Om components have to be stock React components for interop, so we don't actually use protocols per-se, just emulate the syntax

tony.kay18:02:42

this is part of the cleanup work that we need to comb over in a lot of our docs/guide for sever-side rendering. You cannot, for example, call initial-state in your UI and expect clj-land to like it

tony.kay18:02:08

but many of our examples were written before it existed, and are now technically wrong if you want to do ss rendering

nha18:02:20

Ok that all makes sense. So I don’t have the metadata “protocol” with plain om.next components, right (I did have a look at meta in my Repl).

tony.kay18:02:29

I just aped what was in Om's get-query code 😉

tony.kay18:02:45

since that one has to work on both

nha18:02:21

ok I’ll have to dig a bit more (just starting with om 😛 ) thanks for the help!

tony.kay18:02:05

Just FYI on the forms support in ui: I'm touching up the full-stack protocol. It was a little too loose.

tony.kay18:02:24

i.e.: the network communication that is there is changing

baris19:02:10

Hi Tony, I’m using the forms support right now. Are any breaking changes expected?

tony.kay19:02:32

@baris Yes, but not at the UI level.

tony.kay19:02:02

The protocol that got written for telling the server what changed is a little off and unclear

tony.kay19:02:36

I had not code reviewed it, but am now writing the docs. It is technically working, but harder to reason about and use than it should be

baris19:02:53

ahh good to know....I’m in a couple minutes ready to touch the server side....good to know…I’ll wait then

tony.kay19:02:31

Yeah, I should have spec'd this better for the person that wrote it. Like I said, it technically works, just isn't ideal.

baris19:02:10

so far its works like expected and the form support is really handy 👍

tony.kay19:02:13

Yeah, I've messed with the UI layer enough that it is pretty solid. The full-stack stuff I loosely spec'd and got help for. The spec was too loose 🙂

baris19:02:46

I got the following strange use-case: 1) User starts editing an entity (like described in the demo devcard) -> forms show up 2) User makes some changes and the local app-state changes imediatly -> form is dirty 3a) User can revert the changes by clicking the "reset" button -> OK 3b) User commits the changes by clicking the "save" button -> OK 3c) User changes the screens for e.g. by clicking on another top navigation link -> form should reset but it saves the local changes

baris19:02:51

The confusing part is 3c. I'd expect even if I made some changes and I switch to another view (like cancel the current modifications) I'd expect that the changes do not get into the local app state.

baris19:02:57

The forms component already stores the original values in the an isolated :origin {...} map and only uses them when the "reset-*" functions are called. Maybe we should switch the logic here?

baris19:02:01

Store all local changes to a local isolated place and copy them to the orignal "entity" when save/commit is called?

baris19:02:05

For now, I do some workaround while switching the screens and it works so far for me.

tony.kay19:02:42

So, we debated this at some length internally.

tony.kay19:02:50

Here is the reason why it works that way:

tony.kay19:02:09

1. You can always compose reset into any mutation. So, nav without save can undo the changes

tony.kay19:02:40

2. We want you to be able to render just like you always have, and subforms throws a wrench in that if you make the stuff you're editing sideband

torkan19:02:53

Regarding form validation in untangled-ui, are there any plans for extending field validation checks returning more than a boolean?

tony.kay19:02:41

@torkan You're missing the point. Validation is for marking state in the tri-state system: :unchecked, :valid, :invalid. Boolean is all that is needed.

tony.kay19:02:47

The messaging is up to you in rendering

tony.kay19:02:12

@baris On (2), I can give you a more detailed example if you'd like

baris19:02:59

My workaround is ur number 1: I reset them manually when a nav mutation happens

tony.kay19:02:08

that isn't a workaround

tony.kay19:02:14

that is the way to do it 🙂

torkan19:02:16

@tony.kay Wouldn’t be the first time 🙂 I haven’t fine-combed through all the code yet, but it seems like there are no ways to determine why a field was deemed invalid?

baris19:02:20

perfect 🙂

tony.kay19:02:08

@torkan So, you can look at the value they've typed at the UI layer

tony.kay19:02:21

validation is about signalling. Messaging is about interpretation of value

tony.kay19:02:35

The latter is your responsibility in the UI

tony.kay19:02:01

forms support does state management, and all it cares about is that the field is "ok"

tony.kay19:02:19

If you're worried about code re-use: write a single function that returns nil when all is OK, and call that with not in your custom validator, then use the same function to generate the message on the UI

torkan19:02:34

Gotcha… I’m asking since a field might be technically valid in terms of conforming to a value range/regex etc, but business logic might still deem it as invalid, perhaps depending on values in other fields, and so forth…

tony.kay19:02:57

Some of that can only be handled with on-form-change

tony.kay19:02:18

non-local reasoning about fields, that is

torkan19:02:27

Redux-Form for example solves this by letting you pass methods for validating the form, and returning error-values for the fields that failed

tony.kay19:02:45

so we have both

tony.kay19:02:08

The form-level handling is a single function that can do anything to the form (change validation flags etc)

tony.kay19:02:20

the field-level validation is just about reasonable values

torkan19:02:27

Aaah, I totally missed that 🙂

tony.kay19:02:28

you could put the entire validation in the top-level one instead

tony.kay19:02:35

it isn't documented yet 😉

tony.kay19:02:48

and I have not code reviewed it, so it could change slightly

tony.kay19:02:59

The way it currently works is you can add a mutation symbol to the form support that it will trigger any time it detects a change in the form...I have not reviewed when it gets triggered, so I'm not sure what "detects a change" means at the moment 🙂

tony.kay19:02:12

that mutation can do whatever it deems necessary

tony.kay19:02:26

So, at the moment, it triggers on each change (e.g. keypress/selection)

tony.kay19:02:40

Seems like blur might be a better choice on input fields

tony.kay19:02:53

or perhaps the mutation should just be told what kind of change it is

tony.kay19:02:00

yeah, that needs to evolve a little

tony.kay19:02:13

the concept is solid, just needs execution tweaks

torkan19:02:09

Blur is a sensible default, as long as it can be overridden, at least in my opinion

tony.kay19:02:26

but blur will be most common of interest

tony.kay19:02:02

you might want to do tricky things like insert format chars...e.g. typing a cc number and auto-add dashes

tony.kay19:02:11

possibly, I guess

tony.kay19:02:24

might also just use comp local state for that kind of concern and a custom field type

torkan19:02:26

Yup, an error indicating that a new password the user is setting is too short for example, should disappear immediately

torkan19:02:59

Once the password gets strong enough, etc