Fork me on GitHub
#fulcro
<
2020-07-07
>
tony.kay14:07:44

Technically, global error action is called within tx processing, and you’re guaranteed a render after it finishes processing things. This means you could directly swap against the state atom in the global-error-action instead of having to write a mutation (https://gist.github.com/holyjak/a70947d6618c79279c68cc08f948603e#detect-errors)

tony.kay14:07:06

There’s no real benefit to using a mutation there, since you’re really augmenting internal logic, and you don’t plan on doing any full-stack operation, nor do you need a CQRS history of what you did in response to a full-stack error.

tony.kay14:07:05

In https://gist.github.com/holyjak/a70947d6618c79279c68cc08f948603e#detect-errors you might consider looking at default-result-action for mutations. Mutations have ref in env (which is the ident of the component that ran the mutation). There is a built-in variant of what you’re talking about here, but I think I’ve forgotten to document it: https://github.com/fulcrologic/fulcro/blob/develop/src/main/com/fulcrologic/fulcro/mutations.cljc#L198

tony.kay14:07:56

It could be that I forgot to finish the feature 😊

tony.kay14:07:56

but you see that will make sure the data is placed in app state on the component independent of the query. I think perhaps this feature isn’t finished, since it should probably use a :ui prop so that you can add it to the query and have it “just work”. Perhaps play with it.

tony.kay15:07:31

it can be easily overridden, and as you mention in your article you can prevent it on the network query using global eql transform.

tony.kay15:07:05

Another thing to note: The pathom path stuff is nice, but consider this idea: Make sure resolvers never throw, and have them return errors as first-class data. Remember my points here: http://book.fulcrologic.com/#_programming_with_pure_optimism Summary: only (detectable) security hacks and (unexpected) bugs should be hard-core errors. Intentional behavior of your server should always return a sensical value for a query, which may in fact simply be something like: “form save failed”. In that case components can query for problems with a real query prop, and each resolver can populate that key with an error if it has one.

tony.kay15:07:12

So, if you want to do component-level error handling, just adopt that philosophy and make remote-error? assume that something serious went wrong and the user probably should call support, reload the page, and perhaps even log back in.

holyjak16:07:18

Thanks a lot for the feedback!!! > Make sure resolvers never throw, and have them return errors as first-class data. That would be ideal but requires me to wrap each in try-catch or add a pathom transform - and if I forget somewhere and it fails, I'm screwed. The errors I'm getting are mostly unexpected (bug, downstream service issues,..)

tony.kay16:07:04

right, but then that’s a bug 🙂

tony.kay16:07:25

or you can define your own defresolver macro that does it for you (which is what I do, but I also add some addl security logic in as well)

holyjak16:07:04

I encounter mostly bugs and downstream service issues. This is an internal app so I don't worry about exposing the tech error details to the users and it makes troubleshooting easier and little les bad UX :)

tony.kay15:07:03

@jatkin wondering how your “reducers” and “subscriptions” for Fulcro are coming along. Interested in seeing what you’ve come up with.

jatkin15:07:12

Wrapped it up last night actually. Will send more info when I get to my computer :)

jatkin16:07:30

This does not have many details on the readme, but the code is short-ish. Maybe it's better to see the workspaces first. https://github.com/JJ-Atkinson/fulcro-subscriptions

jatkin16:07:01

Basically the model is every subscription is a function, and the interesting part of the api is how to create that function by chaining dependencies, keeping it efficient with short-circuit signals, (coming soon) memoization, (coming soon) push first models that don't call every function on render. Currently this works fine for my usecase though - I will have at most 15-20 subscriptions active on a screen.

jatkin20:07:21

On dynamic routers - why do I need to run this

(comp/get-query (comp/factory Component {:qualifier component-id}))
to get the current query? What is :qualifier doing in here?

tony.kay20:07:56

dynamic queries, by default, are tied to the class. The qualifier on a factory lets you have different queries for different instances in the UI

tony.kay20:07:00

so, that allows each on-screen instance of Component to have a customer query based on the ID of the component

tony.kay20:07:51

dynamic queries in older versions used component-local state, which made it “easier”, but also made a lot of different features unworkable, such as dynamic queries in CLJ, re-starting an app purely from state, etc, etc.

jatkin20:07:05

Cool. Makes sense.

jatkin21:07:27

Is it possible to set dynamic queries on a per-component-instance level? Basically union queries but without the nesting.

tony.kay00:07:38

Make a class per component or use qualifiers. Those are your options

jatkin00:07:57

Right. Saw that. The problem is that I have an unknown number of possibilities that I’d like to configure at runtime. If I’m not misunderstanding i need to set this up at compile time.

tony.kay00:07:28

you can generate factories on the fly

tony.kay00:07:38

the code you quoted to me earlier does just that

tony.kay00:07:46

so I’m confused as to what is missing for your use-case

jatkin00:07:23

OO. I thought it was because routers were singletons that worked. (Found that in the old router)

jatkin00:07:11

I tried running it at the repl and was hitting roadblocks. I’ll revisit and see if I was just being stupid.

zilti23:07:00

What could be the reasons when a defsc with a route loads its content fine when accessed directly (going directly to that URL or refreshing the browser), but when routed to "normally" it fails?

lgessler01:07:23

are the loads you need for that route happening in both cases?

holyjak07:07:45

Could you define "fail"? And is this a deferred route? Does the state of the parent component of the router contain the router state in both cases?

zilti07:07:41

It is a deferred route, yes, the page loads fine, but the data to be displayed in the table is missing.

zilti07:07:16

The loading is done with fd/load! in :will-enter

zilti08:07:04

...well, now I broke it completely... sigh