untangled

NEW CHANNEL: #fulcro
tony.kay 2017-02-28T00:06:20.004682Z

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

tony.kay 2017-02-28T00:06:25.004683Z

Look for the following:

tony.kay 2017-02-28T00:06:28.004684Z

1. It missing

tony.kay 2017-02-28T00:07:01.004685Z

um

tony.kay 2017-02-28T00:07:09.004686Z

what was the other one ...

tony.kay 2017-02-28T00:08:08.004687Z

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

tony.kay 2017-02-28T00:08:29.004688Z

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

tony.kay 2017-02-28T00:09:06.004690Z

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

tony.kay 2017-02-28T00:09:47.004691Z

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

tony.kay 2017-02-28T00:10:04.004692Z

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

tony.kay 2017-02-28T00:10:14.004693Z

almost certainly is an issue like that

fragamus 2017-02-28T00:10:16.004694Z

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

tony.kay 2017-02-28T00:11:54.004695Z

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

tony.kay 2017-02-28T00:12:24.004696Z

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

tony.kay 2017-02-28T00:12:30.004697Z

which is not used for uberjar

fragamus 2017-02-28T00:12:32.004698Z

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

fragamus 2017-02-28T00:12:47.004699Z

oooohhhh nice idea

tony.kay 2017-02-28T00:13:02.004700Z

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

tony.kay 2017-02-28T00:13:37.004701Z

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

qqq 2017-02-28T01:24:35.004702Z

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

darrellesh 2017-02-28T03:01:27.004703Z

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

claudiu 2017-02-28T07:16:13.004704Z

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

qqq 2017-02-28T11:14:18.004705Z

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

qqq 2017-02-28T11:14:53.004706Z

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.kay 2017-02-28T16:46:32.004707Z

@qqq yep

tony.kay 2017-02-28T16:47:52.004708Z

@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.kay 2017-02-28T16:48:06.004709Z

it would be the same as Om Next

tony.kay 2017-02-28T16:48:30.004710Z

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.kay 2017-02-28T16:48:50.004711Z

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

tony.kay 2017-02-28T17:45:57.004712Z

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.

👍 1
macrobartfast 2017-02-28T18:40:14.004713Z

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?

macrobartfast 2017-02-28T18:40:39.004714Z

I'm used to pedestal style swagger dealios

tony.kay 2017-02-28T18:41:12.004715Z

@macrobartfast Two possible choices come to mind:

tony.kay 2017-02-28T18:41:52.004716Z

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.kay 2017-02-28T18:43:07.004718Z

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.kay 2017-02-28T18:44:27.004719Z

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

2017-02-28T18:44:43.004720Z

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.kay 2017-02-28T18:45:08.004721Z

That is my (2), I think

2017-02-28T18:45:30.004722Z

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

tony.kay 2017-02-28T18:45:37.004723Z

AH, I was

tony.kay 2017-02-28T18:45:54.004724Z

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

tony.kay 2017-02-28T18:46:12.004725Z

UC <-> US <-> REST

2017-02-28T18:46:27.004726Z

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.kay 2017-02-28T18:47:12.004727Z

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.kay 2017-02-28T18:47:34.004728Z

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

tony.kay 2017-02-28T18:47:48.004729Z

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

tony.kay 2017-02-28T18:48:38.004730Z

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

2017-02-28T18:49:05.004731Z

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.

tony.kay 2017-02-28T18:49:16.004733Z

ah

2017-02-28T18:49:34.004734Z

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

tony.kay 2017-02-28T18:49:39.004735Z

I see

macrobartfast 2017-02-28T18:50:16.004737Z

that was really helpful, thanks!

tony.kay 2017-02-28T18:50:58.004738Z

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

macrobartfast 2017-02-28T18:51:25.004741Z

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.

macrobartfast 2017-02-28T18:52:12.004742Z

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

macrobartfast 2017-02-28T18:52:52.004743Z

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

tony.kay 2017-02-28T18:55:22.004744Z

Here is a possible architecture:

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

tony.kay 2017-02-28T18:55:33.004745Z

hm....got the whitespace a little off

tony.kay 2017-02-28T18:56:32.004747Z

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.kay 2017-02-28T18:56:59.004748Z

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

macrobartfast 2017-02-28T18:57:00.004749Z

that would be the best of both worlds, then

tony.kay 2017-02-28T18:57:17.004750Z

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

tony.kay 2017-02-28T18:57:26.004751Z

😉

macrobartfast 2017-02-28T18:57:28.004752Z

lol, took the words out of my mouth

macrobartfast 2017-02-28T18:57:39.004753Z

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

tony.kay 2017-02-28T18:57:40.004754Z

then get your CLI written to use cljs in node

tony.kay 2017-02-28T18:57:47.004756Z

😄

macrobartfast 2017-02-28T18:57:53.004757Z

*native mobile apps

macrobartfast 2017-02-28T18:58:06.004758Z

and re cljs in node, exactly

macrobartfast 2017-02-28T18:58:29.004759Z

aight, that's reassuring and helpful

macrobartfast 2017-02-28T18:58:34.004760Z

😀

tony.kay 2017-02-28T18:58:37.004761Z

kool-aid squared

tony.kay 2017-02-28T18:58:45.004762Z

or cubed, I guess

macrobartfast 2017-02-28T18:58:51.004763Z

lol

2017-02-28T19:36:41.004764Z

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.kay 2017-02-28T19:37:11.004765Z

Could be you have a name collision

tony.kay 2017-02-28T19:37:20.004766Z

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

tony.kay 2017-02-28T19:37:38.004767Z

check the keywords you're using in ident functions

tony.kay 2017-02-28T19:37:44.004768Z

more common source of this kind of confusion

tony.kay 2017-02-28T19:38:26.004769Z

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

2017-02-28T19:45:18.004770Z

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.kay 2017-02-28T19:45:50.004771Z

Yes

tony.kay 2017-02-28T19:46:10.004772Z

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

tony.kay 2017-02-28T19:46:39.004773Z

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

tony.kay 2017-02-28T19:47:04.004774Z

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

tony.kay 2017-02-28T19:47:12.004775Z

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

tony.kay 2017-02-28T19:47:54.004776Z

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

2017-02-28T19:48:01.004777Z

so they therefore should have an ident implemented?

2017-02-28T19:48:08.004778Z

shouldn't

tony.kay 2017-02-28T19:48:15.004779Z

no, the ident on the defrouter is their ident

tony.kay 2017-02-28T19:49:03.004780Z

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.kay 2017-02-28T19:49:56.004781Z

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

2017-02-28T19:50:34.004782Z

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 🙂

qqq 2017-02-28T20:36:30.004785Z

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 ?

claudiu 2017-02-28T20:52:06.004786Z

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

tony.kay 2017-02-28T21:33:58.004788Z

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

tony.kay 2017-02-28T21:34:26.004789Z

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

tony.kay 2017-02-28T21:35:05.004791Z

So perhaps you're asking "why queries?"

tony.kay 2017-02-28T21:35:52.004792Z

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

qqq 2017-02-28T21:51:14.004793Z

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

matthavener 2017-02-28T22:10:12.004794Z

qqq: queries specify the data that becomes the props