untangled

NEW CHANNEL: #fulcro
cjmurphy 2016-10-04T01:17:59.001711Z

One thing that occured to me when preparing a Meetup talk some time back was to differentiate between different kinds of keywords. The keys that are often named by-id are ident keywords and are different to query keywords. I don't think it helped my Meetup talk audience at all 🙁, but helped me.

fatihict 2016-10-04T12:36:39.001719Z

Hi folks, I am currently reading the interactive tutorial for untangled. I just finished reading "untangled_tutorial.A_Introduction" and when I click on the link "Let's start with the UI" at the bottom it does take me to the correct page, but I am not starting on top of the page, but somewhere in the middle. The same is true for the links "UI exercises" or "next chapter" at the bottom of page "untangled_tutorial.B_UI". Should I create an issue on GitHub for this? Or is this already known?

2016-10-04T12:58:36.001720Z

@fatihict Thanks for reporting, it is already known. It looks like something funny that happens with devcards but we haven’t spent time trying to figure it out because it’s close enough 🙂. We might take a look this week, we’re doing a team sprint on improving the documentation.

2016-10-04T12:59:02.001721Z

Any questions about untangled so far?

fatihict 2016-10-04T13:08:50.001722Z

@ethangracer Cool 🙂. I am going to read the tutorial first before asking silly questions to you guys. Also, I am a graduate intern sitting next to @mitchelkuijpers and it's really helpful that someone next to you is explaining this stuff 🙂. If you guys need a beginner to Clojure/ClojureScript to read documentation to verify if it is understandable, I am willing to do it 😄

2016-10-04T13:10:58.001724Z

Oh awesome! Mitchel mentioned yesterday that you might be helping us out. We would absolutely appreciate your feedback on any and all of the tutorial documentation / videos / etc. We want to make the Untangled introduction as clear as possible

fatihict 2016-10-04T13:16:15.001725Z

Nice, so far I've watched quite a few of David Nolen's and Rich Hickey's talks and one of Tony Kay (I really liked that one by the way). If you guys have any material I will gladly have a look and give my feedback on them 😄

gardnervickers 2016-10-04T13:45:04.001726Z

@ethangracer I’ll talk to the rest of the team, we’d love to write a testimonial. One thing I would be interested in hearing more about in the docs is how the Untangled team manages different views after a data load. For example, we’ve found a common case to be that one component might want all the items in a table while another just want’s a subset. It took us a bit to realize the benefits of making ident’s for the lists themselves, like :person-list/by-id, where the ident is :all for the list of all items, and maintaining that list in any data loads as post-mutations.

2016-10-04T13:51:04.001727Z

thanks @gardnervickers! that’s an interesting thought for a cookbook recipe, managing lists of items. Your approach is one that we haven’t taken — we do something similar where we query for [{:items [:id :name]}], where the sub-query is on a component that normalizes to :item/by-id. So once the data has loaded it looks like this:

{:items [[:item/by-id 1] [:item/by-id 2] [:item/by-id 3]]
 :item/by-id {1 {:id 1 :name “foo” }
               2 {:id 2 :name “bar”}
               3 {:id 3 :name “baz"}}
So that way we have the items by id automatically put into the :items list at the top level of the app state, which we can query for from any component with [:items _]. No need for the post mutation.

2016-10-04T13:52:40.001733Z

Your approach leaves a “cleaner” top level of the app state though

gardnervickers 2016-10-04T13:53:08.001734Z

Ah ok we were thinking of doing that too, when you need a subset of the full list of items, do you filter after the component get’s the result of querying :items or build sub-list through a mutation?

2016-10-04T13:53:27.001735Z

@fatihict awesome, I’ll send some stuff your way toward the end of the week

fatihict 2016-10-04T13:53:44.001736Z

👍

2016-10-04T13:53:45.001737Z

@gardnervickers yeah we just use filter, it’s quick

gardnervickers 2016-10-04T13:54:36.001738Z

Hmm that seems a lot less involved than our approach

2016-10-04T13:54:36.001739Z

is a post-mutation changing the react-key?

2016-10-04T13:54:39.001740Z

sorting into different lists would obviously be more time efficient for large data sets, we haven’t had to deal with that though

2016-10-04T13:55:02.001741Z

@w1ng not unless you explicitly ask it to

2016-10-04T13:55:57.001742Z

and it wouldn’t really be the best place to do so… you can add :untangled/force-root-render or something similar as a read to any query and it will force a root render

2016-10-04T13:56:15.001743Z

I’d have to look at the data fetch / mutation doc strings to remember exactly when it applies

2016-10-04T13:56:54.001744Z

@gardnervickers to your point though, it’s a fairly common requirement and we should absolutely have a cookbook recipe for that if we don't

2016-10-04T13:57:03.001745Z

@ethangracer thank you!

2016-10-04T13:57:05.001746Z

or make it easier to find at the very least

2016-10-04T13:57:19.001747Z

@w1ng yup!

2016-10-04T16:01:29.001750Z

Nice tip about :untangled/force-root-rerender - I think we've probably needed that and worked around it before. If I remember correctly, we read the "ui/current_route" param we have to trigger a rerender from root, since in our case the rest of the app is based on that.

2016-10-04T16:19:55.001751Z

yeah we were doing the same thing for awhile and decided it wasn’t the most declarative way to trigger a root rerender. it does work though

tony.kay 2016-10-04T16:22:45.001753Z

remember that you can trigger a root re-render by just doing a follow-on read of anything the Root queries

tony.kay 2016-10-04T16:23:01.001754Z

the react-key is about forcing React to re-evaluate the render even in the face of unchanged data

tony.kay 2016-10-04T16:23:20.001755Z

typically, you only need the latter during development, and it is rather heavy-handed otherwise

tony.kay 2016-10-04T16:24:37.001756Z

We do force root render in a couple of cases (which updates the react key, if memory serves), but those might change over time as things stabilize. I think we currently do some internal forcing around post-mutations to ensure that markers are updated, but iff post-mutations are used.

2016-10-04T19:35:07.001760Z

there’s a readme in there about managing lists, along with a more fleshed out example of what we were talking about earlier

gardnervickers 2016-10-04T19:36:50.001761Z

Nice

gardnervickers 2016-10-04T19:41:56.001762Z

What was unclear to me was specifically how to manage projections/views from different tables. The common case for us is that we have several components that all have a view over every element in a table, but some of our tables are way too big and we need to only show a subset. Analogous to you’re approach with querying lists of idents at the top of the db using links, we started making tables for our different list views like :person-list/by-id :all, :person-list/by-id :new-york :person-list/by-id :chicago etc… That way we can default to :person-list/by-id :all, and opt-in to building/maintaining sub-indices if things get too slow.

2016-10-04T19:42:23.001763Z

ahhh interesting

2016-10-04T19:43:12.001764Z

to my knowledge there isn't an accepted design pattern for that kind of problem yet, but it looks like what you’re proposing is a good one to me

gardnervickers 2016-10-04T19:43:42.001765Z

A component (subtree) will re-render when:

- It is the initiator of a transaction
- A transaction mentions one of the things it queried in a follow-on read
- Has the same ident as a component initiating a transaction
I actually had no idea about the third bullet point, but that plays in our favor with this approach too!

2016-10-04T19:45:23.001766Z

good point!

tony.kay 2016-10-04T19:54:01.001767Z

@ethangracer @gardnervickers That kind of is the intended design pattern. In stock Om Next you write different parser routines the try to generate (and somehow memoize for speed) various views of the same data. In Untangled, we just use app state and pre-memoize them.

tony.kay 2016-10-04T19:54:13.001768Z

then query the versions explicitly

tony.kay 2016-10-04T19:54:23.001769Z

Idents normalize everything to prevent duplications

tony.kay 2016-10-04T19:54:24.001770Z

done

tony.kay 2016-10-04T19:55:17.001771Z

make the caching story a bit more directly apparent as well

gardnervickers 2016-10-04T19:55:35.001773Z

Yup that’s becoming clear, it work’s well with things like the data-fetch/load-data where you can just pass :ident [:person-list/by-id :all

tony.kay 2016-10-04T19:55:54.001774Z

yeah, that too

tony.kay 2016-10-04T19:56:14.001775Z

Om has the elegant design, we just chose an implementation that seemed general purpose and logical

tony.kay 2016-10-04T19:56:22.001776Z

and easier to write/maintain than a parser

gardnervickers 2016-10-04T19:56:38.001777Z

Yup, I struggled with writing my own read client parser quite a bit

gardnervickers 2016-10-04T19:57:51.001778Z

Are there plans to support http caching?

tony.kay 2016-10-04T19:57:58.001779Z

yes

tony.kay 2016-10-04T19:58:58.001780Z

for that to be usable, you basically need access to multiple remotes...which we also need to add hooks for

tony.kay 2016-10-04T19:59:18.001781Z

once you have that hook, everything else is up to your server code response and the browser

gardnervickers 2016-10-04T19:59:51.001782Z

Ok great so it’ll be like vanilla Om.Next’s approach?

tony.kay 2016-10-04T20:02:00.001783Z

exactly

tony.kay 2016-10-04T20:02:06.001784Z

we're trying to be really thin

tony.kay 2016-10-04T20:02:43.001785Z

actually, I'd say we don't do anything differently than vanilla. We're just supplying reasonable implementations for the stuff that Om Next "leaves up to you".

tony.kay 2016-10-04T20:04:02.001786Z

parser, network plumbing, merging data, database format, i18n, support viewer of history, etc.

tony.kay 2016-10-04T20:04:19.001787Z

Om Next really does require you write a lot of code just to get started.

2016-10-04T20:04:45.001788Z

^^ that’s a great blurb for the main page of the site

tony.kay 2016-10-04T20:04:46.001789Z

We're realizing that this message needs to be more central in our description of Untangled

tony.kay 2016-10-04T20:04:47.001790Z

yeah

2016-10-04T21:59:16.001794Z

tony are you pancia? I forget

2016-10-04T21:59:19.001795Z

or is he on your team

2016-10-04T21:59:46.001797Z

oh it's adambros

tony.kay 2016-10-04T22:07:13.001798Z

right

tony.kay 2016-10-04T22:07:23.001799Z

@jasonjckn Anthony is a separate person 🙂

2016-10-04T22:07:55.001800Z

Is he on your team or independent?

2016-10-04T22:07:57.001801Z

just curious

tony.kay 2016-10-04T22:07:58.001802Z

on our team

2016-10-04T22:08:00.001803Z

kk

2016-10-04T22:08:08.001804Z

i'm just eyeing his PR 😄

adambros 2016-10-04T22:08:09.001805Z

its me!

tony.kay 2016-10-04T22:08:23.001806Z

yeah, we're making a lot of PRs for doc improvements

adambros 2016-10-04T22:08:29.001807Z

its actually not finished, hes talking about the defui one

2016-10-04T22:08:33.001808Z

the devtools one

tony.kay 2016-10-04T22:08:42.001809Z

there are like 5 of us working on that...oh yeah, that...more ideas coming there

tony.kay 2016-10-04T22:09:03.001811Z

we had lunch yesterday to discuss ideas

2016-10-04T22:09:04.001812Z

yah it looks like it's going to be an epic addition

tony.kay 2016-10-04T22:09:30.001813Z

we found a way, I hope, to make a complete extension point mechanism for defui...going to be really cool if it works 🙂

2016-10-04T22:17:03.001814Z

remember to test Deref / factory function in advanced compilation

2016-10-04T22:17:06.001815Z

I had difficulty with it

2016-10-04T22:17:16.001816Z

but that was 2 months ago

2016-10-04T22:17:20.001817Z

haven't tested advanced mode since

adambros 2016-10-04T22:17:43.001818Z

leave a note on the PR or ill forget

2016-10-04T22:17:51.001820Z

kk

2016-10-04T22:28:01.001821Z

data normalization works for ident joins right, anyone test this? {[:ident-kind :ident-id] [:my :query :keys]} I want to start making heavy usage of this

gardnervickers 2016-10-04T23:18:16.001824Z

@tony.kay Great description, when I was first checking out Untangled I was under the assumption it forced you into using datomic and heavily influenced you’re design decisions. As we’ve been using it and going through the code base it’s clear it’s just a layer over the top.

wilkerlucio 2016-10-04T23:21:11.001825Z

@gardnervickers yep, I for example only use the untangle-client, my server implementation is totally apart, in node-js using sql 🙂

gardnervickers 2016-10-04T23:21:28.001826Z

Ah interesting

tony.kay 2016-10-04T23:22:09.001827Z

@jasonjckn yes, norm and merge work with ident joins

tony.kay 2016-10-04T23:22:38.001828Z

I did just find a bug 15 mins ago related to it, though...if "not found" on the server, the plumbing crashes on ident join merges (issue #39)

tony.kay 2016-10-04T23:25:14.001830Z

@gardnervickers Yeah, @ethangracer is working on the website as we speak and trying to clear up that misconception. I'll probably add something to the Om Tutorial of that sort about Untangled 😄

gardnervickers 2016-10-04T23:34:44.001831Z

Neat, thank’s for all you’re hard work, this has been a pleasure to work with.