Fork me on GitHub
Alex H06:12:31

@currentoor thanks, but no - that's taking a step back for me. It seems like a step backwards that in a generally normalized client app-state like fulcro's, you can't easily deal with multiple representations/selections of the same normalized data

Alex H07:12:26

although I do understand now the intended use case - it's not so much an actual client-side database, but rather just a convenient representation of your current UI state. Anything that isn't part of your current UI state shouldn't really be in fulcro's DB, as you can't easily reshape it, or keep it in sync, etc


fulcro app state should contain anything that is part of your current UI, or where you expect your UI to be, also a good caching mechanism, and because it’s normalized it is kept in sync, you can never have duplication of data as long as it’s correctly normalized


but you’re right it doesn’t support arbitrary queries


you could use pathom resolvers to query it in more sophisticated ways, like the example you suggested, BUT it’ll never be as general as a database query engine


@tony.kay I noticed uism/load doesn’t have an option to specify a custom remote. Is this intentional?


From the docs:

The params of these functions can include most of the normal Fulcro load options (such as marker, which defaults to false for state machines), along with these special values:


just use the options from regular load


got it, thanks


is there an equivalent to devcard's {:inspect-data true} when using workspaces, to show the data in the card itself? Or is my only option to look at the data with Fulcro Inspect?


no inspect data on workspaces by default, we delegate that to Fulcro Inspect


is there something preventing you from using fulcro inspect? (like using other browser than chrome)


no I do use Fulcro inspect, it's just a lot of clicks to drill down into the data structure to view the contents. I find it easier to just see the data on the card directly. But I realized you can achieve that fairly easy anyway by just adding (dom/pre (with-out-str (cljs.pprint/pprint props))) to the card


workspace cards are also extensible, so you can create your own toolbar and give custom interactions from it (like logging to console)


another tip, if you use cmd+click to expand on Inspect, it does a recursive expansion, so avoid having to click too much


oh that's really helpful! thanks


what's the non-mac keyboard equivalent? EDIT: nvm found it, it's alt-click

Andreas Liljeqvist13:12:34

I would like to access the de-normalized form of an ident in a defmutation, any tips?

Andreas Liljeqvist13:12:42

or rather I would like to access the props for a component given an ident


@andreas862 in the env of mutation you have the :ref key, this is the ident of the component who triggered the mutation, so you can get the full data with: (action [{:keys [ref state]}] (get-in @state ref))


@alex340 another way is to delegate that as a load to the server, if you are using pathom having this kind of fetching is easier to do just triggering a new load, that will surely depends on the size of things you are dealing with, I think helps to think as the fulcro db as just a materialization of what your UI is currently doing, you are free to change it by hand, but triggering loads is a convenient way that handles a good portion of the cases

Andreas Liljeqvist13:12:04

@wilkerlucio I would like to get the de-normalized view - Same as the props in render


@andreas862 you can get that with: (fp/db->tree (fp/get-query Component) (get-in @state ref) @state)

Andreas Liljeqvist13:12:37

Thanks, I had already found tree->db. "If only I could have this in reverse". Back to drinking coffee 🙂


Quick question: is there a “LIMIT 500” type of syntax for EQL?


not directly, but you can use parameters to accomplish that, something like: [{(:my-collection {:limit 500}) [:sub :query]}]

Björn Ebbinghaus15:12:25

Bump. Can anyone help me?


Have never seen this problem myself. I would guess you have some kind of conflicting plugin in chrome. Disable all other extensions and see if it works…

Björn Ebbinghaus16:12:15

Hm. Inspecting the Fulcro Inspect Tab gives me this error: Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document. (main.js:3356)

Björn Ebbinghaus16:12:44

And yes, read/write website data is allowed

Björn Ebbinghaus16:12:17


Ignoring unauthorized client request from null

_registerExtension @ shell.js:7789


@wilkerlucio looks like it is accessing the local storage, but not sure why


is this an unmodified output of a template, or have you messed with versions and deps yet?


well, we do use a lot of local storage, what seems weird is why is that getting a denied error, local storage should be accessible


I remember there is some config in chrome that might disallow that, let me check again

Björn Ebbinghaus16:12:01

Ah! It works if I allow "third-party cookies"

Björn Ebbinghaus16:12:09

Yes it works. 😄


something to add to the docs


but we can surely give the user a better error message, @U4VT24ZM3 can you please file an issue on fulcro inspect so I can track it later?

Björn Ebbinghaus16:12:39

@tony.kay @wilkerlucio There should be a fix, where it is not required to allow them. 😕


@U4VT24ZM3 I think we can wrap the calls to localStorage and detect if it fails, the extension can still work without it, but you lose some features like remembering the watchers and snapshots, so I'm thinking we can add a banner or something let the user knows that's happening

Björn Ebbinghaus17:12:30

That would be great. It was a chore to learn fulcro without having a clear view on whats going on.

Andreas Liljeqvist16:12:55

I have a problem with fulcro-inspect. It suddenly stopped working/won't update inspect tab. Browsing in incognito works. Clearing cookies and cache does nothing. This is also using workspaces. Inspecting fulcro-inspect has error "No reader function for tag fulcro/tempid"

Andreas Liljeqvist17:12:33

Might be related but not entirely the same. I have been using tempids for days without problems

Andreas Liljeqvist17:12:02

Also fulcro-inspect won't work again

Andreas Liljeqvist17:12:20

Without using incognito

Andreas Liljeqvist17:12:21

I can do tempid resolution in my incognito browser with no problems

Andreas Liljeqvist17:12:40

Closing all open chrome instances got it back to normal


There is react fragments on fulcro dom?


fragments are not dom specific…just return a vector of nodes


[(dom/div …)
 (dom/div …)]


there is also an explicit helper in primitives, if you want to assign a key


(prim/fragment {:key ...} ...)

Björn Ebbinghaus18:12:40

ARG Now I am getting Invalid join, {:ui/root nil} all over my console, in workspaces Components I wrote yesterday work still fine. Now I can't even get the example working... Removed out, target, deleted all application state in chrome..

(defsc ComponentName
  [this props] ; parameters. Available in body, and in *some* of the options
  ; optional:  { ...options... }
  (dom/div {:className "a" :id "id" :style {:color "red"}}
    (dom/p "Hello")))

(ws/defcard component-name
    {::f.portal/root ui/ComponentName}))


the component for the workspaces must have query and ident, otherwise you can't change it anyway, if you wanna just render you can use a react-card


thats the second time someone get bitten, this needs proper detection as well

Björn Ebbinghaus19:12:09

So I made it worse by reversing everything to the bare minimum... ident is not necessary,

Björn Ebbinghaus19:12:24

{:query []} ist enough


I think @wilkerlucio is saying you must have an ident on a component used like that with workspaces


ident is necessary


unless you use ::f.portal/wrap-root false but that’s a different matter


there is a place "inside" the client where I can put my channels? :shared can hold then or it planned to hold only "values"?


i’m guessing core async channels


what are you using them for?


:shared is meant for immutable data, i don’t think you want to put channels in there


For example, onChange of a text box, I will insert into a channel the new text, it will "do a long process" then mutate the state with the result


Using a async channel I can do that with a slide channel and discard the "excess" of the updates


if we’re talking about a javascript runtime here, that long process will block the main thread regardless of where it happens


you should do that logic in a function that gets called inside the action part of a mutation, then save the result to app state


you could also debounce the onChange function if it’s too much chatter, i’ve done that on color pickers


i don’t think fulcro is meant to be used like the way you’re suggesting


I will try to put some channels on shared. Let's see what happens


you’re welcome to build your software in whatever manner pleases you, and it’ll probably work for most cases simple_smile


just know that what you’re doing is not the recommended architecture and you may run into issues later because of it

👍 4

@U2J4FRT2T Would having an atom in you're utils namespace and just putting those there not work for you're use-case ?


@currentoor @U2J4FRT2T actually shared can hold anything, we had this discussion before, and I for example always use shared for mutable stuff I wanna to be hold with my app

👍 4

@wilkerlucio but the same can be said about app state too, no?


The only issue I foresee with either approach is things like support viewer and history tracking wont work


its different, because app state we try to serialize in many cases, but not shared


Ah I see. Yes you are right, I take back what I said.


Nice. I will put a lot of non-serial things out from db into shared




hey there, i'm trying to follow the websockets demo but i'm a bit lost. the demo and the docs around websockets are still using component while fulcro's been updated to use mount for state management. however, it seems like the fulcro.websockets code is still using component. am i supposed to mix component and mount to do websockets?


(also, this framework has been so much fun to learn about and use so far, and the docs and videos are great - thanks!)


@csapp yeah those docs need to be updated… 😅


yes the websockets component still uses com.stuartsierra.component but that’s easy to use with mount


i’ll make a gist of how i’m doing it right now

❤️ 4

great! this is so helpful. i'll give it a whirl. thanks again 🙂


Also note there are 2 versions of websocket support…use the newer one. See


I think the demo might be out of date there too


yep, that's the one i'm following. thank you!