Fork me on GitHub
#fulcro
<
2019-12-17
>
hadilsabbagh1803:12:22

So I'm still trying to solve my problem. I have gotten much further -- I now have the optimistic update working. However, my mutation code returns:

"Transmission was aborted because the request middleware returned nil or threw an exception"
My client and server mutations match up, and I'm pretty sure this is a client error. Here is my client mutation:
(defmutation add-person
  "Mutation: add a new person with ':person/name :person/age' to the list with ':list/id"
  [{name    :person/name
    age     :person/age
    list-id :list/id
    tempid  :tempid}]
  (action [{:keys [state]}]
          (swap! state assoc-in [:person/id tempid] {:person/id tempid :person/name name :person/age age})
          (swap! state update-in [:list/id list-id :list/people] conj [:person/id tempid])
          (js/console.log "state=" state))
  (remote [env] true))
and here is my server mutation:
(pc/defmutation add-person [env {name    :person/name
                                 age     :person/age
                                 list-id :list/id
                                 tempid  :tempid}]
                {::pc/sym `add-person}
                (log/info "Adding person" name age "to list" list-id)
                (dosync
                  (let [person-id (get @people-table :next-id)]
                    (swap! people-table assoc person-id {:person/id person-id :person/name name :person/age age})
                    (swap! people-table update :next-id inc)
                    (swap! list-table update list-id update :list/people #(conj % person-id))
                    {:tempids {tempid person-id}})))
I appreciate any help offered. I am getting desperate to solve this!

tony.kay04:12:24

@hadilsabbagh18 So, your code looks pretty much right

tony.kay04:12:11

what is the return value of dosync? I don’t remember…if it isn’t serializable, then that is your problem

tony.kay04:12:36

you’re getting a middleware exception on the server or client? you didn’t say where that exception was

hadilsabbagh1804:12:54

Hi @tony.kay. dosync returns the last statement. The middleware exception is on the client. The log statement on the server does not get executed.

tony.kay04:12:28

Are you passing anything strange in as parameters? What is you call to transact! look like?

tony.kay04:12:43

the middleware is pretty robust, but it won’t tolerate anything that cannot be transit encoded

tony.kay04:12:57

and how did you configure your app remote? Did you customize it at all?

tony.kay04:12:24

See also: There is a new algorithms ns called normalized-state…it has a swap!-> macro that is super nice for doing multiple steps in a mutation FYI

hadilsabbagh1804:12:42

@tony.kay Here is my transact! call:

(defsc AddPerson [this {:person/keys [id name age] :as props}]
  {:query [:person/id :person/name :person/age :list/id :tempid]
   :ident (fn [] [:person/id id])}
  (let [tempid (fulcro.tempid/tempid)
        new-person {:tempid      tempid
                    :person/id   tempid
                    :person/name "Mom"
                    :list/id     :friends
                    :person/age  76}
        add-person (fn []
                     (comp/transact! this [(api/add-person new-person)]))]
    (ui-button {:onClick #(add-person)} "Add Mom!")))
I don't know if tempid can be transit-encoded. I did not customize the app remote. Basically I built the application described in the added semantic UI and then added the AddPerson component. My delete works properly and so does the optimistic update.

tony.kay04:12:44

strange…the default http remote middleware is set up to support tempids

tony.kay04:12:47

I was just using them today

tony.kay04:12:59

how is your mutation defined?

tony.kay04:12:12

oh I see it above

tony.kay04:12:35

any more details on the exception?

hadilsabbagh1804:12:18

It is in the Fulcro inspector as an entry in the local database. The console just says cannot write.

tony.kay04:12:47

ah, cannot write sounds like a transit problem…any weird deps in your project?

tony.kay04:12:57

perhaps a screwed up version of transit is in your deps

tony.kay04:12:01

transitively

hadilsabbagh1804:12:33

Let me check into that. Thanks @tony.kay! I appreciate the late night help!

tony.kay04:12:46

try adding "transit-js": "0.8.861" to your package.json

tony.kay04:12:06

there is a weird bug I remember transit having with respect to something…I don’t remember what…but I think that might fix it

tony.kay04:12:22

then do your npm install and clean/restart shadow-cljs

tony.kay04:12:40

(rm -r .shadow-cljs, and generated js files, just to be safe)

tony.kay04:12:08

I’m about done for the night…but I’m betting that will fix it

hadilsabbagh1804:12:37

Thanks again @tony.kay

tony.kay04:12:06

@hadilsabbagh18 interested in knowing if that fixes it…you could also try setting the version of transit-cljs in your deps.edn if it isn’t there

hadilsabbagh1804:12:26

Ok. I will try that also.

hadilsabbagh1804:12:41

The npm did not fix the problem.

tony.kay04:12:57

also, what version of cljs? If you’re using “latest everything” it might be something in some new version of something

hadilsabbagh1804:12:47

adding transit-clj also did not fix the problem. I am using shadow-cljs 2.8.83 and clj 1.10.1

hadilsabbagh1804:12:32

Shoould I use the deps.edn and other config files from the example git repo?

tony.kay04:12:33

@hadilsabbagh18 Always start with a known good config on deps and package.json

tony.kay04:12:58

you can update to the latest version of Fulcro, get your app working, then try bumping other deps

hadilsabbagh1805:12:26

Ok. I'll try that.

thosmos05:12:00

is there a way of adding some metadata on the server side to a query result like (with-meta results {:result-count 42}) ? I was about to add a :query-count key to all queries for this, but I just realized it can possibly be done with metadata? Or does that not cross over the wire?

thosmos05:12:29

or should I do a separate query just for the meta info?

tony.kay05:12:47

metadata does not go on the wire (I think you can enable that in transit, but I don’t have it). You can always use a namespaced key…open maps are your friend.

tony.kay05:12:39

@hadilsabbagh18 you also have cache turned off in Chrome browser while in dev mode?

tony.kay05:12:45

make sure you’re not getting old versions of files

hadilsabbagh1805:12:38

Let me double-check

hadilsabbagh1805:12:48

I do have cache turned off in Dev mode.

hadilsabbagh1805:12:18

@tony.kay I am going to bed. Will pick this up in the morning. Thanks for all your help!

thosmos05:12:18

@tony.kay I suppose the problem with adding a key to something that returns 100 results is that the key is repeated in all records and it would pollute the DB. not a big deal i guess. or I do some strange thing like return an empty record with just the meta keys, etc, but it all sounds hacky. If I wanted to turn on metadata support in transit, would that be doable in the transit wrappers on both side?

tony.kay05:12:50

don’t know off the top of my head…you’d have to look

tony.kay05:12:32

not sure it supports it at all…might be thinking of edn encoding

tony.kay05:12:59

@thosmos you may also be prematurely optimizing…is it really that much space in today’s memory terms or even network speeds?

thosmos05:12:28

hehe, ssshhh I’m actually using this to avoid other things ;)

tony.kay05:12:34

ah…got it

thosmos05:12:55

but good point, I think I’ll just make a separate query just for one row of metadata

thosmos05:12:12

that’s how the old system does it in graphql that I’m replacing

thosmos05:12:30

apparently transit supports it, just need to turn it on. I think it’s a cool feature to have for queries, because pagination uses total number of results before the filters are applied

tony.kay05:12:09

cool, well, might be fun to play around with…let me know if you get good results

thosmos05:12:42

I think I’ll try getting it to work with the template app and will send you a PR if it seems worthwhile (and if I actually get it working)

thosmos07:12:38

So I made a successful test of passing metadata from server to client DB. It’s a one-liner: (wrap-transit-response {:opts {:transform t/write-meta}})

thosmos09:12:11

Ah, but it breaks something in session auth. will need some more work apparently

clojure38809:12:31

@tony.kay Regarding passing the req to parser env: its no trouble for me to reimplement wrap-api, and I should probably do that until my work stabilises - to your point about knowing what else I need.. thanks very much for commenting.

thomas12:12:28

Hi all, I am getting this error at the moment in my Fulcro app: Uncaught TypeError: Cannot use 'in' operator to search for 'fulcro$isComponent' in true and I am not quite sure what it causes this.

thomas12:12:31

any hints?

cjmurphy13:12:23

Perhaps you are not passing this (or app) as first argument in a call to comp/transact! . Just a guess...

fjolne.yngling14:12:57

I’m not sure what’s happening, but from time to time dynamic routers stop passing props to its targets and the only way to fix it is to literally clear all the caches (shadow-cljs + build). Anyone hit this behaviour? I have browser caches off + hit force refresh every time anyway.

fjolne.yngling14:12:43

Ah, I guess the problem is in defsc macro: I moved the target component from one ns to another, so might be that it somehow persisted in both of them. I recall cljs macros not updating unless one cleans the build.

thomas14:12:13

ta, I'll check it out

tony.kay16:12:52

@thomas you are passing a boolean where a component is expected, I think. The field fulcro$isComponent is a hidden field on components. A function tried to access it, but it found that instead of a js object it found the value true.

thomas16:12:53

yes, but the weird thing is that it works sometimes... when the value is false I don't get the error.

thomas16:12:00

only when it is true

tony.kay16:12:03

This particular kind of error message is common in the clj(s) ecosystem: TypeError cannot X on/in Y…in this case X is “use ‘in’ operator to search for ‘fulcro$isComponent’” and Y is “true”

tony.kay16:12:24

probably code that says something like (and component (component? component))

tony.kay16:12:28

(internally)

tony.kay16:12:40

I do that a lot to prevent NPE when ppl nil pun

tony.kay16:12:06

but it doesn’t help if you “boolean pun” 😜

thomas16:12:29

Thank, I'll continue later with this.

fjolne.yngling16:12:48

In case somebody else hits this issue: dynamic router should be elided from parent component query or else its props will get swept from that component, so it could not initialize properly (but otherwise would look ok). Spent like a few hours on this…

tony.kay16:12:56

what do you mean elided from parent component query…that is incorrect

fjolne.yngling16:12:19

Elided for network requests, sorry

tony.kay16:12:20

you have to compose router into your app just like any other component

tony.kay16:12:55

hm….I should beef up the default global eql transform to include that and the form config join

tony.kay16:12:22

in general you don’t “load” routers, so it isn’t an issue

fjolne.yngling16:12:38

Well, in case of the router it’s enough to just have it with ui namespace

fjolne.yngling16:12:14

I usually did it this way, but forgot in one place and that was a nightmare to debug

hadilsabbagh1817:12:06

Hi @tony.kay. I think there is an issue with transmitting tempids. I have instrumented the client and server with debug-handlers (which returns a function that prints its arg and passes it on). I have replaced the tempid with an integer and the network problem goes away.

tony.kay17:12:25

@wilkerlucio can you (or anyone else) think of any reason not to elide com.fulcrologic.fulcro* keys from EQL in network requests? I’m thinking I should make the default eql transform remove those in addition to UI kws, and I can’t think of any problems that will cause.

tony.kay17:12:18

@hadilsabbagh18 I can take a look…I have been using UUIDs a lot lately, but I’d be surprised if tempids are broken, but I would not be surprised if your deps were screwed up and transit was generally broken for your project.

wilkerlucio17:12:54

@tony.kay I can't think of a reason either, but I appreciate if it can be disabled (in case we realize some need for it in the future)

hadilsabbagh1817:12:01

@tony.kay. You are probably right.

tony.kay17:12:35

@fjolne.yngling I’m pushing 3.0.16-SNAPSHOT to clojars that has a new default eql transform that removes those keys from net queries. @wilkerlucio that transform is already configurable, so it is easy to override.

wilkerlucio17:12:52

sure, I just suggest keeping the strip functions separated, so the user can pull them manually and apply the ones that makes sense

tony.kay17:12:54

ah, there is already an elide-eql-nodes function that just takes a predicate…so easy enough to use/customize

wilkerlucio17:12:34

I remember that currently the thing that strip uis element is directly implemented as default-eql-transform, can we get that out?

tony.kay17:12:07

to save me some time: is anyone else using Fulcro tempids on network requests with Fulcro 3?

mdhaney18:12:36

Definitely working for me on 3.0.12

tony.kay18:12:19

Yeah, I’ve verified as well. Thanks 🙂

tony.kay17:12:21

if we have confirmed “it works for me” I’ll not go looking

tony.kay17:12:47

sorry, not 16 snapshot

tony.kay17:12:51

will be 17 snapshot

tony.kay17:12:53

@hadilsabbagh18 I’m running the todomvc project that lives in Fulcro as a test project. It uses tempids, and is working perfectly. The deps tree for the project is:

org.clojure/clojure 1.10.0
  org.clojure/core.specs.alpha 0.2.44
  org.clojure/spec.alpha 0.2.176
com.fulcrologic/guardrails 0.0.9
  expound/expound 0.7.2
edn-query-language/eql 0.0.9
  org.clojure/test.check 0.10.0-alpha3
com.taoensso/encore 2.115.0
  com.taoensso/truss 1.5.0
  org.clojure/tools.reader 1.3.2
cljsjs/react-dom 16.8.6-0
com.cognitect/transit-cljs 0.8.256
  com.cognitect/transit-js 0.8.846
org.clojure/clojurescript 1.10.520
  org.clojure/data.json 0.2.6
  org.clojure/google-closure-library 0.0-20170809-b9c14c6b
    org.clojure/google-closure-library-third-party 0.0-20170809-b9c14c6b
  org.mozilla/rhino 1.7R5
  com.google.javascript/closure-compiler-unshaded v20180805
    com.google.jsinterop/jsinterop-annotations 1.0.0
    com.google.javascript/closure-compiler-externs v20180805
    com.google.guava/guava 25.1-jre
      com.google.errorprone/error_prone_annotations 2.1.3
      org.codehaus.mojo/animal-sniffer-annotations 1.14
      com.google.j2objc/j2objc-annotations 1.1
      org.checkerframework/checker-qual 2.0.0
      com.google.code.findbugs/jsr305 3.0.2
    args4j/args4j 2.0.26
    com.google.protobuf/protobuf-java 3.0.2
    com.google.code.gson/gson 2.7
cljsjs/react 16.8.6-0
com.taoensso/timbre 4.10.0
  io.aviso/pretty 0.1.33
com.cognitect/transit-clj 0.8.313
  com.cognitect/transit-java 0.8.337
    commons-codec/commons-codec 1.10
    com.fasterxml.jackson.core/jackson-core 2.8.7
    org.msgpack/msgpack 0.6.12
      com.googlecode.json-simple/json-simple 1.1.1
      org.javassist/javassist 3.18.1-GA
    javax.xml.bind/jaxb-api 2.3.0
cljsjs/react-dom-server 16.8.6-0
cljsjs/socket-io-client 2.1.1-0
org.clojure/core.async 0.4.474
  org.clojure/tools.analyzer.jvm 0.7.0
    org.clojure/tools.analyzer 0.6.9
    org.clojure/core.memoize 0.5.9
      org.clojure/core.cache 0.6.5
        org.clojure/data.priority-map 0.0.7
    org.ow2.asm/asm-all 4.2

tony.kay17:12:10

Note the transit versions. This is generated with clj -Stree.

hadilsabbagh1817:12:32

Thank you @tony.kay. I will fix my deps accordingly.

hadilsabbagh1817:12:34

@tony.kay what does your package.json look like?

tony.kay17:12:41

it’s right there in the project

tony.kay17:12:44

open source and all 🙂

tony.kay17:12:16

but a lot of that stuff is overkill for a basic project

tony.kay17:12:30

some of it isn’t needed by Fulcro since I moved the book to a new repo

hadilsabbagh1817:12:31

I will just go with your website. Thanks @tony.kay

hadilsabbagh1818:12:21

Hi @tony.kay. I believe I have uncovered my problem. I followed the book but it still has Fulcro 2.8 references. In particular, fulcro.tempid is 2.8. What should I use for Fulcro 3?

tony.kay18:12:52

Oh, you have Fulcro 2 and 3 on classpath? I highly recommend you fix that

tony.kay18:12:11

Fulcro 3's is in com.fulcrologic.fulcro.algorithms.tempid/tempid

tony.kay18:12:23

I should have seen that…I assumed your code had an alias

hadilsabbagh1818:12:28

I now have only Fulcro 3. thanks @tony.kay

tony.kay18:12:56

glad it wasn’t a deps problem on transit…that was worrisome

tony.kay18:12:20

book updated. The ns list at beginning did list the ns, but the code in examples used the wrong alias

tony.kay18:12:37

where else in the book do you see tempid errors?

hadilsabbagh1819:12:40

Hi @tony.kay. Everything works as expected now. I appreciate your efforts in helping me, I know you are busy.

tony.kay19:12:20

welcome…I knew the “having both on the classpath” issue would bite some ppl, which is why I’ve gone to quite a bit of trouble to help ppl avoid it by even making a fork of workspaces that is f3 only. It’s OK for them both to be there, but they are not compatible with each other, as you found

thomas20:12:20

Hi All... still a bit confused here... I have a query for a value and I destructure the keys as well. I can see the value in the Fulcro Inspect tools (great tool BTW). but the value is null when I print it 😞

wilkerlucio21:12:19

when I have this problem it usually means that I forgot to put the key on the query part, or Im looking into the wrong ident

lgessler06:12:37

can you show us some code?

thomas14:12:23

I have figured it out... I had indeed a boolean where I should have done a (comp/get-query .... )

thomas14:12:35

and sorry for not getting back to you earlier.

thomas20:12:55

so I must be doing someting wrong... but I am not sure what though :((((

sfyire21:12:52

I'm playing with the react native fulcro 3 template but can't get the fulcro inspector electron app to connect to the mobile app in the simulator, how do I debug that?

sfyire21:12:15

I've uncommented the line in shadow file for the react target and restarted the web app server and mobile app

tony.kay01:12:56

ios sim or android?

tony.kay01:12:59

I’d use ios

tony.kay02:12:21

android won’t deal with “localhost”…to use it with inspect you have to figure out the IP address of you machine and set it via a goog define…

tony.kay02:12:04

Ah, at the moment I didn’t fix that up…only works with ios sim at the moment

tony.kay02:12:12

just a min…I can probably fix it

tony.kay02:12:29

Use Fulcro 3.0.17-SNAPSHOT

tony.kay02:12:46

and in your shadow-cljs.edn file add this:

tony.kay02:12:28

:dev {:closure-defines {com.fulcrologic.fulcro.inspect.inspect_ws/SERVER_HOST "x.x.x.x"}}

tony.kay02:12:46

I think you use _ in inspect-ws…if that doesn’t line up, use -

tony.kay02:12:38

@ Yes, definitely with the _. I just tested it, and it works (via web…not react, but that is the issue for android and devices)

sfyire19:12:08

I'm using the iOS simulator because of a different issue with using my phone, it appears to just work in your video, this is what I'm seeing https://i.imgur.com/4mqHGFH.png and this is my shadow-cljs.edn