Fork me on GitHub
#fulcro
<
2019-01-15
>
thosmos12:01:34

I'm having a problem with a simple test component:

(defsc StationList [this {:keys [stations]}]
  {:ident (fn [] [::core "stations"])
   :query [({:stations (fp/get-query StationSummary)} {:limit 10})]} ...)
and I'm getting an error: Uncaught #error {:message "Invalid expression ", :data {:type :error/invalid-expression}} which I figure is due to the exposed args parens, but when I attempt to quote it like so
:query `[({:stations ~(fp/get-query StationSummary)} {:limit 10})]
I get a specs error:
39 | (defsc StationList [this {:keys [stations]}]
-------^------------------------------------------------------------------------
Call to cljs.core/fn did not conform to spec.
-- Spec failed --------------------

  ([... clojure.core/sequence ...] ...)
        ^^^^^^^^^^^^^^^^^^^^^
or if I move the quote inside the brackets:
41 |    :query [`({:stations ~(fp/get-query StationSummary)} {:limit 10})]}
-----------------^--------------------------------------------------------------
defsc StationList: [stations] was destructured in props, but does not appear in the :query! at line 41 threshold/admin/ui/root.cljs

mitchelkuijpers15:01:15

Fulcro does not support arguments to queries locally (as far as I know). Only for queries to the server, so if you change your query to this:

[{:stations (fp/get-query StationSummary)}]

tony.kay16:01:53

You can use that query, and it won’t hurt, but you MUST use a lambda for the query when it is that advanced. The macro tries to error-check the destructuring against the query. Use :query (fn [] […])`.

thosmos17:01:36

ah, got it, thanks! that thought of using a lambda crossed my mind, but it was very late!

thosmos17:01:05

@U060GQK8U yes, this is a query to send to a graphql endpoint via pathom! (loving pathom)

sihingkk12:01:47

I don’t know if any of fulcro supporters is using it, but seems to be quite interesting: https://www.clojuriststogether.org/open-source/

thosmos18:01:27

My root component is getting the results of its query in a nil prop, as if its props are one level deep on a nil key: {:stations {}, nil {:stations [{:station/id "17592186178131", :station/StationName "Foote's Crossing", :station/LocalWatershed "Yuba Watershed" ,,,} Here's the root component:

(defsc StationList [this {:keys [stations]}]
  {:ident (fn [] [::core "sts"])
   :query [{:stations (fp/get-query StationSummary)}]}
  (do
    (debug "Render StationList Props" (fp/props this))
    ,,,))
the data appears to be in the DB in the right place:
{:station/id {"17592186178131" {:station/id             "17592186178131"
                                :station/StationName    "Foote's Crossing"
                                :station/LocalWatershed "Yuba Watershed"}
              "17592186178125" {:station/id             "17592186178125"
                                :station/StationName    "Below Fiddle Creek"
                                :station/LocalWatershed "Yuba Watershed"}}
 :threshold.admin.ui.root/core
             {"sts" {:stations [[:station/id "17592186178131"]
                                [:station/id "17592186178125"]]}}}
I'm mounting the root component like so:
(defn mount []
  (reset! app (fc/mount @app root/StationList "app")))
What am I missing?

tony.kay18:01:44

StationList cannot be a root AND have an ident

tony.kay18:01:48

idents and roots don’t match

tony.kay18:01:39

@thosmos remove the :ident and it should work

thosmos18:01:07

ah got it, thanks

tony.kay18:01:09

Your state for a root component must have :stations as a key…merging a component has no idea it is also a root

tony.kay18:01:47

(technically you could probably make it work by targeting that load at :stations, but it’s still a bad idea)

thosmos18:01:40

it works now and I changed the query and target key to ::stations. Why is it a bad idea?

thosmos18:01:35

are you saying it's best to load ident components into the root component, and then load remote data into those?

tony.kay19:01:43

Root is a special node in Fulcro

tony.kay19:01:04

If you want homogenous operation, put a root placeholder node between mount and your app

tony.kay19:01:28

The root component “overlays” on the root of the database…so giving it an ident is saying it has 2 places to live…but it is only one thing

tony.kay19:01:05

Hindsight says I should have written in the special root node so that it was all consistent…but I was based on Om Next to start 🙂

tony.kay19:01:48

well, perhaps that would not work well either…sometimes you just want to mix root-level props in to the top node

thosmos19:01:44

ah got it, I'm more familiar with om.next but it's been a while

thosmos20:01:44

getting the hang of it. funny how copy pasting examples only gets you so far until you really get it

thosmos20:01:22

you've done a ton of work on fulcro amazing work

tony.kay21:01:01

thanks…hope you like it as much as I do…the refinements of pathom, workspaces, and inspect by @wilkerlucio really rounded things out nicely. I’m sitting here working on a production app seeing parallel performance flame charts on server-side queries that are being conveniently resolved by pathom while building my application sub-sections in workspace cards and manually running graph queries with auto-complete in the Query tab of Inspect. It’s really feeling pretty nice at this point.

tony.kay21:01:43

The state machines stuff gave us an easy way to build things like a CRUD machine to re-use in controlling forms screens

thosmos21:01:09

wow, sounds good. looking forward to getting my current app dialed. I'm building an auto-generated CRUD graphql thing based on backend schemas, so the code-generated routing sounds good

thosmos21:01:08

kind of like react-admin, but better 😉

thosmos21:01:25

at least that's the dream

Daniel Hines21:01:01

So I was chatting with the guys behind DatSync at the Clojure Conj. DatSync has a very similar goal: full stack solution for UI. It chooses Datomic and Datascript as the server and clientside DB's respectively. One of their contentions is that if you only have pull (as opposed to full datalog queries), you sacrifice a lot of power, particularly in the area of "cross-cutting UI concerns". My answer to this was to create custom pathom resolvers, but this, admittedly, isn't quite as powerful/expressive as querying. You guys have put way more thought into this than I have - what are the tradeoffs to sacrificing full datalog queries?

tony.kay22:01:38

So, DatSync looks like a dead project to me…in alpha with no commits since 2017

tony.kay22:01:44

I’m not sure what you’re asking…are you implying that pathom resolvers are purely pull??? Any attribute/sub-graph can be computed from any kind of qury.

wilkerlucio22:01:38

@d4hines I think datalog is powerful, but for browser rendering it gets to be too slow, om.next start having this option open, but I never saw anybody getting too far with it, in practice EQL can express pretty much anything you need, we also reduce complexity on the api user, datalog is powerful but you have to know manually how data relate to each other, connecting a long chain (5 or more joins) gets very tedious and verbose, IMO using EQL with Pathom gets the best balance of power and control over what you want to expose

tony.kay22:01:43

Ah…so you think he means “having datalog in the UI?” I missed that. Yeah, the overhead of datalog in the UI seems rather extreme for the common case, and derived attributes seem to serve us quite well. For client-based datalog: Not only do you have to keep a full database in sync (with all of the complexity of that) you have to make a bunch of higher-order components to tie them to some kind of subscription mechanism. Gets messy pretty fast I think.

tony.kay22:01:58

the big win for graph query systems is that they can pull just what they need for the UI in question….once you add datalog now you have to pull “everything” to the client, or it just isn’t isomorphic and is more confusing and complicated that it is worth IMO

Daniel Hines22:01:27

In regards to the performance/pull everying issue of datalog, Niko Gobel is working on that with his 3df project. His talk at the conj was really cool https://github.com/comnik/clj-3df

Daniel Hines22:01:27

In theory, he’s streaming the changes to datalog queries just to the clients that have subscribed to them. But to your point, he’s been working at this for a long time, and it’s extremely difficult math stuff involved.

tony.kay22:01:05

Cool…and those kinds of things definitely have use-cases…I myself would find something quite valuable that could keep it all working in “offline mode”…

tony.kay22:01:17

but it is a nightmare of additional complexity when you don’t actually “need” it.

tony.kay22:01:02

and I think there are much simpler solutions that suffice in the common cases…so I would not consider such a technology for the general case.

tony.kay22:01:20

you’re already doing distributed computing with a webapp…it’s sort of like the ORM database thingy…yeah, the features look nice, but then you actually use them in big apps and the drawbacks eat you alive.

tony.kay22:01:41

how do you debug it when it goes wrong?

tony.kay22:01:22

clear map-based database with simple graph queries: Easy to understand, easy to write, easy to morph, fast, and straightforward to debug.

tony.kay22:01:20

UISM in incubator just got some additional helper functions from @currentoor in version 0.0.27…try it at a clojars near you 😉

Daniel Hines22:01:10

Thanks for your input @tony.kay, @wilkerlucio. As always, it’s highly valued!

exit223:01:42

Whats the most popular/used form lib for Fulcro applications?

tony.kay23:01:18

couldn’t say….I use the built-in form-state support…don’t have UI generators