This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-08-20
Channels
- # announcements (1)
- # bangalore-clj (27)
- # beginners (82)
- # boot (4)
- # chestnut (1)
- # cider (22)
- # cljs-dev (26)
- # cljsrn (4)
- # clojure (118)
- # clojure-dev (18)
- # clojure-italy (2)
- # clojure-losangeles (1)
- # clojure-nl (2)
- # clojure-russia (1)
- # clojure-spec (15)
- # clojure-uk (125)
- # clojurescript (61)
- # core-async (74)
- # cursive (2)
- # datomic (41)
- # duct (6)
- # editors (7)
- # emacs (3)
- # events (1)
- # figwheel-main (3)
- # fulcro (111)
- # hoplon (11)
- # jobs-discuss (97)
- # lein-figwheel (99)
- # off-topic (34)
- # onyx (4)
- # parinfer (9)
- # pedestal (4)
- # precept (2)
- # re-frame (5)
- # reagent (2)
- # reitit (4)
- # ring-swagger (11)
- # shadow-cljs (104)
- # spacemacs (4)
- # tools-deps (19)
- # vim (8)
- # yada (15)
@hjrnunes sorry for the late reply, I had fallen asleep. 😅 May I see your load code?
defsc SecurityRow [this {:keys [db/id ui/editing?
;ui/dropdown
] :as row}]
{:query [:db/id :security/name :security/sym {:security/currency [:currency/sym]}
:ui/editing?
{[:ui/dropdown '_] (prim/get-query bs/Dropdown)} ;reusable dropdown
fs/form-config-join]
:ident [:security/by-id :db/id]
:form-fields #{:security/name :security/sym}}
(sui/ui-table-row nil
(for [field securities-header-ks
:let [value (if (= :security/currency field) (get-in row [field :currency/sym])
(get row field))]]
(sui/ui-table-cell
{:key field}
(if editing?
(if (= :security/currency field)
(form-input this row field "String required") ; dropdown would go here
(form-input this row field "String required"))
(dom/span #js {:onDoubleClick (fn [evt] (prim/transact! this `[(gmut/edit-row {:id ~id :class ~this})]))}
value)
)))))
(def ui-security-row (prim/factory SecurityRow {:keyfn :db/id}))
(defsc SecuritiesTable [this {:keys [sec-table/title sec-table/securities]}]
{:query [:db/id :sec-table/title {:sec-table/securities (prim/get-query SecurityRow)}]
:ident [:sec-table/by-id :db/id]}
(dom/div
(dom/div title)
(sui/ui-table nil
(securities-header)
(sui/ui-table-body nil
(mapv ui-security-row securities)))))
(defsc SecuritiesRoot [this {:keys [securities/table]}]
{:query [{:securities/table (prim/get-query SecuritiesTable)}
{:ui/dropdown (prim/get-query bs/Dropdown)}
]
:initial-state (fn [p] {:securities/table (prim/get-initial-state SecuritiesTable {})
:ui/dropdown (bs/dropdown :security/currency "Currency" [(bs/dropdown-item :foo "foo")
(bs/dropdown-item :bar "bar")])
})}
(dom/div
(ui-securities-table table)))
(defcard-fulcro securities-card
"# Full App"
SecuritiesRoot
{}
{:inspect-data true
:fulcro {:started-callback (fn [app]
(df/load app :securities/table SecuritiesTable
{:post-mutation `gmut/init-rows)
(js/console.log :STARTED))}})
The data is being loaded in :started-callback
init-rows
just initialises :ui/editing?
I don't get why I'm seeing [:ui/dropdown _] [:fulcro.client.primitives/not-found nil]
in the data-tree
All your query joins have a get-query
except this one: {:security/currency [:currency/sym]}
. Is it supposed to be like that?
sorry, not the query, but the data-tree when matched to query. The query actually seems fine
`(bs/dropdown :security/currency "Currency" [(bs/dropdown-item :foo "foo") (bs/dropdown-item :bar "bar")])` <--- why can't that be a call to get-initial-state
It is no problem at all to have components that don't render - with the rendering done elsewhere, often in the parent.
That way you get a table in the state, with a record. All singletons probably need to be in state from the outset.
ok, this is what my components look like, now:
(defsc CurrencyCell [this _]
{:query [:currency/sym]
:ident [:currency/by-sym :currency/sym]})
(defsc SecurityRow [this {:keys [db/id ui/editing?
;ui/dropdown
] :as row}]
{:query [:db/id :security/name :security/sym {:security/currency (prim/get-query CurrencyCell)}
:ui/editing?
{[:ui/dropdown '_] (prim/get-query bs/Dropdown)} ;reusable dropdown
fs/form-config-join]
:ident [:security/by-id :db/id]
:form-fields #{:security/name :security/sym}}
...)
(defsc SecuritiesRoot [this {:keys [securities/table]}]
{:query [{:securities/table (prim/get-query SecuritiesTable)}
{:ui/dropdown (prim/get-query bs/Dropdown)}
]
:initial-state (fn [p] {:securities/table (prim/get-initial-state SecuritiesTable {})
:ui/dropdown (prim/get-initial-state bs/Dropdown {:id :security/currency
:label "Currency"
:items [(prim/get-initial-state bs/DropdownItem {:id :foo :label "foo"})
(prim/get-initial-state bs/DropdownItem {:id :foo :label "bar"})]})})}
(dom/div
(ui-securities-table table)))
Yep:
{:ui/dropdown nil
:securities/table [:sec-table/by-id 1]
:security/by-id {1 {:db/id 1
:security/name "Facebook"
:security/sym "FB"
:security/currency [:currency/by-sym "usd"]
[:ui/dropdown '_] [:fulcro.client.primitives/not-found nil] ; <---------------------
:ui/editing? false}
2 {:db/id 2
:security/name "Apple"
:security/sym "AAPL"
:security/currency [:currency/by-sym "usd"]
[:ui/dropdown '_] [:fulcro.client.primitives/not-found nil] ; <---------------------
:ui/editing? false}
3 {:db/id 3
:security/name "BP"
:security/sym "BP.L"
:security/currency [:currency/by-sym "gbx"]
[:ui/dropdown '_] [:fulcro.client.primitives/not-found nil] ; <---------------------
:ui/editing? false}}
:ui/locale :en
:fulcro.inspect.core/app-uuid #uuid "bc2f57b4-de02-44b7-87ff-c4f18f7ecd9a"
:fulcro/loads-in-progress #{}
:sec-table/by-id {1 {:db/id 1
:sec-table/title "Securities"
:sec-table/securities
[[:security/by-id 1]
[:security/by-id 2]
[:security/by-id 3]]}}
:fulcro/ready-to-load ()
:ui/loading-data false :currency/by-sym {"usd" {:currency/sym "usd"}
"gbx" {:currency/sym "gbx"}}}
well, I did already. I get the dropdown to initialise fine in there, and normalised, and even rendered, to a point
@currentoor oh right..crap. Yeah, that was an oversight. I thought that change would be transparent. Your change is the exact opposite of what I was trying to do.
@hjrnunes So, the :ui
prefix keywords do not key elided from server queries if you use them as link queries…that is a but…link queries should not appear in loads at all, really.
Also, it makes no sense to use a link query with a ui prefix….I really don’t think it a good idea to use link queries very much at all. A dropdown is something that is a proper child of something, and should just be coded that way. Create an edge in yoru data graph instead of trying to access the root node
@tony.kay right, the reason I switched to :ui was precisely to avid sending to the server
@hjrnunes it might help if you modify your load call to make use of the :without
key.
http://book.fulcrologic.com/#_pruning_the_query
@levitanong that's the state with the dropdown in
So, what you want is to initialize the dropdown into the graph with an edge…I take it you’re adding this security thing with a load, right?
@tony.kay I'm trying to reproduce this example: http://book.fulcrologic.com/#_selecting_an_entity_for_edit
so, each row should probably have it’s own state, right? So the dropdowns aren’t shared
ok, so here’s what you do:
1. Change the query to include a join on the dropdown with a more normal key, like {:ui/meaning-of-dropdown (get-query bs/DropDown)}
2. Issue your load for the row(s), and include a post-mutation:
(load ... {:post-mutation `populate-dropdowns})
3. In the post-mutation, go through and create state for the dropdowns and link them into the new rows.OR, use a controlled dropdown that uses component-local state that is sent from the parent
in the OR case then, I'd, say, load the currencies elsewhere and pass them in as props to each row?
You can’t “share” the dropdown, because then they would share their state (what they have selected)
sure…and you could use shared
for things like that which are just global lists of data
Ok, the immediate issue, here, so I understand, is that the link query isn't being actually ellided, right?
So if I'd add it to :without
on the load query, that will get rid of those missings?
The funny thing is I had added it to :without
but whilst it being :ui/dropdow
I changed it to :root/dropdown
and it worked
the :ui
prefix is special, so it could be that it was removing it properly for the serer, but not from mark-missing
; plain missing prop
(and (keyword? element) (nil? (get result element)))
(assoc result element ::not-found)
The intention of that feature was to allow local props on components that were known to not come from the server
they are intended to be implementation details that don’t leak…and links are definitely leaks
you’re basically coding your app so you have to think globally about your database instead of locally
yep, i realised that, but I'm just dipping my feet, and wanted a dropdown working, so I went for that specific example
sure…I should really remove the need for links from my examples. The two I can think of that are relatively “valid” are example that link to the routers or load marker tables…because sometimes you just want to know “where an arbitrary route is pointing” or “what some random load marker is doing”….but shared
is probably better for those cases. It is cheap enough to do a root render to update those.
@currentoor I’m not sure it should be doing that….can you help me understand where it is making you require where you didn’t before?
oops @currentoor I found it
@currentoor Please try RC9-SNAPSHOT
@tony.kay will do, thanks
also what i proposed, that would only add bloat to the clojure version right? not the cljs builds
at least that was my understanding
it works
hm…it didn’t look like it would work to me. The defsc was still referring to a function in css ns
which infects everything. I just refactored it all to split that out, since that didn’t need garden directly
It seems to work. I just updated the template to use it, and the new sytle element works with SSR now, and everything compiled ok…
is there a shorcut fn to get an entity by ident? for when traversing the state in a mutation
@hjrnunes the ident
is literally the path on the app state for that entity, so a get-in
should be enough