@tony.kay I don't know if there's a way to replace a pull request, so I just make a new one.
you can force push on your branch
it will auto-detect the change
Ah. It's so ingrained in me to not push a rebase.
e.g. do a git reset --soft ...
, then commit the work as a single patch, then force-push
Thanks for the tip.
@grzm one more tip (I can take care of this one): we work against the develop branch (git flow). Master is for releases.
@tony.kay Thanks 🙂 Hopefully your tips are a good investment and I contribute more 😉
@mitchelkuijpers FYI, I'm continuing to work on the template (in the template workspace project I mentioned earlier). I've added full support for running all tests from the command line (cljs and clj) for CI.
I also added some example "extra routes" for REST integration with other clients, commented the sample of hooking into the Ring chain, and beefed up the README quite a bit
can I override the default error handling mechanism
like a default tx/fallback when there is none
there is a global error handler you can set
nice thanks!
but it is really for errors that the server "calls" errors
more like 400 error codes
there is no global idea of fallback, since the transactions are meant to be abstract mutations that need some kind of rollback
But, a helper function that always includes some specific fallback in your mutations is trivial to write
@ethangracer Did we ever get to the "clear the network queue" as a function ppl can call?
the error handling story isn't complete, and that is part of it
@tony.kay not that I’m aware of
the last modification I remember making was to add the previously received error to the lop level of the app state
I think it is time to add the support for clearing networking's throat, so to speak
is the global error handler still called if there's a tx/fallback?
other way around
a server response that says "bad monkey" will trigger g-e-h
and then, I think, any fallbacks
@ethangracer can you short-circuit fallbacks?
I'm in the code reading, so if you don't know, don't look it up 🙂
@tony.kay yeah I’m not sure off the top of my head
pretty sure that you can’t
not that there’s any harm in having it run if it isn’t implemented and just returns nil
@jasonjckn Confirmed. Fallbacks will always run on errors
@jasonjckn the global error handler is always called, yes
the global callback is built into the networking layer object, which (if you override) is lower level
Ok cool
that fits my use case
also, remember that overridding the network layer would lose that support
@jasonjckn @tony.kay see here for a higher level explanation of the error handling, if you haven’t already https://github.com/untangled-web/untangled-cookbook/tree/master/recipes/error-handling
i have read that, i'll read it again
oh right...the recipe 😉
our whole team has read that 🙂
we do have some documentation 😅
Yeah, we still need the ability to say "stop processing the stuff that's optimistically queued"
@tony.kay I don’t fully understand what you mean by that
I thought that everything was batched and sent at the same time, in one transaction
why would we ever need to clear the queue?
say you did five things in the UI, and the first transaction has gone remote, the rest are waiting
assume network is SLOOOOOW
4 are still queued. Say you said "add this new list", "add an item to that list"
if the first fails, then the second SURELY will
we rewrite tempids in the queue to deal with the fact that "add" will respond with a rewrite
but we have no way for the app to say "yeah, throw out the rest...nothing else will work"
gotcha
What you're missing is that these are separate UI interactions, and the net is slow...so it was multiple calls to transact!
I should probably write down the list of "TODO" items somewhere 😉
yeah that makes sense. no reason to trigger errors unnecessarily.
well, it might be ok to trigger them, but some ppl will want to circumvent it.
right, no harm in letting it happen, but no harm in circumventing either
well, we don't know. It is their data. Could be ok, could be a disaster
much more complicatd to write fallbacks that "undo" the optimistic things in a predictable manner
much easier to say "reset to the point there was no list and stop processing" (in the sample case)
but the use-cases are hard to count, so flexibility is good
but the flip side: you really do not know what is on the queue...so clearing it might leave you in an inconsistent state
Ah, which means our "clearing" support should let you filter the queue
see, glad we didn't write it yet....spec is evolving before our eyes 🙂
It might be that the only case you ever want to clear are those that involve tempids that were in the failed tx...perhaps we just auto-clear those?
anything that has real IDs are probably valid (if you can get them to the server)
it's really the ones that are trying to work on a thing you failed to remap that are going to be a disaster...oh, but how can we know the difference?
Yeah, unhappy path handling with optimistic updates opens a can of worms. If I had to guess: most ppl will just reset the whole app if an error occurs.
Throw something up like "There was an error. Click here to reload"
@tony.kay sorry got distracted by another task. that’s exactly what we’re doing in insight — click to reload for everything. works like a charm, though it’s definitely a case of “if all you have is a hammer, everything becomes a nail"
though more fine-grained error handling is time consuming
and not necessarily that much better
I agree that filtering the queue is better than clearing it
@mitchelkuijpers Just FYI, I renamed reset-history to reset-history!
@tony.kay thnx, I got a go from my team on moving to untangled. But you can probably expect pull request for every lein plugin for a boot counterpart, because we won’t move away from boot. I hope you don’t mind ^^
We are also very interested in the untangled i18n solution, we would love to remove our dictionary.clj for translations.. because it is always out of date 😛
I am just watching the "Untangled Web Framework at Portland Clojure Meetup” youtube very funny to see a part about not using query parameters for the ui… I used the beginning and after a lot of fighting we would just put them in the app state and trigger the right refreshes. Solves so much problems.
@mitchelkuijpers Love to have boot stuff as long as the boot users maintain it
I just pushed UC 0.5.6-SNAPSHOT to clojars. This adds support to the UntangledApplication interface: - Ability to clear pending network requests - Ability to reset app state to original (as if just loaded), along with trigger a possibly alternate callback - Mitchel's reset history support...oh, wait, I guess I should include that in reset app 🙂...will push again in 5 mins
oh right
pushed...reset app should be feature complete and easy-to-use now
Btw one small question, if you load data from the server let’s say :contacts/list
and I want for some reason two lists, is it possible to somehow say merge this list in :contacts/list1
and load this with different params in contacts/list2
?
@mitchelkuijpers it sounds like you're about to "get it" 🙂
So, the stock Om idea is you write a parser so you can send queries to the server, have them come back as a tree, and then your parser can construct the various alternate views once that data is normalized.
As I'm sure you discovered in that model: the parser is a big maintenance point
So, in Untangled the load functions have a post-mutation parameter. The idea is that you morph the server response after it's been merged
much easier to reason about since that is a direct data transform
"the parser is a big maintenance point" that is a big YES
There are some helper functions as well in core
Aha that sound trivial.. lol
let me see.....
integrate-ident!
is kinda handy
I was thinking about using post-mutations, so I was in the right direction
yeah, it just takes all that inherent complexity away...you've got to reshape stuff...why not reshape it directly?
makes the db a little larger...but really? do we care?
My vote is this is a great space vs time/complexity trade-off
and my experience of working with it is muuuuuch better
Not to insult anyone on the channel (or myself for that matter), but most engineers find direct data transforms easier than parsing logic
(integrate-ident! state [:thing 2] :append [:people/by-id 4 :things])
is an example of that helper...
does some sanity checking for you too...eliminates mutation bit-twiddling on normalized databases, since a lot of what you do is pepper idents around
Nice that is a pretty powerful function
has :prepend, :append, and :replace
and you can specify them more than once in a single call
The spec tests are helping me a lot on understanding those functions
great!
I ❤️ spec testing...even when we don't always do the best job of it.
We currently have no testing story for the ui, we do selenium testing. But we will probably start using spec for the app-state testing
Bleh selenium. Did you see @therabidbanana blog post on using devcards?
No I think I missed it, we only use selenium for our happy paths but it they are mainly so we feel confident and we are creating a JIRA Addon. So we will detect early if JIRA breaks our addon
I see
We are building on atlassian connect and the way it works you can install addons on jira cloud and we will get an Iframe in a part of the application or we will get a complete Iframe for the page. This has some pretty nasty complications as you can imagine…
https://github.com/untangled-web/untangled-client Just released 0.5.6
@mitchelkuijpers, we are a boot shop happily using untangled for over 5 months now
we haven't needed to write any custom untangled boot tasks, though we don't use the internationalization thingy
@currentoor Aha cool, I’ll remember that if I have any questions. I think we will look into the internationalization thingy but not in the near future, but shouldn’t be too hard to make that working 🙂
@mitchelkuijpers i had the same reaction as you though, untangled seems awesome but so is boot, i only want to use it if i can make it work with boot