This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-10-07
Channels
- # aleph (15)
- # beginners (18)
- # boot (18)
- # business (1)
- # cider (11)
- # cljs-dev (13)
- # cljsrn (19)
- # clojure (14)
- # clojure-austin (8)
- # clojure-dusseldorf (1)
- # clojure-finland (1)
- # clojure-greece (118)
- # clojure-poland (3)
- # clojure-russia (46)
- # clojure-spec (65)
- # clojure-uk (18)
- # clojurebridge (3)
- # clojurescript (16)
- # cloverage (7)
- # core-async (8)
- # cursive (74)
- # datomic (28)
- # editors (3)
- # emacs (3)
- # ethereum (5)
- # hoplon (19)
- # jobs-rus (18)
- # lein-figwheel (1)
- # off-topic (2)
- # om (107)
- # om-next (4)
- # onyx (23)
- # pedestal (23)
- # proton (3)
- # protorepl (1)
- # re-frame (108)
- # reagent (10)
- # ring-swagger (15)
- # spacemacs (2)
- # specter (11)
- # testing (7)
- # untangled (79)
- # vim (4)
- # yada (53)
the problem is: how I can recover the possibility to ask for remote call when I use the parser recursively?
@rastandy are you using om/db->tree
?
@wilkerlucio no, I have a custom database format
the problem for me is that if I call the parser recursively from “read”, I lose the possiblity to ask for remote call from my read methods
umhum, I see the issue, I don't know how to solve that using a recursive parser
are you doing it for the sake of learning or just trying to get something working?
had you tried the Untangled framework?
you don't have to choose the backend
I for example only use the untangled-client
because it saves me all this work on the parser
at least on the client-side, on the server-side I'm using cljs + node
no worries, if you have some time take a read on their docs: http://untangled-web.github.io/untangled/reference/reference.html
@rastandy: here's an example of solving the problem you're having: https://github.com/awkay/om-tutorial/blob/master/src/main/om_tutorial/parsing.cljs#L191
@anmonteiro thank you, will take a look at that
btw, @anmonteiro thank you for your great talk “Clients in control”, I really enjoyed that, and also I started reading your blog
Thanks, always glad to be of help
Here's how I've been doing it @rastandy. https://gist.github.com/petterik/abfae9d8383138b2daa83588e4c7a9fb
It's a bit hacky and I should probably look at the om-tutorial version. Just thought I'd provide another example
@petterik I’m not able to understand your solution, maybe when I’ll go deeper in this problem
@rastandy I didn't understand it either. Was a long time since I hacked it together. So I made it better: https://gist.github.com/petterik/abfae9d8383138b2daa83588e4c7a9fb
which is now pretty much an inline version of the om-tutorial version, without the (decend )
code
Thanks for letting people know that Untangled doesn't force you into a back-end @wilkerlucio. That seems to be a common misconception. It is really just a collection of libraries that, taken together, provide a full-stack solution. But just in case others are wondering: The client and server libraries don't have any opinion on back-end database. There is a Datomic integration library that adds some helpers for that, but you could easily use PostgreSQL, MySQL, etc etc etc. Even the testing library (untangled-spec) is a stand-alone library that you can use stand-alone. Basically, Untangled makes it easy to get going on an Om Next app (you don't have to write a parser, network plumbing, etc.). You do have to tolerate a few decisions (e.g. we pick the "default" database format, and provide more complete merge/migration implementations), but we've not had a single complaint about that. We also give a server interaction story that is pre-constructed, but it uses stock Om-Next primitives...it just does a lot of the work you'd have to do anyway.
We're in the process of updating the docs (the tutorial is becoming a dev guide...feel free to check out the progress on the develop
branch of https://github.com/untangled-web/untangled-tutorial/tree/develop
The parser is actually called twice: once with target
set to nil
, and once with it set to your remote name (and then again for each additional remote you have)
When target
is nil
, it'll return the value of the :value
key. When target
is a remote name, it'll return the query you return for that remote.
so you actually do get the remote query when you're parsing recursively, you just have to make sure to call the parser with the target
@peeja interesting, are there some example of this? I’m not sure I understand the call graph 😞
Also, the :remote
key in the map you return from your read
expects an AST (or true
, to include everything), but the parser returns a query. You'll need to covert that query back to an AST to include it recursively in another read
invocation.
I don't have an example to point to, but you can see it happening here: https://github.com/omcljs/om/blob/master/src/main/om/next.cljc#L1267-L1273
And here (if I'm reading right) is where it calls it without a target
: https://github.com/omcljs/om/blob/master/src/main/om/next.cljc#L2560
The weird thing is that your read
generally returns a map, but the parser is only ever paying attention to one of the keys in that map. Which key it cares about depends on whether it was invoked with a target
(and if so, which one).
You can also check the value of target
in the env
from your read and only calculate the :value
or the :remote
as appropriate, if you'd like.
For instance, we're doing this:
(defn read [{:keys [target] :as env} key params]
;; Dispatch to either read-local or read-remote. Remember that, despite the
;; fact that a read function can return both a :value and a :remote entry in a
;; single map, the parser is actually only looking for one or the other during
;; a given call, and the presence or absence of target tells you which it is.
(case target
nil {:value (read-local env key params)}
:remote {:remote (read-remote env key params)}))
We found it wasn't useful to make read
the multimethod; instead we've got a read-local
multimethod and a read-remote
one.
I’m trying to understand your suggestions, but I think I need to study the source first, because the process is still obscure to me
Keep slamming your head against the things that don't make sense until it all clicks. That's how I did it. 😛
I need to make a working demo very fast or else people will think this is a too complex solution to use
but I will try hard, I feel like there is nice panorama after the tip of the mountain 😉
If you can get away without calling the parser recursively, it'll probably help. It takes a bit of massaging to do it right. Even if that's ultimately the right thing for your app, it may not be worth the time for a prototype
@rastandy Thanks. One of the main reasons we built and open-source it is I realized a number of things were a bit hard to reason about (like the stuff you're discussing right now with remotes). I saw a number of generalizations (e.g. when you want to remote: you end up marking things in state, running a parser to figure out how to do things...which just looks at something you invented in state, and then return the whole remote true/ast. I realized that you could build all of that in, so you didn't have to write all of that. The load story becomes explicit calls instead of these convoluted constructions of parser/state)
and you get things like "loading markers", no need for process-roots
, etc. The main trade-off is that you move away from a parser and towards explicit post-read data transforms.
The overall model is mostly preserved (which is awesome, because David designed something really cool here), but most of the pain evaporates.
@tony.kay If I can query a REST api without writing any server code, I think I can give it a try
We wrap an external REST api with our Untangled server, if that helps, it's a bit of indirection, but lets us be more flexible.
well, actually, you could replace the networking component on client. That is supported
just implement untangled.client.impl.network/UntangledNetwork
(two functions, only one of consequence).
you get the EDN, and would transform it to REST, then call the provided ok
with a proper Om Next response transformed from the REST response
Taking @therabidbanana 's approach is better, because then you get all the coolness of other bits as you add new functionality.
saving your messages for when they’ll make sense, after reading the Untangled tutorial
@tony.kay I think that having a good story for REST api’s is nice because it’s easier to convince people writing the frontend that om.next and clojurescript are awesome
@rastandy If that's what you're doing, though, you're losing some of the best parts of the Om Next story.
@rastandy I hope you convince them! You and your corporation are very welcome to this community
@petterik I hope it too! Frontend development is awesome with clojurescript and om.next!
I'm sorry if it's already covered somewhere, but I suddenly realized that I don't understand why :foo/by-id is a common idiom in Om land. Why :foo is a namespace here? As far as I understand, we don't usually have :foo/by-id, :foo/by-bar, etc. Why not :by-id/foo?
does anyone here knows if there is a way to access React private API's from the compiled version? I want to use the ReactMultiChild
mixin (used by people on react-canvas), but I can't figure how to access it