Fork me on GitHub
#fulcro
<
2021-03-08
>
tony.kay02:03:35

Fulcro 3.4.19-SNAPSHOT is on clojars with various additional dev-time checks to help with common mistakes: • Emits a compiler error if a component’s query looks like an obviously wrong EQL statement • Emits js console warnings if the initial state of your application looks wrong on initial mount • Emits runtime warnings to js console if the app query looks wrong on set-query! or dynamic hot code reload

😻 18
Jakub Holý (HolyJak)15:03:02

BTW, based on our chat, I plan to add a runtime check to fulcro-troubleshooting checking that initial state of every component that has one is properly included in its parent (as much as this will be possible). If you say this is a common source of errors that it will be great to help with avoiding the trap :)

tony.kay15:03:26

Already did that

tony.kay15:03:44

See the bottom of components.cljc

tony.kay15:03:55

added that as part of touching up your extra warnings

tony.kay15:03:29

it occurred to me that now that I have a component registry, it is possible to just scan for all declared components and check them

Jakub Holý (HolyJak)16:03:04

Ah, awesome! BTW I see this in my app > Component com.fulcrologic.fulcro.algorithms.form-state/FormConfig has a constant ident, but no initial state. This could cause this components props to appear as nil unless you have a mutation or load that connects it to the graph after application startup. even though I do not even use form state (though something I inherited from RAD demo and forgot to delete might). I suppose it is ok and should just be ignored but wanted to let you know in case it is an undesired side-effect.

tony.kay16:03:20

I should add it as an exception. In this case the ID portion of that class is strange, and is mis-detected

👍 3
tony.kay16:03:54

updated snapshot

tony.kay16:03:20

68138eb5d510eebd0d317cbb257ea9f23001e44a is the SHA

❤️ 3
Jakub Holý (HolyJak)16:03:53

> a mutation or load that connects it to the graph after application startup I am afraid this might be unclear to beginners. What is the load expected to do? Insert some - possibly empty but non-nil - data as in (pseudocodish) (assoc-in state (get-ident component) {}) ? Or insert some data in its parent, as in (assoc-in state (conj (get-ident (get-parent component)) <the name of the corresponding parent's prop>) {}) ?

tony.kay16:03:49

The warning is to let you know something is wrong. The book and videos are there to help you resolve it. I’m open to better messaging, such as “See …” with a book URL if you want to make one

tony.kay16:03:32

Heck, we can create a book section for “Understanding errors and warnings” that makes a list of them and gives a lot of detail

😻 3
tony.kay16:03:49

Then every error message could point to a URL in the book. That would be great

Jakub Holý (HolyJak)16:03:32

No, that would be absolutely awesome! I would be very happy to help with that. Something like the errors react logs...

Jakub Holý (HolyJak)16:03:44

Perhaps I could go through the codebase and make a list of all log/error and log/warn texts?

👏 3
tony.kay16:03:09

please. Then add an Appendix to fulcro-developer-guide adoc file?

tony.kay16:03:29

I’m happy to help with the content detail, of course, but it’d be nice to have the help joining it all together

alex-eberts21:03:14

This is great. I’m very happy to help with documentation and leg-work where ever I can. I’m optimistic that an “understanding errors and warning” page will really help people get “un-stuck” when working through the getting started material.

tony.kay01:03:59

Please. I’m swamped, so if you two want to coordinate that’s great. Any amount of putting together the errors and figuring out what to link them to (and generating those internal adoc cross-ref links) would be great. I can then just concentrate on writing a paragraph or two (or refine what you write) in the book.

alex-eberts02:03:20

Will do - I’ll coordinate with @holyjak. :thumbsup:

Jakub Holý (HolyJak)10:03:49

I am making some progress:

(g/grasp-string
 (slurp (io/file "components.cljc"))
 (s/cat :log #{'log/warn 'log/error}
         :rest (s/+ (constantly true))))
; =>
[(log/error
  "Cannot create proper fulcro component, as *app* isn't bound."
  "This happens when something renders a Fulcro component outside of Fulcro's render context."
  "See `with-parent-context`.")
 (log/warn
  "get-ident was invoked on "
  (component-name x)
  " with nil props (this could mean it wasn't yet mounted): "
  x)
 ...
🙂

tony.kay15:03:55

I think a “Find in Path…” in IntelliJ would have been quicker 😉

Jakub Holý (HolyJak)15:03:44

No doubt about that. But the coolness factor is close to 0 :)

tony.kay02:03:11

git sha cb160470072a7489719c613994a9aa9f193ad268 if you want to try it that way. Thanks to @holyjak for most of the work on the query validation.

Marcus11:03:00

Ok. So I am trying to learn fulcro by walking through the "getting started" chapter in the fulcro book. At section https://book.fulcrologic.com/#_mutations_on_a_normalized_database I have updated the example code. It works fine except that the mutations don't remove persons from the lists. Where can I find a complete example of this code? I.e. excluding the remote stuff for now.

Jakub Holý (HolyJak)12:03:52

I am not sure there is one. What does your code look like, can you share a link to it? Also, have you seen https://fulcro-community.github.io/guides/tutorial-minimalist-fulcro/ and https://blog.jakubholy.net/2020/troubleshooting-fulcro/ ? Though for mutations there is perhaps not that much help. Remember you can use REPL to get the value of the client DB I am not sure there is one. What does your code look like, can you share a link to it? Also, have you seen https://fulcro-community.github.io/guides/tutorial-minimalist-fulcro/ and https://blog.jakubholy.net/2020/troubleshooting-fulcro/ ? Though for mutations there is perhaps not that much help. Remember you can use REPL to get the value of the client DB (com.fulcrologic.fulcro.application/current-state app.application/app) and try your mutation code (what you have inside action ) in the data (only replace swap! with update ). What does happen? How does it differ from what you expected?

Marcus12:03:13

Thanks for the resources. I will look through them all. 🙂 I tried to debug the mutation and I got it working by modifying the parameters sent in to delete-person and the destructuring setup in delete-person itself. I think I just need to clean it up now to see how it really should be

🎉 3
Marcus12:03:57

(defmutation delete-person "Mutation: Delete the person with :person/id from the list with :list/id" [{:keys [person-id list-id]}] (action [{:keys [state]}] (swap! state merge/remove-ident* [:person/id person-id] [:list/id list-id :list/people])))

Marcus12:03:24

plus passing in the correct values to the mutation

Marcus12:03:28

ie (fn [person-id] (comp/transact! this [(api/delete-person {:list-id id :person-id person-id})]))]

Marcus14:03:19

@holyjak thanks for the tutorial tip.. it really helps to read both tutorials.

👍 3
Jakub Holý (HolyJak)15:03:02

BTW, based on our chat, I plan to add a runtime check to fulcro-troubleshooting checking that initial state of every component that has one is properly included in its parent (as much as this will be possible). If you say this is a common source of errors that it will be great to help with avoiding the trap :)

alex-eberts22:03:25

@tony.kay Do you have any plans to support namespaced keyword in incoming parameters for the template form of :initial-state? If not, then perhaps this is another opportunity for a warning or error message. I bumped into this case this afternoon - only after careful reading of 6.2.5 in the book did I notice that incoming parameters must use simple keywords. 😅

tony.kay01:03:52

No, not in the magic interpretation. If you write initial state as a fn, then you can do whatever you like with the params.

tony.kay01:03:45

The problem is without a param ns the magic could get confusing with respeect to what is a prop (for error checking), what is a literal keyword, and what should be pulled from “params”

alex-eberts02:03:50

Ok - got it. That makes sense. :thumbsup: