strange. You should look through the generated uberjar (i.e. generate one locally and run jar tf file
on it)
Look for the following:
1. It missing
um
what was the other one ...
I don't remember what goes in there. I think uberjars are exploded, and often the clj files are compiled into classes.
sometimes classpath :exclusions can drop it (e.g. it is in dev, but not prod profile)
I've also seen weirdness when a lib (source) gets accidentally included inside of another one
or different versions get included, and the one that ends up compiled in is an old version
e.g. during dev your classpath has a newer one, and in prod it has an old one
almost certainly is an issue like that
i understand it gets hairy thats why im developing my skills to look in the uberjar and the loader etc
so, look at your :dev profile, and lein deps :tree
My guess is if you analyze what is pulling in component, you might find it is resolving through :dev profile
which is not used for uberjar
ok it'll take me a little while to bring that up in the context of the heroku build
oooohhhh nice idea
a quick fix might be to put the latest ss component in your main deps
if it is already there, then that worries me a bit. Anything in your top-level deps should take precedence in all envs
https://gist.github.com/anonymous/d092e747bc9d6e358afbc61cef5e137f in ex5, @reconciler has entries for :person/by-name in ex6, @reconciler does NOT have entries for :person/by-name my question: how does @reconciler know about :person/by-name ? I see that it's defined in defui Person .... but I don't see how this info is passed to reconciler
@tony.kay Thanks for adding the form argument to the validator. I now have access to the form field values to be leveraged in the multimethod to f/form-field-valid?
(defmethod f/form-field-valid? 'less-than-value-valid? [_ value {:keys [untangled.ui.forms/this-form field min max]}]
(let [value (int value)
field-value-to-test (f/current-value this-form field)]
(and
(<= min value max)
(< value field-value-to-test))))
(f/integer-input :range-question/minimum-value :validator 'less-than-value-valid?
:validator-args {:field :range-question/maximum-value :min 0 :max 5})
Hello. Just wondering, are there any docs or example apps on how to do server side rendering with untangled ?
I think I'm finally starting to understand this Query/Ident model
Query is: I'm given these props. How do I select the part of it I care about? Ident is: I'm given these props. How do I derive an ident from it (this will correspond to where this ident is stored in the graph databse).
@qqq yep
@claudiu Not yet. I swear I wrote something as a quick demo, but I don't remember where. Needs to be a cookbook recipe
it would be the same as Om Next
so, any example that works there would work for Untangled. You'd just render to string using the root node and a props tree.
Our InitialAppState would make it a bit easier to get an initial state for that, but otherwise identical
Working on a reusable file upload component. I'm also adding support for multiple remotes in client, which will assist with these kinds of components.
having a tl;dr confession moment... I'm having a hard time reconciling in my imagination how to work with typical REST services/microservices and the type of server/client syncing that untangled provides... can anyone summarize or direct me to resources to help clear this up?
I'm used to pedestal style swagger dealios
@macrobartfast Two possible choices come to mind:
1. Implement UntangledNetwork and provide that to your client. Your send
implementation would convert the EDN requests to REST calls, and translate the responses to properly structured EDN for giving to callback that send is given (which merges the result for you)
2. If you own the services, use the normal network stack that comes with Untangled and do back-end integration with the real data instead of using the REST. Part of the point of data-driven apps is you want the client query to be the network protocol
Om Next (and therefore Untangled) kind of assume you want to avoid REST for the most part, and want an overall better model. So, our story for REST integration is present, but not primary
3. Use the normal Untangled network stack to wrap up your standard REST services - translating EDN requests into REST calls as necessary (and caching the data if you want), if those already exist (this is the option we use)
That is my (2), I think
Ah, I thought you were implying talking directly to the databases instead of using REST though.
AH, I was
if you're using the whole stack, does that mean you're going to one server, then talking to another?
UC <-> US <-> REST
Yeah. We're in a somewhat unique position though - we already had the RESTful api built out and have another application built relying on it.
that is going to be common, I just don't understand why it is easier to proxy to REST than it is to just implement calls to the functions that the REST API uses to build the responses...YMMV 😄
not saying that ppl won't want REST for legacy integration points
just that I would not normally choose to complect the two if I could avoid it
at that point why not just do the REST translation layer in the client, as in suggestion (1)?
Yeah, definitely a mileage-may-vary situation. For us it was easier because all of that code lives in a Ruby app. And proxying has benefits because we get the opportunity to cache and store the data into datomic and usually serve that instead.
ah
Making it more UC <-> US (sometimes to get more data: <-> REST)
I see
that was really helpful, thanks!
@macrobartfast the networking stack is in untangled.client.impl.network. The protocol is public...the namespace name is an unfortunate legacy oversight
My tongue is bright orange from all the architecture decoupling kool-aid I drank, and I associate REST interfaces with that, so it's a bit of a brain warp to think about the more direct approach.
For instance, building out an app server to support a web app, a cli tool, and a couple native mobile clients...
it seems like the REST approach might be better down the road, but I think I'm not grokking something, no doubt.
Here is a possible architecture:
Webapp <----> US <--------|
|
CLI <-- REST --> XLATE -->| Common Access API
^ |
Mobile <---+-- or------ ------->|
hm....got the whitespace a little off
bleh...you get the idea. Mobile/cli could talk to REST, which is a thin layer over top of the real APIs that get/manipulate the data
webapp in Om/Untangled uses the read/mutate Om parser technique on the server, and uses the same common API layer
that would be the best of both worlds, then
Then get Om/Untangled going with react native....
😉
lol, took the words out of my mouth
yeah, because I'd much rather go in that direction than native
then get your CLI written to use cljs in node
😄
*native mobile apps
and re cljs in node, exactly
aight, that's reassuring and helpful
😀
kool-aid squared
or cubed, I guess
lol
I'm using the client routing code in 0.7.0 and it appears that it breaks the app-state database in some way, I've got a ui/menu-active in the root of a screens query and I'm trying to toggle it with ucm/toggle!. It does toggle part of the app state but it's the state described by the screens ident rather than the state that's held and returned in the screens query which stays the same (the value set in the initial-state)
Could be you have a name collision
e.g. you named a table the same as some other top-level kw
check the keywords you're using in ident functions
more common source of this kind of confusion
I established the bad habit in the early days and a lot of our docs have examples with non-namespaced keywords that tend to lead to this problem
I don't think that's the problem as I can't find any ident collisions (I only have two screens - a login and message screen) Should the ident of each screen correspond to anything that the router knows about (implying the screen knows where it's placed in the router)?
Yes
The ident of the screen must have a first item that matches the route's name.
which must be obtainable from the data in the object itself, since the ident function on the router reads it
In other words, the ident
function on the router is the ident function for the screens it routes to
those screens don't get an ident function of their own
that's how the queries resolve: the "current ident" of the route also "routes" the query
so they therefore should have an ident implemented?
shouldn't
no, the ident on the defrouter is their ident
so, their state must be set up so that the ident on the router returns an ident that has the screen "name" as the first member
I believe the docs say this, but it is an unfortunate fact that all of those things have to align 😕
okay, I think I understand a bit more now, I'll recreate a simple test case so I can examine what's going on a bit more 🙂
Here's something I continue to not understand. 1) We can pass in data via props / computed. 2) Why do we have an extra component for defining queries to pull in more data? 3) Why not send in all data via props / computed ?
@qqq Tony talks a bit about computed in this video https://youtu.be/fH0DX0Dubx8?t=22m34s
@qqq you're number (2) does not make sense to me. Too many possibilities for what you mean.
and (1 and 3) are always how the data gets passed through the tree, no matter what
So perhaps you're asking "why queries?"
the answer to that is the main central defining quality of Om Next...so you should watch more David Nolen talks...or perhaps stuff on Facebook's Relay or Netflix's falcor
@tony.kay: That's an accurate deciphering of my question. The point I'm now confused on indeed is: "why have queries at all? why not pass all data through props/computed entirely"
qqq: queries specify the data that becomes the props