Clojurians
# om

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

tony.kay 02:14:52

Due to a branding issue with Untangled, I’m having to fork the project under a new name: Fulcro. I’ve released versions of the 4 core libraries. See https://github.com/fulcrologic. It includes a script to help rename untangled projects. So, for those of you looking for some batteries to stick into Om Next, I’d recommend the new library (which is being maintained) over the old.

tony.kay 02:17:27

Questions should be directed at the #fulcro channel

roklenarcic 10:52:50

btw your bootstrap devcards are broken for me

claudiu 11:35:11

@roklenarcic Seems to be fulcro tutorial. Can write in the #fulcro channel. Pretty sure Tony will fix it asap :slightly_smiling_face:

claudiu 12:43:52

@roklenarcic Seems to be working on the repo. Probably needs a redeploy. You can just clone git@github.com:fulcrologic/fulcro.git and ./run-devguide.sh until that gets redeployed on the website.

levitanong 12:58:48

are om.next static fields really not meant to be accessed in clj?

claudiu 13:07:10

@levitanong what do you mean ? If referring to static/IQuery should work on server also as far as I know (om.next/get-query MyComponent)

levitanong 13:08:04

@claudiu Not at all. You can do static field some-name 42

levitanong 13:08:22

and then you can access it by (.-some-name MyComponent)

levitanong 13:09:17

I was trying to use it “server” side to generate styles from co-located component styles, but it kept complaining the field didn’t exist.

levitanong 13:09:44

I checked next.cljc and it seems they left out the fields from defui-clj

claudiu 13:11:26

ahh think I ran into this. In the om-next there seem to be a few conditionals like https://github.com/omcljs/om/blob/master/src/main/om/next.cljc#L774

levitanong 13:14:38

I wasn’t too satisfied with ladderlife’s implementation because they seemed to keep the styles in the cljs side

levitanong 13:14:56

but I haven’t seen fulcro yet. Will check! Thanks for the heads up, @claudiu

levitanong 13:15:50

Ah, it’s similar to something I made myself, it seems. XD

levitanong 13:16:56

but fulcro has a convenience method for composing styles upwards

claudiu 13:18:31

@levitanong ladderlife also seems to generate 1 big css. With falcro-css it's in clj & cljs. Gets dead code eliminated, and with code splitting you can bundle js & css.

levitanong 13:23:10

@claudiu You know, I hadn’t actually thought of the dead-code elimination part. I suppose in the CLJS side, since nothing was calling the static methods for getting the styles, then they’d be eliminated. Is that so?

claudiu 13:25:31

yep. They have to compose to the top. If you don't use it it will not get bundled in production. Also like the idea of loading in the html only the css needed for that page.

levitanong 13:52:25

And by loading only the CSS for that page, youre referring to the new code splitting stuff for cljs?

claudiu 14:03:22

@levitanong nope :slightly_smiling_face: I mean that if I'm on the about page I can load only the layout & about page css into the html (the other css is in the js but I don't add it to the dom). Then when you change the route, unmount the loaded css and insert the css for the other page.

claudiu 14:04:38

in chrome inspect the header and then change routes, and look at how the css is loaded on route change :slightly_smiling_face:

levitanong 14:28:14

@claudiu interesting

tony.kay 18:41:50

@roklenarcic Ah…I forgot to recompile the js file for the live guide with the new naming. Thanks!

tony.kay 19:40:47

should be working now

marvin 22:06:02

Hi, I am stuck with this issue: when my component is a root component the parser calls the read function before rendering. When my component is a child of another simple component, the read function does not get called by the parse and the component is rendered without any data. Is this an issue with my query expression? Is there away to trace the execution?

wilkerlucio 22:35:08

hello @marvin, you mean render after a transaction? or on first render?

marvin 22:41:01

Hi @wilkerlucio on first render the parser does not call my read function if my component is not a root component.

wilkerlucio 22:42:45

@marvin are you composing the queries on your root component? remember that with stock Om is your responsability to parse the query, so you will only receive reads directly for the root entries

samcf 22:46:09

the critical thing for me to grok the query business was to realize the render fn isn't considered while creating the UI query

samcf 22:47:03

so rendered children's queries aren't implicitly included in the final query

samcf 22:47:39

( at least to my knowledge )

wilkerlucio 22:48:53

@samcf yes, that's true, and that's what enables the query to be fully realized in a static way

marvin 22:51:50

@wilkerlucio so Om only call read for the root component? Do I then need to pass down the data to the child-component at rendering time?

wilkerlucio 22:52:52

@marvin yes, your root component is supposed to have the full query (composed by calling om/get-query on the children), and then on the render you pick that value from the props and pass down to the children

wilkerlucio 22:53:41

can you share with us how is your root component is written? I guess we can get less abstract and see what might be wrong

tony.kay 22:56:35

@marvin There is a path-opt option that allows Om to start at a component with an ident

tony.kay 22:57:02

but initial render will always come from root

marvin 23:09:06

@wilkerlucio my app data is a simple big map and my queries are simple keys. My app has one root component for menus and to implement routing using Compassus. The next level of children components display a mixture of text and clojure code in a text editor, these components uses a simple key to retrieve the code from the app-state. Your explanation helps to clarify the fact that the parser only invokes the read function for root component and it is the responsibility of the root component to propagate the data down to its children components. I did not know this fact and was assuming something else.

marvin 23:11:16

@tony.kay hi Tony, thanks for your input, I was not aware of this option.

wilkerlucio 23:12:31

@marvin in case you don't know, there is a helper function called om/db->tree that does most of the effort to translate from a DB form to a plain tree, but maybe it's not much helpful if you are not using idents

tony.kay 23:17:15

I’ve had some recent problems with path-opt…possibly only with unions. not sure. There is an open issue on it.

tony.kay 23:17:40

and idents: you should be using those :slightly_smiling_face:

marvin 23:20:04

@wilkerlucio I will explore om/db->tree. I have not thought of using idents since I don't have list of data to display. @tony.kay Do you meant I should make a practice to use idents across the board?

marvin 23:24:42

@wilkerlucio after a transaction, is it correct to assume that the parser will invoke the read function only for the affected components?

marvin 23:25:56

@samcf Thanks for your clarifications.

wilkerlucio 23:26:59

@marvin it will trigger the re-render of the current component (if it has an ident, hehe), otherwise you should add follow-up read keys for the keys affected by your transaction, eg: (om/transact! this '[(my/tx {}) :affected-key/to-be-read])

wilkerlucio 23:27:31

but I think this behavior also depends on the path-opt setting

wilkerlucio 23:27:57

@tony.kay can you clarify that one? I'm not sure if after a TX the root query is called when path-opt is off

tony.kay 23:36:31

@marvin Idents are what make mutations easy. It causes all component to appear in “tables”, which make get-in, update-in, and assoc-in able to work with them using the ident (two element vector). So, anything that changes over time should have an ident.

tony.kay 23:37:10

The query (wihtout path-opt) is always from root; however, it gets focused to the components that need refresh

tony.kay 23:37:29

focusing is this cool function that strips off all of the query branches that don’t lead to the component(s) of interest

tony.kay 23:37:41

so, your query is much lighter on a refresh

tony.kay 23:37:58

but it is still structured from root (unless path-opt)

tony.kay 23:38:32

with path-opt, it is basically hooked up with a join on the component’s ident [{[:table id] (om/get-query component)}] so that the query can start from there…but since the parser needs to be told how to handle that, it is not on by default.