Fork me on GitHub
#pathom
<
2022-11-15
>
sheluchin17:11:31

Can someone explain to me why this doesn't work (snippet in thread)? I have items and sub-items. My sub-items contain pointers (`:sub-item/parent`) to their parent, but it seems that Pathom isn't able to follow the relation, even though all the attributes are declared. Is this sort of operation not supported because the item -> sub-item -> item puts a cycle in the DAG?

šŸ‘ 1
caleb.macdonaldblack16:11:13

Interested in knowing more about this also.

caleb.macdonaldblack16:11:54

@UPWHQK562 Iā€™m having struggles with similar examples.

Ben Grabow22:11:25

{::pco/output [:sub-item/id
                 {:sub-item/parent [:item/id]}]}
This output spec claims that the resolver will return a 1-to-many relationship from 1 :sub-item/parent to many records that each have an :item/id, but that's not what the resolver returns. It returns data with a 1-to-1 relationship between :sub-item/parent and :item/id.

Ben Grabow22:11:54

You may want to model the parent ID as a top-level attr of the sub-item record:

(pco/defresolver sub-item
  [{:sub-item/keys [id]}]
  {::pco/output [:sub-item/id :item/id]}
  (let [sub-items {1 {:sub-item/id 1 :item/id 1}
                   2 {:sub-item/id 2 :item/id 2}}]
    (get sub-items id)))

Ben Grabow22:11:33

The other option is to model the :sub-item/parent attribute as a vector of parents rather than a singular parent record (note the [] around {:item/id 1} and {:item/id 2}:

(pco/defresolver sub-item
  [{:sub-item/keys [id]}]
  {::pco/output [:sub-item/id
                 {:sub-item/parent [:item/id]}]}
  (let [sub-items {1 {:sub-item/id 1 :sub-item/parent [{:item/id 1}]}
                   2 {:sub-item/id 2 :sub-item/parent [{:item/id 2}]}}]
    (get sub-items id)))

sheluchin23:11:57

@UANMXF34G my understanding is that one of the limitations of EQL is that it doesn't specify whether the join is to a single value or a collection, and that {:x [:y]} is to-one or to-many depending on what is found. From Fulcro's docs: >Joins are automatically to-one if the data found in the state is a singular, and to-many if the data found is a vector. Is this a Fulcroism that doesn't apply to Pathom?

Ben Grabow23:11:13

I don't know that much about Fulcro, so I'm not sure if this is just a Fulcro thing or a Pathom thing. It's surprising to me to hear that to-1 joins are possible with this syntax. However I see the EQL docs say the same thing! https://edn-query-language.org/eql/1.0.0/what-is-eql.html#_eql_for_selections Have you been able to traverse a to-1 join with Pathom before? I have never tried it, so it jumped out at me that you were trying it.

sheluchin23:11:43

Afk right now so can't look at my code for exact examples, but I believe I have. 90% certain. Thank you for the suggestion but I believe it's inconclusive for now. I'll try to put some tests around this theory when I get in front of a computer. I would be surprised if it were the case, but it would be nice if a long held erroneous understanding got corrected.

Ben Grabow23:11:02

I think I found the problem! Just a small typo:

(pco/defresolver item
 [{:item/keys [id]}]
 {::pco/output [[:item/id :item/foo]]}
 (get {1 {:item/id 1 :item/foo "a"}
       2 {:item/id 2 :item/foo "b"}}
      id))
should be
(pco/defresolver item
 [{:item/keys [id]}]
 {::pco/output [:item/id :item/foo]}
 (get {1 {:item/id 1 :item/foo "a"}
       2 {:item/id 2 :item/foo "b"}}
      id))
There were extra [] around the output spec.

Ben Grabow23:11:40

The query works as written now:

(p.eql/process
  (pci/register [all-items
                 item
                 sub-item
                 earliest-sub-item])
  [{:all-items [:item/id
                ;; works!
                :item/foo
                {:item/earliest-sub-item [:sub-item/id
                                          {:sub-item/parent
                                           [:item/id :item/foo]}]}]}])
=>
{:all-items [#:item{:id 1, :foo "a", :earliest-sub-item #:sub-item{:id 1, :parent #:item{:id 1, :foo "a"}}}
             #:item{:id 2, :foo "b", :earliest-sub-item #:sub-item{:id 2, :parent #:item{:id 2, :foo "b"}}}]}

Ben Grabow23:11:03

It was my own misunderstanding. Today I learned that we can express to-one queries in EQL!

sheluchin23:11:23

Hah, oh man... Well, thank you. I wish there was same way to catch typos like that. I was looking for a typo in a misspelled key. OK, so now to continue with the repro of my actual issue lol I'll start another thread for that :)

šŸ‘Œ 1
rschmukler23:11:03

Is there any way to get a non-batched value from a pathom batched resolver? Eg.

(defresolver foo-resolver
  [_]
  {:foo 5})

(defresolver users-resolver
  [_]
  {:users [{:user/id 1}]})

(defresolver batch-computed-foo-resolver
  [users]
  {::pco/input [:user/id :foo]
   ::pco/output [:user/foo-times-two]}
  (mapv (contantly (*2 (-> users first :foo))))
When I have something like the above I get an error saying that it can't find a path for :user/foo-times-two when I try and query for {:users [:user/id :user/foo-times-two]} - if I remove :foo from the input then it can find a path

wilkerlucio22:11:04

I think the issue is that your response has only the value, you need each item on the collection to be like {:user/foo-times-two 5}

wilkerlucio22:11:05

if its not, please provide a repro and we can check, mixing batch and non batch should be fine

rschmukler22:11:40

@U066U8JQJ Thanks for the reply! I posted a repro in the GitHub of the issue that I am facing. Please let me know you need any more information. I apologize the code example above was incorrect (but in my repro, and in prod, I am indeed returning the full maps, not just the value) Link to the issue: https://github.com/wilkerlucio/pathom3/issues/171

šŸ™ 1
wilkerlucio23:11:23

replied at the issue