Fork me on GitHub
#fulcro
<
2018-10-30
>
pvillegas1200:10:42

The loading mutation is run without waiting for the file-upload one to finish

pvillegas1200:10:01

I am seeing a successful OPTIONS request, basically file-upload OPTIONS fires, file-upload POST is pending, but the load is fired at that point

tony.kay00:10:33

what does your file upload mutation look like

pvillegas1200:10:48

ah, does it matter that the mutations have different remotes?

pvillegas1200:10:16

(defmutation upload-file [{:keys [ident value]}]
  (action [{:keys [state]}]
    (println "upload-file")
    (swap! state set-value* ident value))
  (file-upload [env] true))
(defmutation load-adapted-data [{:keys [file-id] :as params}]
  (action [{:keys [state] :as env}]
    (println params)
    (println env)
    (println "load-adapted-data")
    (println (get @state :file/by-id))
    (df/load-action env :adapted-data nil
      {:params {:file-id file-id}}))
  (remote [env] (df/remote-load env)))

pvillegas1200:10:42

(prim/ptransact! this '[(upload-file …) (load-adapter-data …)]

tony.kay00:10:02

hmmm…run this function and tell me what the output is:

(prim/pessimistic-transaction->transaction `[(upload-file {}) (load-adapted-data {})]
  {:valid-remotes #{:remote :file-upload}})

tony.kay00:10:09

sorry, you need that valid remotes for it to work right

pvillegas1200:10:31

in my ptransact! ?

tony.kay00:10:15

no, just log the output of that

tony.kay00:10:30

that’s the function ptransact! uses to transform your tx

tony.kay00:10:38

I want to see what it transforms it to

tony.kay00:10:55

the ... can just be empty maps…

tony.kay00:10:10

re-read that message, I edited it, or perhaps you saw the typo

pvillegas1200:10:10

[(contaico.api.mutations/upload-file {:ident [:file/by-id #fulcro/tempid["aa3bfdfb-f46b-462c-9fc0-159a4e81d839"]], :value {:db/id #fulcro/tempid["aa3bfdfb-f46b-462c-9fc0-159a4e81d839"], :file/type :file.type/main, :file/name 2018-05-alegra-invoices.csv, :file/size 561887, :file/uploaded? false, :file/js-file {}}}) 
(fulcro.client.data-fetch/deferred-transaction {:remote :file-upload, :tx [(contaico.api.mutations/load-adapted-data {:file-id #fulcro/tempid["aa3bfdfb-f46b-462c-9fc0-159a4e81d839"]})]})]
@tony.kay

tony.kay00:10:12

hm…that looks ok

tony.kay00:10:36

and it is using the correct remote for the deferred

tony.kay00:10:02

you didn’t specify parallel on the remote did you?

tony.kay00:10:47

like, you’re using the normal http remote from fulcro, just with middleware for the req/resp

pvillegas1200:10:12

I’m using this

(def api-request-middleware (-> (net/wrap-fulcro-request) wrap-auth-token))
(defn api-response-middleware [app]
  (-> (net/wrap-fulcro-response) (handle-token-expiration app)))

(defn api-remote [app endpoint]
  (net/fulcro-http-remote
   {:url                 (str "" endpoint)
    :request-middleware  api-request-middleware
    :response-middleware (api-response-middleware app)}))

pvillegas1200:10:13

But it looks like it is not waiting on the file middlewares no?

pvillegas1201:10:47

wait, this might be fishy

(defn handle-token-expiration [handler app]
  (fn [{:keys [status-code status-text] :as req}]
    (if (and (= status-code 401)
             (= status-text "Unauthorized"))
      (prim/transact! (:reconciler @app) `[(token-expired)])
      (handler req))))

pvillegas1201:10:54

I’m transacting within a middleware

tony.kay01:10:19

no…it could be that ptransact requires the remotes to all be the same…let me refresh my memory

currentoor01:10:51

i don’t think so @tony.kay

tony.kay01:10:51

yeah, it uses the load queue to do the defer…so it has to be the same remote

tony.kay01:10:30

I think the new incubator stuff will work for your use-case

pvillegas1201:10:37

I’ll take a look

tony.kay01:10:25

@currentoor was just doing some of this…I’ll defer to his more recent knowledge 🙂

currentoor01:10:05

so i’ve got this mutation that uses the file-upload remote

(defmutation upload-file
  "Mutation: Start uploading a file. This mutation will always be something the
  app itself writes, because the UI will need to be updated. That said, adding
  the file to the client database is done via the helpers add-file*."
  [{::file-upload/keys [id size abort-id] :as file}]
  (action [{:keys [state]}]
    (swap! state (fn [s]
                   (-> s
                     (file-upload/add-file* file file-upload/MAX-FILE-SIZE)
                     (assoc-in [::camera-btn :singleton :file]
                       [::file-upload/by-id id])))))
  (file-upload [{:keys [ast]}]
    ;; don't even start networking if the file is too big.
    (when-not (>= size file-upload/MAX-FILE-SIZE)
      (-> ast
        (m/with-abort-id abort-id)
        (m/with-progressive-updates `(file-upload/update-progress ~file))))))

currentoor01:10:27

and i’ve got this other mutation that was built for the incubator’s pmutat!

currentoor01:10:46

(defmutation new-wash-&-unconfirmed-vehicle
  [{:keys [wash file-id]}]
  (action [{:keys [state]}]
    (log/info "Creating unconfirmed vehicle with file id" file-id "wash-id" (:wash/id wash))
    (swap! state add-wash* wash))
  (ok-action [{:keys [state ref] :as env}]
    (let [unconf-v (get-in @state (conj ref ::pm/mutation-response))
          ident    (prim/get-ident u.m.s.confirmation/UnconfirmedVehicle unconf-v)]
      (swap! state
        (fn [s]
          (-> s
            (prim/merge-component u.m.s.confirmation/UnconfirmedVehicle unconf-v)
            (assoc-in [:wash/id (:wash/id wash) :ui/unconfirmed-vehicle] ident))))))
  (error-action [{:keys [state reconciler] :as env}]
    (u.flash/show! reconciler {:error (util/default-error @state) :duration 0})
    (r/route-to-impl! env {:handler :camera})
    (u.m.state-machine/set-impl! env {:value :base}))
  (remote [env] (pm/pessimistic-mutation env)))

currentoor01:10:01

which definitely relies on the upload-file mutation happening on the server a priori

currentoor01:10:46

and i’m able to ensure this only with the incubators ptransact! not the one built into fulcro proper

(pm/ptransact! this
                        `[(r/route-to {:handler :packages})
                          (u.m.state-machine/set {:value :photo-taken})
                          (upload-file ~file)
                          (new-wash-&-unconfirmed-vehicle
                            {:file-id ~id :wash {:wash/id    ~wash-id
                                                 :wash/state :initial}})])

currentoor01:10:53

i’m not sure how (if) tempid resolution is affected across remotes however, i’m using client generated UUIDs which i use as primary keys everywhere

currentoor01:10:13

@pvillegas12 does that make sense?

pvillegas1201:10:04

yeah, @currentoor I’ll try using the incubator ptransact! I can get the tempid mapping from the state if they are properly chained

currentoor01:10:57

ok, do you need tempids?

currentoor01:10:33

switching away from them to client generated random-uuids did save me some headache and complexity

pvillegas1201:10:49

this is the first time tempids are biting me 😛

currentoor01:10:22

are you using datomic also?

pvillegas1201:10:22

but I do see how the client uuids can help here

pvillegas1201:10:27

yes, using datomic

currentoor01:10:33

yeah same for me

pvillegas1201:10:49

The tempid remapping is quite harmless 🙂

currentoor01:10:30

yeah in most cases i agree it works, but it is a non-zero amount of extra complexity

currentoor01:10:03

and i’m not sure how much benefit it provides, it’s just one more thing that can go wrong

pvillegas1201:10:44

Do you have the convention of some field for all types of objects?

currentoor01:10:12

yeah it was @tony.kay’s suggestion, we use <entity-name>/id

currentoor01:10:51

so a user entity will have an attribute called :user/id which will be a UUID with a uniqueness constraint (indexed)

currentoor01:10:13

I believe @wilkerlucio uses that too?

pvillegas1201:10:50

yeah, that looks like a better way to handle client generated tempids

currentoor01:10:13

i’d recommend going one way or another early on, refactoring in a larger project won’t be fun 😅

currentoor01:10:22

but do what works for you simple_smile

wilkerlucio01:10:39

I like the :user/id format, reduces the translations of attributes to do on server side when using pathom

currentoor01:10:14

oh yeah i forgot, it’s better for working with pathom (which is pretty cool by the way)

pvillegas1202:10:08

Incubator’s ptransact! works 😄

Sturm04:10:55

When using defrouter would it be normal to define your "navigation handler" function in the root component and pass it all the way down to the place where it's needed? So you might be using prim/computed going down through several levels of UI components?

currentoor04:10:16

for a component that needs to know the current route you add [fr/routers-table '_] to it’s query

currentoor04:10:18

say the relevant router is ::admin-router

(defrouter WashProgramAdminRouter ::admin-router
  (fn [_ props] (tab-ident props))
  ::details WashProgramDetailsTab
  ::subscriptions WashProgramSubscriptionsTab
  ::reports WashProgramReportsTab)

currentoor04:10:50

then in render you can get the current tab like so

(let [routers-table (get props fr/routers-table)
      active-tab    (first (fr/current-route routers-table ::admin-router))]
  ...)

Sturm04:10:52

what if it needs to change the route though? Won't optimisation prevent the root component from re-rendering with the new route displayed if the mutation is made from a nested UI component?

currentoor04:10:21

if you want to change the route you have two choices

currentoor04:10:43

fulcro.client.routing/route-to mutation

currentoor04:10:18

or fulcro.client.routing/route-to-impl! helper function can be called inside one of your mutations

currentoor04:10:06

> Won’t optimisation prevent the root component from re-rendering with the new route displayed if the mutation is made from a nested UI component? the root component queries for the top level router right? it should update

currentoor04:10:30

does that make sense?

Sturm04:10:36

I'm currently using routing/route-to, but was finding that while the DB was changing, the router wasn't being re-rendered. I might need to do some more testing. Thanks for your help

currentoor04:10:23

hmm yeah it should work probably need some debugging, unless i misunderstood something 😅

currentoor04:10:52

definitely try to avoid passing routes directly through computed props

currentoor04:10:05

have you read the book’s sections on routing?

currentoor04:10:10

and no worries

currentoor04:10:24

oh but i just realized my router uses html5 routes, that might change things

currentoor04:10:57

you can make your own mutations that calls r/route-to-impl and use declarative refresh http://book.fulcrologic.com/#_declarative_refresh

Sturm04:10:10

I've read bits and pieces about routing in the book, but I probably need to go through it all again

currentoor04:10:41

if the mutation changes something the root depends on, and you declare that key in it’s refresh section then it definitely will re-render

Sturm04:10:02

I've just tried calling (prim/transact! this [(routing/route-to {:handler :list})])` on a component a few levels below the router and it's definitely changing the DB but not re-rendering the router

Sturm04:10:43

Where this is the nested component

Sturm04:10:44

@currentoor if I add a follow-on read for something on the root component it works though

levitanong09:10:46

@tony.kay I’m looking at the fulcro book, and it says somewhere that if I want to deal with REST, I should be using the fulcro legacy networking API. Could you elaborate on why this is the case? I ask because I’ve been using the new networking API with REST just fine, and I’m wondering if I’m missing something.

aisamu12:10:50

IIRC the new recommendation is Pathom and the docs are just outdated

tony.kay14:10:07

Yes, Pathom is the answer…please open an issue or send a PR…probably should dump that chapter

tony.kay14:10:13

and refer to pathom async parsers for the client

tony.kay14:10:26

much better and easier

levitanong02:10:21

awesome, thanks! issue opened.

Sturm12:10:56

Any tips on how to make a controlled input field that syncs remotely onBlur? I'm currently passing an extra parameter to my mutation called local-only in onChange, which seems to work ok

Sturm12:10:18

I'm basically trying to avoid making a server request on every keystroke

Pontus13:10:01

@ben735 perhaps you could have the onChange only update local react-state and bind the mutation to onBlur ?

tony.kay14:10:26

@ben735 You just need to add a follow on read for something in the parent, or even fr/current-route…the routing stuff in Fulcro doesn’t invalidate the rest of the UI refresh story.

currentoor16:10:22

@ben735 mutations refresh section is a follow on read simple_smile <EDITED>

tony.kay16:10:28

I don’t follow your comment @currentoor

tony.kay16:10:38

remote? Do you mean refresh?

pvillegas1217:10:16

@currentoor the incubator functions don’t help either, a composition of mutations with different remotes does not respect pessimism 😞 I went with returning the data I need from the first remote instead of separating it out

currentoor17:10:47

strange it’s working for me

pvillegas1217:10:01

Looking at the above snippet, how do you actually rely on the file upload finishing?

pvillegas1217:10:49

If you are using a client generated file id for the optimistic part of the UI you don’t really need the server to respond from the file upload

pvillegas1217:10:51

m/with-target is not working for me in the file-upload remote, any ideas how to debug this?

tony.kay17:10:34

so, all of the returning/targeting stuff works by modifying the AST of the remote request

tony.kay17:10:00

chances are you’re middleware is morphing the query/ast and dropping the data

tony.kay17:10:31

read the source of with-target @pvillegas12, and follow the data through your middleware

pvillegas1217:10:08

Now I’m getting Query ID received no class, how do I ensure meta-data is preserved when copying the right data? In this case it’s 'query from the ast

tony.kay17:10:41

if you make a new query, just copy the metadata over from the old one

tony.kay17:10:57

the query will also have metadata for :component

tony.kay17:10:09

which is the secret sauce for normalization

pvillegas1217:10:29

In this case, I want to put raw data into a specific path

tony.kay17:10:30

when you get to the networking layer, things get a bit more involved 🙂

pvillegas1217:10:55

Right now I’m doing

(cond-> (assoc resp
                      :error :none

                      :transaction [(merge (select-keys ast [:query])
                                      {(file-path real-id) [:db/id :status]})])

pvillegas1217:10:20

@tony.kay what else should I be doing apart from this merge?

tony.kay17:10:01

So, here’s the core thing you need to know: The return value from your middleware goes directly to prim/merge!

tony.kay17:10:11

your query is the query to merge, and the data is the data to merge

pvillegas1217:10:59

(Right now the data is getting merged, however it is being merged at root)

tony.kay17:10:00

get-query adds metadata to the query to let it know how to normalize..and the shape has to match

tony.kay17:10:09

so normalization is ok

pvillegas1217:10:29

no normalization (big payload)

pvillegas1217:10:55

This is the file upload use case I was discussing before

pvillegas1217:10:03

I’m returning the computation with the tempid mapping

pvillegas1217:10:16

(couldn’t get two remotes to behave :()

tony.kay17:10:42

prim/merge-mutation-joins is the processing for a mutation that has a returning

tony.kay17:10:05

you’re doing a mutation for uploads if I remember right

pvillegas1217:10:24

yes, I’m currently doing

(file-upload [{:keys [ast]}]
    (println "upload-file")
    (println parent-id)
    (m/with-target ast [:integration-details :root-router])))

pvillegas1217:10:32

for the remote part of the mutation

tony.kay17:10:43

so targeting won’t work unless the mutation looks like a mutation join…because otherwise there is nothing to move

tony.kay18:10:39

your query should look something like [{(upload-mutation param-map) ['*]}]

tony.kay18:10:19

or whatever query matches the thing your returning besides [*]

tony.kay18:10:41

then targeting is added on the metadata of THAT query…e.g. (vary-meta (get-query ReturnType) assoc ::fdi/target [:target :path])

tony.kay18:10:17

where the get-query gets you a query that has :component metadata on all of the recursive things in the query

tony.kay18:10:48

but it no normalization, then you could just use ['*] for the query I think

pvillegas1220:10:38

@tony.kay I got it working 😄 that was intense 😛

tony.kay20:10:52

happy to hear feedback on making it easier…also, I should probably see if I can fix ptransact across multiple remotes…it should actually work

pvillegas1220:10:35

If you give me some guidance I can work on this

tony.kay20:10:36

you mean the issue?

tony.kay20:10:41

be happy to!

tony.kay20:10:07

It could be easier for me to fix than guide…I’ll have to glance around. But the testing part takes time, so that would be helpful if you’d be willing to do that part at least. I might be able to direct you to the code path as well…easier for you to do both if the fix is relatively direct

pvillegas1220:10:42

Yeah, would be interested in going more into the internals, so I would be grateful, even for testing 😉

pvillegas1220:10:22

@tony.kay you can either DM more details or add info on the issue and I’ll take it from there (asking questions along the way)

pvillegas1220:10:09

Namely I aligned these two pieces

(assoc resp
                  :error :none
                  :transaction [{(file-path real-id) [:db/id :status]
                                 target              [:pipeline-data]}])
and
(assoc resp :body
    (merge body {(file-path id) {:db/id id :status status}
                 target         (select-keys body [:pipeline-data])})))

pvillegas1220:10:40

The problem was an understanding of how the middleware (the file upload one) was manipulating the query merging

pvillegas1220:10:43

@tony.kay doing this manual merging, how do I get rid of the edge on the root? I am seeing pipeline-data in the correct path, but root has the same data too.

tony.kay20:10:19

I mean, if you’re properly using the targeting system, it should do that for you

pvillegas1220:10:47

(defn- body-response [{:keys [body] :as resp} target id status]
  (assoc resp :body
    (merge body {(file-path id) {:db/id id :status status}
                 target         (select-keys ('upload body) [:pipeline-data])})))

(def file-response-middleware
  "Response middleware that manipulates the merging of data (mainly the datomic
  id of the file and the computed data from the pipeline) by handcrafting
  :transaction in the response."
  (->
    (fn [{:keys [body error] :as resp}]
      (let [ast     (prim/query->ast1 (:transaction resp))
            id      (get-in ast [:params :value :db/id])
            target  (-> ast :query meta vals last)
            real-id (get-in body ['upload ::prim/tempids id])]
        (cond-> (assoc resp
                  :error :none
                  :transaction [{(file-path real-id) [:db/id :status]
                                 target              [:pipeline-data]}])
          (= error :network-error)      (body-response target id :network-error)
          (= error :http-error)         (body-response target id :network-error)
          (and real-id (= error :none)) (body-response target real-id :complete))))
    (net/wrap-fulcro-response)))

pvillegas1220:10:59

That’s what I’m doing (similar to the one in the file upload repo)

pvillegas1220:10:11

I got around it my hiding the data in 'upload 😛

pvillegas1220:10:50

I feel I’m tiptoeing the targeting system, but I don’t think it can be avoided

tony.kay21:10:11

I don’t see you using targeting anywhere in that code

pvillegas1221:10:50

Implicitly using it here target (-> ast :query meta vals last)

tony.kay21:10:04

you’re reading it, but you’re not letting Fulcro process it for you

pvillegas1221:10:30

right, that’s because I’m creating a new :transaction if I understand correctly

tony.kay21:10:31

and vals last is not reliable

tony.kay21:10:01

maps have a “predictable order” for internal reasons you should not rely on

tony.kay21:10:30

nor can I guarantee that order won’t change due to my own code changes to Fulcro

pvillegas1221:10:11

yeah, you’re right

tony.kay21:10:51

so, you’re not changing the body, but your code isn’t enough for me to understand things…what is IN body?

tony.kay21:10:34

and what target are you passing?

pvillegas1221:10:17

body

{upload
 {:fulcro.client.primitives/tempids
  {#fulcro/tempid["8e9d4a09-e06d-451f-8d7b-f10a178a6f9c"]
   #object[Object 28684059345420642]},
  :pipeline-data [...]
call site
(defmutation upload-file [{:keys [ident value parent-id]}]
  (action [{:keys [state]}]
    (swap! state set-value* ident value))
  (file-upload [{:keys [ast]}]
    (println "upload-file")
    (println parent-id)
    (m/with-target ast [:integration/by-id parent-id])))

pvillegas1221:10:10

From what I can see, if I change :transaction within the response, I need to manually merge the data I care about

tony.kay21:10:44

no, you change the transaction to include the mutation merge “query” that will support targeting

tony.kay21:10:09

you want something like (in this last defmutation) (-> ast (m/returning ['*]) (m/with-target [:integration/by-id parent-id]))

tony.kay21:10:52

then your middleware pretends to be the server, and returns

{`upload-file {data map of stuff}}

tony.kay21:10:27

actually returning takes a component, I think

tony.kay21:10:36

so you might need to write a placeholder component with that query

pvillegas1221:10:12

and I don’t touch the transaction in the response then in the middleware?

tony.kay21:10:22

for that matter, if you write the placeholder and it has an ident function that could generate the “target”, you’d be all set I think

tony.kay21:10:39

don’t think you need to, do you?

tony.kay21:10:44

are you adding other data?

pvillegas1221:10:53

no, that’s the entire implementation above

tony.kay21:10:01

the db/id status thing, perhaps?

pvillegas1221:10:15

the db/id is tempid remapping

tony.kay21:10:14

nah, I mean the ident-based merge you’re doing for the file upload entity

tony.kay21:10:01

is pipeline data a single map? You’re showing it as a vector

pvillegas1221:10:34

it is a vector of maps

pvillegas1221:10:44

but it should not be normalized

tony.kay21:10:46

if you want to return that shape from the server, then :pipeline-data is going to end up nested in the entity map

tony.kay21:10:24

but your with-target isn’t doing anything because there is no query…you have to use returning

tony.kay21:10:34

or with-target is a noop

tony.kay21:10:02

as far as it’s concerned, there is nothing to move, because you’re returning “void”

pvillegas1221:10:21

The error-message retargetting

tony.kay21:10:35

ah, I was misremembering I guess…

tony.kay21:10:52

but then I’m not understanding why you had to do all of this manipulation

pvillegas1221:10:32

just the with-target part would not re-target the data, the pipeline-data would remain placed in the root

pvillegas1221:10:04

and then I realized that the middleware was modifying the :transaction and that led me to the above

tony.kay21:10:29

I see…but the problem wasn’t the targeting…it was the manipulation of the transaction

tony.kay21:10:36

it was throwing out the metadata

pvillegas1221:10:51

I also tried adding the metadata back in to the query part

tony.kay21:10:29

did you try just pulling the incoming transaction and doing a conj for the file upload status?

pvillegas1221:10:41

something like

:transaction [{(file-path real-id) (with-meta ['*] (meta :query resp)     }])

pvillegas1221:10:57

let me try that

tony.kay21:10:58

or just (update resp :transaction conj ...)

tony.kay21:10:00

the original mutation query would have been correct for the targeting, and you didn’t need to throw it out…just add in the extra stuff you want to cause to be merged

pvillegas1221:10:58

@tony.kay

(defn- body-response [{:keys [body] :as resp} id status]
  (assoc resp :body
    (assoc body (file-path id) {:db/id id :status status})))

(def file-response-middleware
  "Response middleware that manipulates the merging of data (mainly the datomic
  id of the file and the computed data from the pipeline) by handcrafting
  :transaction in the response."
  (->
    (fn [{:keys [body error] :as resp}]
      (let [ast     (prim/query->ast1 (:transaction resp))
            id      (get-in ast [:params :value :db/id])
            real-id (get-in body ['upload ::prim/tempids id])]
        (cljs.pprint/pprint body)
        (cljs.pprint/pprint (:transaction resp))
        (cond-> (assoc resp
                  :error :none
                  :transaction (conj (:transaction resp)
                                 {(file-path real-id) [:db/id :status]}))
          (= error :network-error)      (body-response id :network-error)
          (= error :http-error)         (body-response id :network-error)
          (and real-id (= error :none)) (body-response real-id :complete))))
    (net/wrap-fulcro-response)))

pvillegas1221:10:06

not working 😞

pvillegas1221:10:26

The transaction before is

[{(contaico.api.mutations/upload-file
   {:ident
    [:file/by-id
     #fulcro/tempid["49514c48-f4f8-42ec-886c-c86b5e13ba12"]],
    :parent-id #object[Object 62469852643721535],
    :component #object[contaico.ui.file-upload.FileUpload],
    :value
    {:db/id #fulcro/tempid["49514c48-f4f8-42ec-886c-c86b5e13ba12"],
     :file/type :file.type/main,
     :file/name "2018-05-alegra-invoices.csv",
     :file/size 561887, 
     :file/uploaded? false, 
     :file/js-file {}}}) 
  [*]}]

pvillegas1221:10:11

is the problem that the query is not including the :pipeline-data?

tony.kay22:10:58

@pvillegas12 your problem I think is body-response

tony.kay22:10:17

well, maybe not…reading again

tony.kay22:10:29

I’m not seeing the problem 😕

pvillegas1222:10:17

weirdness, at least the other version is working

tony.kay22:10:19

wait…is that the right order for the middleware

tony.kay22:10:28

I always have trouble thinking about that…

tony.kay22:10:52

I guess it is

tony.kay22:10:31

is your server changing the name of the mutation?

tony.kay22:10:43

you’re reading 'upload out

tony.kay22:10:05

but that’s not the mutation name you showed in the response

pvillegas1222:10:36

mmm, can you elaborate?

tony.kay22:10:53

contaico.api.mutations/upload-file vs upload

tony.kay22:10:23

your server isn’t responding with the same mutation name as the client is putting in the request

pvillegas1222:10:19

I guess this is taken care of by the macros like defquery-root on the server right?

tony.kay22:10:45

yes…the parser period

tony.kay22:10:18

The network protocol is very simple…you send a query for :x or ’mutation, and the response has to include {:x value 'mutation value}.

👍 4
tony.kay22:10:22

not hard really 🙂

tony.kay22:10:26

things just have to match

tony.kay22:10:47

and of course queries can nest, so there is that complication, but in principle, it’s very simple

tony.kay22:10:37

but yeah, for return value processing and targeting, the internals cannot assume the targeting on one mutation applies to some other, just because it’s the only one there 🙂

pvillegas1222:10:30

thanks for the help!

pvillegas1222:10:56

Haven’t tried yet, @tony.kay I’ll let you know if that does it

tony.kay23:10:49

So @pvillegas12 @currentoor, I’ve just run a test on Fulcro on ptransact! against two diff remotes. It behaves as I would expect, and defers properly. I’m confused as to why either of you had problems.

currentoor23:10:52

i’m in the middle of something, but i can verify later

currentoor23:10:16

wait does original ptransact! support ok-*?

tony.kay23:10:30

I’ll expand my tests and see if I can reproduce

currentoor23:10:46

I’m getting this error when i run the clj side of fulcro-spec (#:fulcro-spec.selectors{set-active-selectors #:fulcro.client.primitives{:error java.lang.AbstractMethodError}} "Parser error:\n" {:status 400, :body #:fulcro-spec.selectors{set-active-selectors #:fulcro.client.primitives{:error {:type "class java.lang.AbstractMethodError", :message nil}}}})

currentoor23:10:55

but i’m not sure what i’m doing wrong

tony.kay23:10:39

yeah, sorry…I think there are certain things your tests can do that break the runner over there…I’ve seen that as well…fixing it is usually commenting out some tests

tony.kay23:10:52

and then trying to figure out what’s wrong with the one failing

tony.kay23:10:55

Marking bug 254 as “cannot reproduce”. I wrote a full-stack example with two remotes, and it works as documented.