Fork me on GitHub
#untangled
<
2016-04-12
>
vmarcinko15:04:25

hey all, I'm slowing building/learning my first om/untangled app, and now I came to forms... BTW, is there some good example of multi-field form out there that I could study? TODO mvc app just exposes single text field stuff...

vmarcinko15:04:55

meaning, I need some example of few form fields, and submit button etc...

vmarcinko15:04:09

Is om next kanban app good example of this, or Untangled offers some enhancements in this regard?

ethangracer15:04:52

untangled doesn’t have any field-specific enhancements, no. we do have the toggle!, set-integer!, and set-string! functions in untangled.client.mutations which are intended to be used for setting ui namespaced keywords on components. Those can definitely be used for form fields. If you’re looking to persist those to the server though, you’ll have to write your own mutations to send that data across the wire. As for good examples of form fields, we don’t have one in Untangled for now. Our apps all use optimistic updates that are immediately pushed to the server, so we have less of a need for more traditional submit logic. I’m periodically working on a cookbook of common code snippets so I can add it to my list — although PRs are always welcome if you find a dev pattern for form fields that you think works well

brianosaurus18:04:57

Is there an easy way to inject an error-handler into the untangled client? When we fail to authenticate we send back 403 and when we fail to authorize we send back 401.

ethangracer18:04:58

@brianosaurus: yes, you have 2 options. The preferred way is to implement a tx/fallback mutation to handle the errors, then you get to take advantage of the built-in networking. The other option is to implement your own networking object that defines its own error callback.

vmarcinko19:04:39

@ethangracer: Still not exactly clear about purpose of :ui/ attributes. For example, if I have standard text field, should I set onChange handler to call:

(ucm/set-string! this :ui/my-text-field-value :event evt)
or I'm missing the intended purpose here?

vmarcinko19:04:00

or should I just call standard Om's om/update-state! to set component's local state?

brianosaurus19:04:03

@ethangracer: it appears a (defmethod m/mutate 'tx/fallback [env _ {:keys [action execute] :as params}] doesn’t get called.

ethangracer19:04:14

@vmarcinko The only special thing about ui attributes is that they don't get sent to the server. So depending on what you're trying to do you might use UI attributes or you might use component local state

brianosaurus19:04:30

m is our namespace for untangled.client.mutations

ethangracer19:04:22

There is no use of tx/fallback in our code yes. You have to implement it for the transaction that you're doing... Not completely clear on how those work, that'd be a question for @tony.kay

brianosaurus19:04:00

@ethangracer: ahhh, gotcha. Thanks again.

tony.kay21:04:39

@brianosaurus: They are not tested quite enough, and were missing "clear the send queue"; however, in concept they are simple: Include a (tx/fallback { :action mutation-symbol }) in your transact. If the main bits of the transaction fail, the fallback mutations are run (in order)

tony.kay21:04:09

(transact! '[(my/f) (tx/fallback { :action undo-f })])

tony.kay21:04:33

the fallbacks never go to the server...they are stored with the tracking of the outgoing network request

tony.kay21:04:21

additional parameters can be sent to the mutation by including them in the fallback parameter map

brianosaurus21:04:05

@tony.kay: I see. Thanks. IMHO it would be nice to simply add a global error handler in something like new-untangled-client (eventually).

tony.kay21:04:45

Yeah, that is probably true...the context is often important, though...e.g. what did you do?

tony.kay21:04:13

The unhappy path definitely needs a bit more work

brianosaurus21:04:07

I suppose you’d need to pass in the http code, what you were up to, etc...

tony.kay21:04:38

well, the reasoning is as follows: - You did an abstract mutation, which included optimistic updates - The transaction failed on the server (for whatever reason...mutations do return error codes, but it typically isn't useful data) So, you're going to need to do one or more of the following: - Fix your local state (from the optimistic change)...you can close over that in your original parameters to the fallback - Figure out what the server actually knows. If you are still connected, you can ask (app/load), if you're not, you just don't know...so the UI should probably block and reload when available to restore state

tony.kay21:04:10

So, say you just added an item to the todo list. Your fallback is to either: remove the todo item, OR reload the entire list

tony.kay21:04:40

either mutation implies an idea of what the individual transaction was trying to do

tony.kay21:04:08

It is true that you might be able to detect the exact nature of the error (permission denied) and just undo the add locally

tony.kay21:04:33

So, that is where we should probably hook the real result (and http code) of the mutation into the fallback handling mutation

tony.kay21:04:46

For simple/lame apps, a global handler is believable: got an error: reload the whole shebang....but I'd hate to see a monster of spaghetti of case logic in a global handler trying to do something more clever

tony.kay21:04:24

The point is to have simple reasoning...nothing simpler than reasoning about failures where/when they occur

brianosaurus21:04:07

In the case of a 401 or 403 it makes sense to have a global handler. One is unauthenticated (your login timed out) another is unauthorized (someone revoked your right to do something)

tony.kay21:04:18

Yep. agreed

brianosaurus22:04:49

@tony.kay: Just wondering. On an optimistic mutation is the old app state passed back to tx/fallback on db failure?

tony.kay22:04:13

nope, but you can add what you need as parameters to the original fallback call

currentoor23:04:59

Hi fellas, I'm using the load-field and lazily-loaded functions like so. https://github.com/untangled-web/untangled/blob/master/src%2Fclient%2Fapp%2Fui.cljs#L66

currentoor23:04:02

Does DataItem have to have an ident?

currentoor23:04:31

Say instead I had a DatatItemsTable component instead that I wanted to pass the entire collection of data items to.

currentoor23:04:10

Right now I've got a hack were I use DataItem in the query (of that parent that calls load-field) but use DataItemsTable to render the collection.

currentoor23:04:52

I'm not sure if this is frowned upon.