Fork me on GitHub
#fulcro
<
2017-12-02
>
tony.kay00:12:48

Fulcro 2.0.0-alpha4-SNAPSHOT is on clojars. This has all of the changes proposed and tested on defsc

tony.kay00:12:05

M05-More-Concise-UI documentation heavily updated

tony.kay00:12:10

I’m going to port a bunch of stuff over to it and triple check it is all good.

tony.kay00:12:52

seems to be good. very much an improvement I think. Fully general and usable now

tony.kay00:12:05

@mitchelkuijpers css support will be there in a few mins on clojars

tony.kay00:12:36

I left notes where the validation can go in the source…it was not simple 🙂

tony.kay00:12:51

Fulcro 2.0.0-alpha6 is on clojars, as is Fulcro Spec 2.0.0-alpha5

tony.kay00:12:20

I still have a lot of documentation I’d like to update, and a few more renames to do…but we’re getting close to an RC1

tony.kay01:12:03

PREVIEW release of 2.x Developer’s Guide: https://fulcrologic.github.io/fulcro/guide-2.html NOTE: This was built after I did the rename of client (which is on 2.0.0-alpha7-SNAPSHOT on clojars and 2.0.0-alpha6-SNAPSHOT of spec)

mss03:12:34

hey all, newish to om and fulcro. watched the videos and worked through the devguide. still trying to wrap my head around the data model. I’m struggling with the following: a few components in different branches of the ui graph might want to read the same data, but that piece of data isn’t necessarily easy to represent as a full-on component with an ident/query/render method. to get concrete, here’s some code:

(defui FirstComponent
  static fc/InitialAppState
  (initial-state [this params]
    {:shared-prop 1})
  static om/Ident
  (ident [this props]
    [:first-component :singleton])
  static om/IQuery
  (query [this]
    [:shared-prop]))

(defui SecondComponent
  static fc/InitialAppState
  (initial-state [this params]
    {:shared-prop 1})
  static om/Ident
  (ident [this props]
    [:second-component :singleton])
  static om/IQuery
  (query [this]
    [:shared-prop]))

(defui Root
  static fc/InitialAppState
  (initial-state [this params]
    {:root-prop 42
     :first-component-data (fc/get-initial-state FirstComponent {})
     :second-component-data (fc/get-initial-state SecondComponent {})})
  static om/IQuery
  (query [this]
    [{:first-component-data (om/get-query FirstComponent)}
     {:second-component-data (om/get-query SecondComponent)}]))
the app db spit out by that is the following:
{:root-prop 42,
 :first-component-data [:first-component :singleton],
 :second-component-data [:second-component :singleton],
 :ui/locale :en,
 :first-component {:singleton {:shared-prop 1}},
 :second-component {:singleton {:shared-prop 1}}}
unfortunately, that shared-prop is duplicated across the first-component and second-component. to get around that, do I have to make a standalone component for shared-prop with its own ident and query? if so, that feels a little weird. it’s almost as if the parent is “stealing” data from the child component, and the child component only really exists to satisfy a data dependency of the parent component. that feels particularly icky wrt something like a user-authenticated? piece of data. quite a few components need to know that to make a rendering decision, but making a user authentication data-only component with its own ident and query just so parent components aren’t duplicating data within the state tree don’t quite feel right. at the same time, keeping that piece of state separate means setting/updating it in far too many places anytime you want to do a mutation. also seemingly a nightmare. obviously, out of the two of those, making a standalone, data-only component makes the most sense. just wondering if there’s something I’m missing wrt specifying certain data that should exist in a normalized format without all the machinery of a component. I’d appreciate any opinions that people care to offer. please let me know if I’m thinking about this wrong. thanks in advance for the help!

tony.kay05:12:25

Hey @mss. welcome. So, share data has a special query notation so you can save it at the root node. [ [:root-key '_] ] is a query for something in the root node

tony.kay05:12:35

It’s a “unique ident”

tony.kay05:12:07

so [ [:first-component '_] ] on your database would return {:singleton {shared-prop 1}

tony.kay05:12:27

Idents are really meant for things that have a clear identity…like a persistent entity. The “singleton” approach is if you have a specific UI component that you’d like to link up in the graph more naturally…so inventing an id that ends up making a single entry in a table is useful when you want to link something into the graph.

tony.kay05:12:42

The entire graph database is designed for solving the data-sharing need. I noticed you didn’t actually use any links from within components in your sample graph…so you really are just linking back to root.

tony.kay05:12:42

I’m glad to help clarify things further if that isn’t answering your question.

tony.kay05:12:11

perhaps an example will help:

{:shared-prop 1  ; in the database, at root
}
(defui
  static om/IQuery 
  (query [this] [ [:shared-prop '_] ])  ; query of root node
  ...
  Object
  (render [this]
    (let [{:keys [shared-prop]} (om/props this)] ...)))

tony.kay05:12:47

I believe I use this in the websockets demo app, and the template for the current logged-in user.

thheller14:12:37

I’m looking at fulcro as my next potential UI library. should I skip the v1 version and directly start with v2 or how far along is that?

thheller14:12:42

it might be total overkill for what I need but I like it so far

thheller14:12:00

don’t like that it adds 100kb gzip by just requiring and not even using anything though

thheller14:12:27

you may want to try excluding cljs.pprint and cljs.analyzer from the build in some way

tony.kay14:12:35

Hi @thheller and welcome! I’m working on an RC of v2. Should be the next few days. It won’t hurt to start with v1. v2 porting is relatively painless.

tony.kay14:12:22

and yes, I’d love to optimize the build a bit. There are little things like that that are needed for sure 🙂

tony.kay14:12:10

I think in advanced opt doesn’t that get cleaned up? Not sure what you mean in that particular case. The dev user file includes some things that are useful, but that ins’t even in the prod build of the cljs.

thheller14:12:43

I just required fulcro.client.core nothing else

thheller14:12:03

from 2.0.0-alpha6

tony.kay14:12:18

ah….yeah, I have not gotten to cleaning yet.

thheller14:12:27

advanced doesn’t like cljs.pprint or cljs.analyzer

tony.kay14:12:36

Good to know

tony.kay15:12:44

Om Next pulls in compiler internals and hacks them unfortunately. 2.0 inherits that code for now, but I think I know how to fix it and get rid of that requirement. I’ll double-check on pprint.

thheller15:12:26

yeah when decide to use this I’ll take a look at this and try to optimize this

tony.kay15:12:36

confirmed…I’ll get rid of those. The source had an original team of 10…some of them were a little free with the requires

tony.kay15:12:14

hm…not sure it is that easy 😕 Logging uses it. Is pr-str as bad? I don’t remember if that is just the impl of pprint

tony.kay15:12:19

That’s very helpful. Thanks!

thheller15:12:22

pr-str is fine

tony.kay15:12:31

ok, that’s good enough

thheller15:12:10

I don’t expect a alpha release to be optimized yet so no worries

tony.kay15:12:38

still helpful…that was a long way off in my mind, but it’s important

thheller15:12:19

cljs.analyzer is probably something that gets included for self-host support but wouldn’t be required otherwise

thheller15:12:35

om.next has the same issue

tony.kay15:12:53

I have not looked…people also use it for macro env detection, no? Oh, but that would be in a clj file…

tony.kay15:12:37

Yeah, at the moment I’m not too worried about self-hosting env.

thheller15:12:01

I expect that its only used by a macro yes. it is easy to include more than you should when trying to make self-host work.

tony.kay15:12:38

so, I’m not familair enough with the compiler…these are the only lines:

rname            (if env
                              (:name (ana/resolve-var (dissoc env :locals) name))
                              name)

thheller15:12:39

def defui*? thats macro right?

thheller15:12:56

or rather called from a macro.

tony.kay15:12:00

it is a function for running the internals of a macro, yes

thheller15:12:18

if you don’t care about self-host then it should be in #?(:clj ...)

thheller15:12:27

if you care things get very very icky 😛

tony.kay15:12:41

I don’t care at the moment, and it is the only dep on analyzer

tony.kay15:12:39

I’m in the midst of testing some refactoring…I’ll do that and then see if it flies ok. Thanks for the tip

thheller15:12:08

looks like that file is basically 95% macro code, might be less painful to just use a .clj file

tony.kay15:12:25

primitives?

tony.kay15:12:35

not at all…lots of “both”

tony.kay15:12:02

the defui macro is just huge

tony.kay15:12:47

I’m managing to put the compiler into infinite loops at the moment 😜

tony.kay15:12:08

The equivalent of (def a a) isn’t well-liked

thheller15:12:38

yeah closure does not like that

tony.kay15:12:05

I’m moving some things around, and I don’t want the old names to break…but forgot to namespace things (on at least one).

thheller15:12:44

what happens if two components have the same ident? is that bad?

tony.kay15:12:08

nope, totally expected. PersonForm PersonDetail PersonSummaryLine

tony.kay15:12:23

prob all have [:person/by-id ###]

mss15:12:25

@tony.kay makes sense, thanks for the help!

tony.kay15:12:29

I had to push a spec update…forgot to include the server js for server tests 😕

tony.kay15:12:01

fulcro-spec 2.0.0-alpha6-SNAPSHOT was updated

tony.kay16:12:25

Fulcro 2.0.0-alpha7-SNAPSHOT is on clojars. Renamed a few things (but put defs in old places to point at new). One caveat, fulcro.client.core -> fulcro.client. README-2.0 updated to reflect that. @thheller I think I got the pprint out of that one, but not the analyzer…that’ll take a little bit more work.

roklenarcic18:12:01

what happens if two components have the same ident? -> the only thing to watch out for is that when multiple components with same ident declare different forms (e.g. one component is used in person name editing popup and the other is used to edit person's description). Then you can run into an issue where one of these components initializing forms prevents the other component from initializing a different form on the same ident (since forms init checks if form is initialized).

wilkerlucio19:12:56

it pulls but never uses

wilkerlucio19:12:59

sending a PR to remove

wilkerlucio20:12:51

@tony.kay also fulcro-spec is still using fulcro.client.core