untangled 2016-11-16

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.

Did it last minute yesterday

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.

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

Ie using the atom but fixed

@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)

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)

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

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

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

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

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

Always a good idea to let it simmer

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

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

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

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?

you have to run the server

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

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

right....that too 😄

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

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

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.

Thanks for the heads up

ok, I just released 0.6.0 of Untangled Client to clojars

untangled-template-workspace and cookbook pushed with updated versions

👍 1

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.

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.

👍 1

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

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?

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

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

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

@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

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

See the parameter of that name in the client construction function

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

I think @jasonjckn was trying it out

cool, I'll check it out

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

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

fallback runs if there is a real server hard error

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

I think you have to throw an ex-info

fallbacks are about reallllly unhappy path

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

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

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

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

it seems to be working

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

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

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

the bug is going to force a breaking change.

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?

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

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

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

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

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

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.

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?

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

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

👍 1

in other words: ask 🙂

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?

there is a gamut of possibilities. Choose one in specific

password failure on login?

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

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

those are global concerns

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?

easy enough to do the former via a js redirect

: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.

from the client constructor

global network error handler

right, makes sense

I think the template demos login, right?

it does, I saw the tx/fallback example there

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

it uses local, not global handling

no big deal 🙂

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

expire and illegal can come from anywhere at any time

don't want to code fallback into everything

yeah, agreed

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