This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-02
Channels
- # aleph (14)
- # boot (4)
- # cider (3)
- # clara (1)
- # cljs-dev (62)
- # cljsrn (20)
- # clojure (81)
- # clojure-berlin (2)
- # clojure-russia (76)
- # clojure-spec (35)
- # clojure-turkiye (1)
- # clojurescript (84)
- # cursive (2)
- # data-science (6)
- # datomic (4)
- # hoplon (92)
- # lumo (35)
- # om-next (1)
- # pedestal (2)
- # re-frame (2)
- # reagent (36)
- # ring-swagger (10)
- # unrepl (30)
- # untangled (124)
I've watched that video a few times. Is one of the best for understanding things - very good video. I see that load-data
does have config
as last argument, which can include params
. So I guess can achieve [({server-property (om/get-query SubqueryClass)} params)]
by other means - in fact I can see that [state-atom server-property-or-ident SubqueryClass config]
will do the job.
So -action
means it is callable from within a client mutation?? That's the all important thing for me right now.
@cjmurphy yes. The -action
is intended to mean that. It’s really simple how it works: Calls to load
basically run a mutation transaction on the untangled mutation load
(don’t remember the ns). The load mutation gets processed, but what it does is stores your desired load info into an app state load queue. The mutation specifies that it wants to be remote. When the layer just above networking sees the load mutation, it instead pulls the stuff from the load queue in app state and sends those queries instead.
The -action
versions are the part that put the load on the queue. So, you still need to specify a remote-side, and data-fetch
has a function (`remote-load`) for generating the right-looking thing for the remote side that will cause load queue processing to happen.
any number of load-actions
can be run (each adding an entry to the load queue), and one remote-load
(as the return value of the :remote
side.
load-action
affects state, but Om won’t even try to go remote without a remote indicator, which is generated by the remote-load
function.
The doc string for load-action
is pretty specific about that. Do you not have docstring help?
(defmutation load-existing-rules [{:keys [sub-query-comp source-bank target-ledger]}]
(remote [env] (df/remote-load env))
(action [{:keys [state]}]
(df/load-action state :my-existing-rules sub-query-comp
{:target help/rules-list-items-whereabouts
:refresh [[:banking-form/by-id p/BANKING_FORM]]
:params {:source-bank source-bank :target-ledger target-ledger}})))
Mutations in Om can have multiple parts. The action
is always local. It cannot trigger anything to do with networking. The other sections are names of remotes (the default name of a remote is remote
). Each one indicates what should be done on that specific remote for this action. The special value true
means “the same abstract thing that happened on the client`...but for load actions, you don’t want to run load-existing-rules
on the server, you want to send the query. The load-action
has stored the query in a queue. The remote-load
returns an AST that will trigger the queue processing on that remote.
technically, for loads, triggering remote-load from any remote causes queue processing, and the queue entries themselves use a :remote
option to indicate which remote they query
@tony.kay The docstring even has example, so you are correct it should be pretty obvious. At the moment I just read docstrings by looking at the source (cntl+B on the function), where there is no colour coding or anything. The example is in the old pre-defmutation style and is at the top of some lines of comments. And a colon sometimes looks like a semi-colon to me. So to my eyes :remote (df/remote-load env)
was just part of the comments and got missed. If it had been new style, starting with a paren, or the remote had been after the action, so with lots of whitespace around it - in either of those case it would have been hard to miss. Syntax colouring is probably my answer - I'll see about using the proper IntelliJ way of looking at docstrings.
It is cnrl+Q on my Linux machine for looking at docstrings, but it doesn't have a different colour for code. Really I should have understood/researched your comment: "`data-fetch` has a function (`remote-load`) for generating the right-looking thing...". All my eyes needed was to see (remote [env] (df/remote-load env))
, which was nowhere to be found. I did try (remote [_] true)
, but of course that didn't help.
Yeah, this was one of the important realizations in Untangled: how to turn mutations into loads so that we don’t need a parser to be involved in remote queries. It turns out that you need a mutation to modify state so that your parser can trigger a load anyway in Om Next (otherwise you’d be loading at every parse…the state has to change so your parser can be intelligent about loading). So, the trick was to realize that any mutation with a remote AST will cause Om Next to try to send that over the wire, so we hack into that to transform the mutation into a query. The only downside is that composing loads into mutations then looks a little wierd.
I guess there could be some macro similar to defmutation that always indicates you’re wanting to process the load queue and does it for you.
I'm going to be calling om/tranact!
from within a defmutation... that's what about to try
When a drop down is loaded with all its values - thats the first mutation. It works out the value which will be the chosen value of the drop down. Now data needs to be loaded from remote for this chosen value.
so, you’re trying to write a mutation that 1. sets the dropdown display, and 2. triggers a load
if you say “remote true”, then you’re asking the top-level transaction to go over the wire…still doesn’t know the guts of action
by using remote-load
, you’re replacing the top-level transaction with a special AST that processes the network queue
I can just try it both ways, with and without making the first mutation remote. So it sounds right from what you are saying to make the first one be remote true.
but I assume you just elided that. So, remote true
means you want to send the top-level tx, as DATA, across the wire to the server, as is from the UI
Yeah the code I posted is the second defmutation, that I'm calling from another one.
If you’re doing a load-action
, you do not want to send the top level UI tx…you want to process the queries of load-actions.
you either:
1. Write a transact that does the two in succession: (om/transact! this '[(a) (b)])
2. Write a transact that calls one (om/transact! this '[(combo)])
and then in that one mutation you do the local updates along with load-action
I think I have to. No way round it - if not actually call, do the equivalent of calling.
Why not write a query that asks for both facts you need, as a union query. Then the server can tell you everything you need with one load
[{:dropdown-options (om/get-query DD)} ({:subdata (om/get-query Union)} {:current-selection :a})]
either the server knows the complete answer, or you know a fact you can tell the server. There is no need for chaining in these cases 🙂
(and two calls to load
in the same event handler will be sent together as one request)
Yeah the first mutation is choosing the one to be selected as current in the drop down, but that is the wrong place for that choice, I think...
You’re doing a thing like “choose your make of car”, then “choose a model”, where model gets loaded after they choose a make
1. the initial setup (e.g. a load of the first dd content)
2. The user interacts with the dd. This triggers (transact! this '[(choose-first {:val v})])
3. The choose-first
defmutation:
3a. Threads state through a function that updates the dropdown they interacted with
3b. continues the thread through a load-action
that can send the proper query and param based on v
3c. Has a remote
of (remote-load env)
(assuming you targeted the load-action result to the dd state, or otherwise got it there with a post-mutation)
By default "Expenses" say. Kind of arbitarily - perhaps the most popular choice in my mind, so user has to do less actions.
yeah, but you’re loading data they may not want to see at all, which is extra overhead for your user and your server
but whatever…you can do it either way, as I just described…just move the default choice load to step (1)
If I make the first choice explicit at the client level (not defmutation level) then I think my design becomes better.
say you show me expenses. You just loaded data from the server. That just consumed CPU and disk IO. Say you have 10000 users. They all go to that screen. You just did 10000 bits of CPU and IO. Now let’s say 20% of them didn’t want that. You just blew 2000 users worth of interaction time…slowing down the other 8000 as well.
ie "Expenses" - no reason that should be down at defmutation level - then my problem goes away.
They will all want it in my use case. They are creating a rule that they must create. So the 20% you mention is really 100%.
Yes. But I needed your help to get a better design. So thanks for taking the time. Working solo here...
My experience with Untangled so far has been: If it’s hard, you’re doing it wrong or missing a concept.
The “chaining” temptation is tricky: I loaded A, now A told me something that makes me want B. The thing is, unless you’re loading from more than one server, the server knew about what was in A when it sent it to you, meaning you could have also asked for B in a generic sort of way and had it handled at the same time.
There’s nothing technically impossible about using transact!
within a mutation, other than it leads to a design where you could conceivably end up with recursive-looking transaction loops. So, poor design. If you had to do a two-server chained load, I think you’d probably be stuck with it, though. I just strongly encourage not doing it in most cases. Hm. actually, I take that back. There’s no way to get the timing right. You’d probably have to install a merge handler and trigger the second one from there. Or use a post mutation to trigger a transact!
against app
. Post mutations are not allowed to have remote sides (they’re ignored).
If possible, I’d probably design server A to talk to server B for me, and avoid the whole client scenario 😜
hello people, I would like to announce a new little open-source project I built with Untangled, it's a Chrome extension to represent an Youtube Queue based your emails, I made a post about it, I hope you can enjoy it 🙂 https://medium.com/@wilkerlucio/using-gmail-messages-to-track-youtube-channels-ef35308a0ceb