Fork me on GitHub
#untangled
<
2017-02-28
>
tony.kay00:02:20

strange. You should look through the generated uberjar (i.e. generate one locally and run jar tf file on it)

tony.kay00:02:25

Look for the following:

tony.kay00:02:28

1. It missing

tony.kay00:02:09

what was the other one ...

tony.kay00:02:08

I don't remember what goes in there. I think uberjars are exploded, and often the clj files are compiled into classes.

tony.kay00:02:29

sometimes classpath :exclusions can drop it (e.g. it is in dev, but not prod profile)

tony.kay00:02:06

I've also seen weirdness when a lib (source) gets accidentally included inside of another one

tony.kay00:02:47

or different versions get included, and the one that ends up compiled in is an old version

tony.kay00:02:04

e.g. during dev your classpath has a newer one, and in prod it has an old one

tony.kay00:02:14

almost certainly is an issue like that

fragamus00:02:16

i understand it gets hairy thats why im developing my skills to look in the uberjar and the loader etc

tony.kay00:02:54

so, look at your :dev profile, and lein deps :tree

tony.kay00:02:24

My guess is if you analyze what is pulling in component, you might find it is resolving through :dev profile

tony.kay00:02:30

which is not used for uberjar

fragamus00:02:32

ok it'll take me a little while to bring that up in the context of the heroku build

fragamus00:02:47

oooohhhh nice idea

tony.kay00:02:02

a quick fix might be to put the latest ss component in your main deps

tony.kay00:02:37

if it is already there, then that worries me a bit. Anything in your top-level deps should take precedence in all envs

qqq01:02:35

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

darrellesh03:02:27

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

claudiu07:02:13

Hello. Just wondering, are there any docs or example apps on how to do server side rendering with untangled ?

qqq11:02:18

I think I'm finally starting to understand this Query/Ident model

qqq11:02:53

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

tony.kay16:02:52

@claudiu Not yet. I swear I wrote something as a quick demo, but I don't remember where. Needs to be a cookbook recipe

tony.kay16:02:06

it would be the same as Om Next

tony.kay16:02:30

so, any example that works there would work for Untangled. You'd just render to string using the root node and a props tree.

tony.kay16:02:50

Our InitialAppState would make it a bit easier to get an initial state for that, but otherwise identical

tony.kay17:02:57

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.

macrobartfast18:02:14

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?

macrobartfast18:02:39

I'm used to pedestal style swagger dealios

tony.kay18:02:12

@macrobartfast Two possible choices come to mind:

tony.kay18:02:52

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)

tony.kay18:02:07

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

tony.kay18:02:27

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

therabidbanana18:02:43

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)

tony.kay18:02:08

That is my (2), I think

therabidbanana18:02:30

Ah, I thought you were implying talking directly to the databases instead of using REST though.

tony.kay18:02:54

if you're using the whole stack, does that mean you're going to one server, then talking to another?

tony.kay18:02:12

UC <-> US <-> REST

therabidbanana18:02:27

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.

tony.kay18:02:12

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 😄

tony.kay18:02:34

not saying that ppl won't want REST for legacy integration points

tony.kay18:02:48

just that I would not normally choose to complect the two if I could avoid it

tony.kay18:02:38

at that point why not just do the REST translation layer in the client, as in suggestion (1)?

therabidbanana18:02:05

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.

therabidbanana18:02:34

Making it more UC <-> US (sometimes to get more data: <-> REST)

macrobartfast18:02:16

that was really helpful, thanks!

tony.kay18:02:58

@macrobartfast the networking stack is in untangled.client.impl.network. The protocol is public...the namespace name is an unfortunate legacy oversight

macrobartfast18:02:25

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.

macrobartfast18:02:12

For instance, building out an app server to support a web app, a cli tool, and a couple native mobile clients...

macrobartfast18:02:52

it seems like the REST approach might be better down the road, but I think I'm not grokking something, no doubt.

tony.kay18:02:22

Here is a possible architecture:

Webapp   <---->  US  <--------|
                                      |
CLI     <-- REST --> XLATE -->|  Common Access API
          ^                          |
Mobile  <---+-- or------ ------->|

tony.kay18:02:33

hm....got the whitespace a little off

tony.kay18:02:32

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

tony.kay18:02:59

webapp in Om/Untangled uses the read/mutate Om parser technique on the server, and uses the same common API layer

macrobartfast18:02:00

that would be the best of both worlds, then

tony.kay18:02:17

Then get Om/Untangled going with react native....

macrobartfast18:02:28

lol, took the words out of my mouth

macrobartfast18:02:39

yeah, because I'd much rather go in that direction than native

tony.kay18:02:40

then get your CLI written to use cljs in node

macrobartfast18:02:53

*native mobile apps

macrobartfast18:02:06

and re cljs in node, exactly

macrobartfast18:02:29

aight, that's reassuring and helpful

tony.kay18:02:37

kool-aid squared

tony.kay18:02:45

or cubed, I guess

tobias19:02:41

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)

tony.kay19:02:11

Could be you have a name collision

tony.kay19:02:20

e.g. you named a table the same as some other top-level kw

tony.kay19:02:38

check the keywords you're using in ident functions

tony.kay19:02:44

more common source of this kind of confusion

tony.kay19:02:26

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

tobias19:02:18

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

tony.kay19:02:10

The ident of the screen must have a first item that matches the route's name.

tony.kay19:02:39

which must be obtainable from the data in the object itself, since the ident function on the router reads it

tony.kay19:02:04

In other words, the ident function on the router is the ident function for the screens it routes to

tony.kay19:02:12

those screens don't get an ident function of their own

tony.kay19:02:54

that's how the queries resolve: the "current ident" of the route also "routes" the query

tobias19:02:01

so they therefore should have an ident implemented?

tony.kay19:02:15

no, the ident on the defrouter is their ident

tony.kay19:02:03

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

tony.kay19:02:56

I believe the docs say this, but it is an unfortunate fact that all of those things have to align 😕

tobias19:02:34

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 🙂

qqq20:02:30

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 ?

claudiu20:02:06

@qqq Tony talks a bit about computed in this video https://youtu.be/fH0DX0Dubx8?t=22m34s

tony.kay21:02:58

@qqq you're number (2) does not make sense to me. Too many possibilities for what you mean.

tony.kay21:02:26

and (1 and 3) are always how the data gets passed through the tree, no matter what

tony.kay21:02:05

So perhaps you're asking "why queries?"

tony.kay21:02:52

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

qqq21:02:14

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

matthavener22:02:12

qqq: queries specify the data that becomes the props