Fork me on GitHub
#untangled
<
2016-11-16
>
tony.kay00:11:32

the new snapshot has support for dealing with return values from server mutations

tony.kay00:11:55

but I think we found a bug in it...

tony.kay00:11:57

In general, the recommended approach is to do a mutation with a follow-on remote read and a post-mutation. The new return value support makes that better, but unfortunately there was something amiss. Um...who was using that? Did we fix it? Sorry, lot's going on

wilkerlucio00:11:04

@tony.kay I remember that I read you talking about it, the new return value support, but I can't remember how it was supposed to be used

tony.kay00:11:12

The basic API is to install a return-handler method at app start time, which hacks into the merge

tony.kay00:11:43

See the parameter of that name in the client construction function

tony.kay00:11:10

generally you'd make a multimethod on the symbol that has a RV, and co-locate the defmethod for the return next to the mutation

tony.kay00:11:38

I think @jasonjckn was trying it out

wilkerlucio00:11:38

cool, I'll check it out

tony.kay00:11:48

the bug has to do with where in the process it runs

wilkerlucio00:11:49

curiosity: how does the tx/fallback captures an error above?

tony.kay00:11:02

fallback runs if there is a real server hard error

tony.kay00:11:12

e.g. throw an exception on server and generate a status code of 500

tony.kay00:11:31

I think you have to throw an ex-info

tony.kay00:11:54

fallbacks are about reallllly unhappy path

tony.kay00:11:03

the behavioral tests on it pass, but the subtle problem is that the atom is hit twice and ends up undoing the return value's change

tony.kay00:11:47

so someone needs to tinker with the plumbing to move that up. Haven't had time to look at it.

wilkerlucio00:11:06

ha, now that you pointed out, my template actually had an example with it picard-facepalm

tony.kay00:11:23

oh right...I knew I coded an example somewhere

wilkerlucio00:11:58

it seems to be working

wilkerlucio00:11:16

but I wish it provided the full enviroment, not just state

tony.kay00:11:55

you're not in a parser at that stage, you're in a merge

tony.kay00:11:14

which just means you should include context in the return value to reconstruct what you need

tony.kay00:11:12

the bug is going to force a breaking change.

wilkerlucio00:11:13

I remember the idea about colocating the response, do you think in our return-handler we could just call the parser again and use a different target function to dispatch the response?

tony.kay00:11:56

I don't have the query at that stage. It isn't passed through by Om

tony.kay00:11:19

so, you'll have to put all needed info into your response.

tony.kay00:11:30

which means you might have to pass extra info in the mutation itself

tony.kay00:11:03

I'm not sure the rv handling really helps much. I think follow-on remote reads make more sense in most cases

tony.kay00:11:23

validation, for example, is solved better by having a cljc file that makes validation possible on both sides without needing to worry about a response. Other responses would be better served (due to normalization needs) by asking a question of the server with a proper query as part of the overall transaction

tony.kay00:11:52

which is the main reason I had never added it...I think in general most cases don't need it, or there is a better "Om" way of doing it.

wilkerlucio00:11:37

what about validations that can't be handled on the client, for example to check if a user name is taken, what you think should be the common way to handle?

tony.kay00:11:55

The double-swap problem in the current implementation just points out the additional incidental complexity of the overall solution required for return values to function properly in the context of Om

tony.kay00:11:03

(load-data :name-taken :params { :desired-name "boo" }) with a UI query on [:name-taken '_]

tony.kay00:11:25

in other words: ask 🙂

wilkerlucio00:11:31

in my case, I'm currently trying to implement some authentication mechanisms. when you detect unauthorized access, you fail with some HTTP status or do something else?

tony.kay00:11:00

there is a gamut of possibilities. Choose one in specific

tony.kay00:11:12

password failure on login?

wilkerlucio00:11:42

session expired, or user trying to access resources he doesn't own

tony.kay00:11:22

probably a combo of throwing exceptions on the server and a global error handler in the client

tony.kay00:11:40

those are global concerns

tony.kay00:11:16

the first should go t a login screen. The second is someone trying to break in and should be considered less friendly (and common)...who cares how badly you treat an attacker?

tony.kay00:11:32

easy enough to do the former via a js redirect

tony.kay00:11:57

:network-error-callback is a function of two arguments, the app state atom and the error, which will be invoked for every network error (status code >= 400, or no network found), should you choose to use the built-in networking record.

tony.kay00:11:04

from the client constructor

tony.kay00:11:08

global network error handler

wilkerlucio00:11:10

right, makes sense

tony.kay00:11:28

I think the template demos login, right?

wilkerlucio00:11:41

it does, I saw the tx/fallback example there

tony.kay00:11:45

so, a mutation followed by a "who am I"

wilkerlucio00:11:49

it uses local, not global handling

wilkerlucio00:11:17

no big deal 🙂

tony.kay00:11:21

that's fine too. Login is a localized concern. The ones you named are more global

tony.kay00:11:36

expire and illegal can come from anywhere at any time

tony.kay00:11:42

don't want to code fallback into everything

wilkerlucio00:11:16

thanks @tony.kay! I'll go back to coding now 🙂

mitchelkuijpers08:11:49

Btw @tony.kay I tried the return-handler and had lot’s of problems, the first one is that you get an app-state atom which will be overwritten by the merge. After that we tried to trigger a mutation from the return-handlerthat somehow get’s run in the between the merge and also get overwritten.. lol Now we fixed it by wrapping our return handler in a setTimeout, which works but feels dirty.

tony.kay15:11:46

Did it last minute yesterday

tony.kay15:11:00

I am considering changing the api and putting it back in merge but making return handler be f state -> state instead of giving the atom.

tony.kay15:11:15

Torn. The new way is probably better because it can be placed after post mutations

tony.kay15:11:41

Ie using the atom but fixed

mitchelkuijpers15:11:10

@tony.kay Or you could make an atom in the merge en then run them all and then dereference the atom and use that to merge on (that was the solution we thought of)

mitchelkuijpers15:11:37

But running it after the merge also makes it possible to trigger transactions from the return handlers (although I am not sure you should do this)

tony.kay15:11:19

Ah that's true, but seems silly to add an atom in fp for that

mitchelkuijpers15:11:58

That’s true but then it feels like the same api as mutations..

mitchelkuijpers15:11:25

When you put it that way the maybe pull request #53 is the right solutino

tony.kay15:11:04

I'm headed to work now, I'll give it more thought on the wat

mitchelkuijpers15:11:27

I’ll wait it out, we have a hack for now 🙂

mitchelkuijpers15:11:36

Always a good idea to let it simmer

tony.kay16:11:48

So, my proposed fix doesn't work. That section only runs for queries

mitchelkuijpers16:11:21

Thnx for the heads up @tony.kay So then it will probably become the f state -> state. I’m off now if I think of a elegant solution I’ll let you know

tony.kay16:11:34

Yeah, that's what I'm going to try next

afhammad17:11:45

Trying out untangled for first time using https://github.com/untangled-web/untangled-template-workspace. Doesn’t seem to be working out of the box. Client can’t reach server on localhost:3449/api when running (start-figwheel). Also /cards.html can’t find cards.js. Am I missing something or is it still WIP?

tony.kay17:11:11

you have to run the server

tony.kay17:11:41

the instructions are pretty clear about how to use it, I thought. If you find an error let me know

afhammad17:11:29

ah, i had the server running but i was using 3449 instead of 3000 in browser

tony.kay17:11:01

right....that too 😄

afhammad17:11:58

Do I need to run anything else for cards to build?

afhammad17:11:10

This did the trick (start-figwheel [:dev :cards])

tony.kay17:11:56

FYI: I'm releasing an update to U.C. 0.6.0-SNAPSHOT which has a breaking change on the new return handler API. Details coming as soon as I've tested in against all of the cookbooks to make sure I've not broken anything.

gardnervickers17:11:44

Thanks for the heads up

tony.kay17:11:26

ok, I just released 0.6.0 of Untangled Client to clojars

tony.kay17:11:33

untangled-template-workspace and cookbook pushed with updated versions

tony.kay18:11:35

I just pushed an updated devguide. I added documentation on the new load function, as well as the mutation merge support. Both are in section H.

tony.kay18:11:09

The new load should be considered of alpha quality, as we have not used it much yet. I'll be using it more heavily in the coming days and will bug fix things as I find them.

tony.kay19:11:35

NOTE: cookbook now has a recipe showing a couple of working examples of the new load API: https://github.com/untangled-web/untangled-cookbook/tree/master/recipes/load-samples

jasonjckn22:11:47

does untangled have a built in helper for the pattern of conditionally doing a server read on df/load [x/by-id "123"] only if the data is not present in the app-state?