Fork me on GitHub
#untangled
<
2016-10-04
>
cjmurphy01:10:59

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.

fatihict12:10:39

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?

ethangracer12:10:36

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

ethangracer12:10:02

Any questions about untangled so far?

fatihict13:10:50

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

ethangracer13:10:58

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

fatihict13:10:15

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 😄

gardnervickers13:10:04

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

ethangracer13:10:04

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.

ethangracer13:10:40

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

gardnervickers13:10:08

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?

ethangracer13:10:27

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

ethangracer13:10:45

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

gardnervickers13:10:36

Hmm that seems a lot less involved than our approach

w1ng13:10:36

is a post-mutation changing the react-key?

ethangracer13:10:39

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

ethangracer13:10:02

@w1ng not unless you explicitly ask it to

ethangracer13:10:57

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

ethangracer13:10:15

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

ethangracer13:10:54

@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

ethangracer13:10:05

or make it easier to find at the very least

therabidbanana16:10:29

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.

ethangracer16:10:55

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.kay16:10:45

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

tony.kay16:10:01

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

tony.kay16:10:20

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

tony.kay16:10:37

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.

ethangracer19:10:07

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

gardnervickers19:10:56

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.

ethangracer19:10:23

ahhh interesting

ethangracer19:10:12

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

gardnervickers19:10:42

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!

tony.kay19:10:01

@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.kay19:10:13

then query the versions explicitly

tony.kay19:10:23

Idents normalize everything to prevent duplications

tony.kay19:10:17

make the caching story a bit more directly apparent as well

gardnervickers19:10:35

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.kay19:10:54

yeah, that too

tony.kay19:10:14

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

tony.kay19:10:22

and easier to write/maintain than a parser

gardnervickers19:10:38

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

gardnervickers19:10:51

Are there plans to support http caching?

tony.kay19:10:58

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

tony.kay19:10:18

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

gardnervickers19:10:51

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

tony.kay20:10:06

we're trying to be really thin

tony.kay20:10:43

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.kay20:10:02

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

tony.kay20:10:19

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

ethangracer20:10:45

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

tony.kay20:10:46

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

jasonjckn21:10:16

tony are you pancia? I forget

jasonjckn21:10:19

or is he on your team

jasonjckn21:10:46

oh it's adambros

tony.kay22:10:23

@jasonjckn Anthony is a separate person 🙂

jasonjckn22:10:55

Is he on your team or independent?

jasonjckn22:10:57

just curious

tony.kay22:10:58

on our team

jasonjckn22:10:08

i'm just eyeing his PR 😄

tony.kay22:10:23

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

adambros22:10:29

its actually not finished, hes talking about the defui one

jasonjckn22:10:33

the devtools one

tony.kay22:10:42

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

tony.kay22:10:03

we had lunch yesterday to discuss ideas

jasonjckn22:10:04

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

tony.kay22:10:30

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

jasonjckn22:10:03

remember to test Deref / factory function in advanced compilation

jasonjckn22:10:06

I had difficulty with it

jasonjckn22:10:16

but that was 2 months ago

jasonjckn22:10:20

haven't tested advanced mode since

adambros22:10:43

leave a note on the PR or ill forget

jasonjckn22:10:01

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

gardnervickers23:10:16

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

wilkerlucio23:10:11

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

tony.kay23:10:09

@jasonjckn yes, norm and merge work with ident joins

tony.kay23:10:38

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.kay23:10:14

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

gardnervickers23:10:44

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