Fork me on GitHub
#fulcro
<
2020-01-29
>
levitanong09:01:11

Hi all, is there an idiomatic way to change the route (to one that isn’t the default) while building the initial state for SSR?

levitanong09:01:34

I’ve tried modifying the ::dr/current-route of the relevant router, but that alone doesn’t seem enough. It appears I need to modify the queries as well, but when i use set-query* I end up with transit errors about the anonymous functions in the metadata.

tony.kay15:01:26

I would initialize the entire app and run it headless, and use the change-route function

tony.kay15:01:48

ah, so functions in the metadata…that may need some work

tony.kay15:01:46

I don’t remember putting functions in the metadata…oh…the components are metadata. I thought I changed that to their kw names in the component registry

tony.kay15:01:59

So, if that is the case, it’s a bug…the fix is to change the dynamic query system to use the component’s key in the registry instead of the component itself…I thought that was aleady done

tony.kay15:01:46

@U0BR5D7A6 Yeah, line 829 in components.cljc…it is still doing it the old way 😞

tony.kay15:01:14

it isn’t that hard to fix…basically anywhere the component bit is used in the metadata needs to change to using the component registry key (which is a keyword)

tony.kay15:01:01

An alternative is to do this: 1. Do NOT send initial state to the client. 2. Make an “initialize based on route” function 3. Render that on the server 4. Start the app and initialize normal state on the client, but DO NOT mount it yet. 5. Run (2) on the client 6. Mount the client with hydrate Then no initial state serialization is required.

tony.kay15:01:26

I’ll open an issue on dyn queries

👍 1
tony.kay15:01:10

@U0CL8APJ5 you were looking for a Fulcro task, I think…any interest in this? https://github.com/fulcrologic/fulcro/issues/367

davewo15:01:01

yes, I am interested!

tony.kay15:01:14

great, hit me up if you need help understanding it…it really is just finding all the spots and changing the code to use keywords

tony.kay15:01:44

and testing it all, of course…but any program that uses things like dynamic routers should fail pretty miserably if this is broken

levitanong19:01:36

Thanks guys! 😅

thosmos20:01:57

my fulcro-inspect chrome extension just suddenly stopped loading with no significant change in my project that I can figure out. Any tips for how to troubleshoot why it’s not loading? I deleted .cp-cache .shadow-cljs folders and my JS build target folders and restarted the build.

tony.kay20:01:02

I had the same problem yesterday

tony.kay20:01:16

@thosmos does your extension have a “Settings” button?

thosmos20:01:54

my extension doesn’t have a “settings” button, but on the extensions list there is a “Details” button

tony.kay20:01:23

ok, so you did not get the update

tony.kay20:01:36

and the code in Fulcro really didn’t change in a way that should break it…

thosmos20:01:25

is it maybe a problem related to a new version of Chrome?

tony.kay20:01:43

there is a new version of inspect coming out, but we cancelled the release when I saw that problem

tony.kay20:01:53

I’m trying to find out if maybe it got released

tony.kay20:01:13

or, perhaps it is on the client side of Fulcro…in which case rolling back to 3.1.4 or earlier might fix it

thosmos20:01:13

oh, hmm, it says it’s version 1.0.17 from Nov ’19

thosmos20:01:51

I am running fulcro out of a :local/root repo

tony.kay20:01:04

ah, so latest source?

thosmos20:01:10

just weird that it was running fine and then suddenly stopped

tony.kay20:01:16

try checking out an earlier version…

wilkerlucio20:01:17

@tony.kay I canceled the publishing after you reported the issue, its not moving forward

tony.kay20:01:29

I wonder if we broke it in F3 in general though

wilkerlucio20:01:32

@thosmos I heard that happening to a lot of people before, usually re-installing the extension fixes it

tony.kay20:01:34

since the client is in Fulcro now

tony.kay20:01:37

not in inspect

thosmos20:01:13

ok will try re-installing

tony.kay20:01:53

If you can isolate it to either a reinstall or the Fulcro version (latest vs 3.1.4 or so) that would be really helpful as well

wilkerlucio20:01:35

question about dynamic router and sync the URL, how you usually update the URL in response to a change-route? there is a hook for it, or you change the URL first, detect that and then call change-route?

tony.kay20:01:14

DR has nothing at all to do with browsers

thosmos20:01:17

@wilkerlucio I’m using pushy and have it detect the URL change and then call change-route from its handler (which I got from the F3 videos)

tony.kay20:01:20

it can be used in native, etc.

tony.kay20:01:34

it is purely concerned with changing the UI

tony.kay20:01:45

think of it like union router changing an ident…that is all it does

wilkerlucio20:01:46

I understand they don't have a explicit connection, but as an app developer I'm trying to understand the best hooks/places to connect them

tony.kay20:01:05

I have no opinion, because I have not really done it much 🙂…I’m not a fan of bookmarking stateful applications, but I do understand the need.

wilkerlucio20:01:52

@thosmos thanks, I was aiming for that direction, just wanted to confirm if this is a sound approach that people tried before with this

wilkerlucio20:01:15

@tony.kay in my case its important, sharing permalinks is a important feature of the app I'm working on

thosmos20:01:53

(defonce history
  (pushy/pushy
    (fn [p]
      (let [r-segments (vec (rest (str/split p "/")))]
        (timbre/spy :info r-segments)
        (if (seq r-segments)
          (dr/change-route SPA r-segments)
          (dr/change-route SPA ["main"])))) identity))

(defn start! []
  (pushy/start! history))

(defn route-to! [route-str]
  (pushy/set-token! history route-str))

👍 1
thosmos20:01:29

so I use (route-to! "/full/root/path")

thosmos20:01:33

which is straight from Tony’s F3 videos

thosmos20:01:26

no idea about query params to represent stateful options though, as I haven’t crossed that bridge yet

thosmos20:01:20

re-installed inspect extension and restarted Chrome and it’s working again …

thosmos20:01:26

This is the fulcro commit I’m on (3.16)

tony.kay20:01:22

let me know what you find…reinstall may just fix it

thosmos20:01:14

yes it did just fix it

thosmos20:01:33

no clear clue as to any thing that caused it

tony.kay20:01:29

perhaps that is what I was running into when I was testing the new version…I’m using the new version from a local build today and it is working so far

thosmos20:01:10

I have a form component that I’m using both for editing new and existing things. In the various field onChange handlers I have (fs/mark-complete! nil field-key) so when loading the existing thing those get called and it appears dirty even though it’s not. Any advice for how to do that better? I’m thinking of having a :ui/loaded flag in state that prevents the mark-complete! until after it’s loaded? reasonable approach or is there a better way?

tony.kay20:01:15

Follow what I’m doing in forms in RAD.

thosmos20:01:48

ok I’ll take a look (I was thinking I should do that while writing my question 😉 )

tony.kay20:01:11

So, I just refactored RAD to be MUCH simpler (and easier to use in existing apps)

tony.kay20:01:30

The forms stuff is pretty free-standing, and uses the route will-enter and will-leave to do pretty much everything

tony.kay20:01:40

(start a form state machine, etc).

tony.kay20:01:57

and then the route itself is ["route-prefix" :action :id]

tony.kay20:01:25

so ["customer" "create" "ffffff-fff-ffff-ff"] causes the state machine to use tempids on the form

tony.kay20:01:43

and ["customer" "edit" "some-id"] is edit

tony.kay20:01:55

you specify the route prefix as a config on the form component

tony.kay20:01:26

I’m adding relational support today, and there is very limited form field type support so far

tony.kay20:01:40

but it is SUPER fast to get stuff going…I’m pretty excited

🎉 1
thosmos20:01:48

in my case I have a parent comp that is the route target and the child is the form comp with :form-fields I assume it’ll be obvious how to pass through whatever is needed

tony.kay20:01:02

I just added 4 entities in like 10 mins, and other than the ref stuff it all “just works”

tony.kay20:01:35

routing composes

thosmos20:01:37

but maybe if this just works I’ll collapse it into one component. One reason I have 2 layers is the parent loads lookup tables for dropdowns, etc

tony.kay20:01:51

["a" "b" "customer" "create" "tempid"], etc.

thosmos20:01:29

I’ll take a look

tony.kay20:01:57

but RAD isn’t complete enough to use just yet…have not considered passing data from UI separate from what a route might use

thosmos01:01:40

I ran into some weird build errors when looking at RAD, and I have a rough draft milestone to deliver on Fri, so I skipped it for now. I think in the long run merging with RAD, at least in part, is gonna be the way to go. But for now I just need to get something working.

thosmos01:01:38

my problem was an order of operations error. I fixed it by adding the form-state in the post-load-mutation, whereas before I was adding the form-state to the small bit of props I had followed by a full load of the entity, so anything new triggered the dirty flag.

tony.kay02:01:38

oh, I did not mean RAD was usable in an application

tony.kay02:01:49

I meant to look at the state machine and macro as source

fjolne03:01:35

@thosmos I’ve had similar concerns and eventually came to a mental model which worked in all my cases so far, but is pretty opinionated: 1) no field => input is disabled 2) nil-valued field => input is enabled, but the value does not conform to spec, so user needs to enter smth 3) non-nil-valued field => input is enabled and its value validity is determined by spec; then you initialize all the missing values in pre-merge with nils or whatever suits for defaults, and you’re also adding form-state in pre-merge, so there might be nowhere to mark-complete before the load and furthermore you’re in control of everything that said, if your problem is pretty much solved by :ui/loaded and you need to 🚢 soon, i’d go with that. there’s a lot of caveats when implementing forms...

thosmos03:01:27

@tony.kay I understood you meant just to look at the source, but it usually helps me understand it more quickly when I can play with it in the demo

thosmos03:01:50

@UDQ2UEPMY thanks for the tips, adding to my notes for the future!

otwieracz20:01:10

Is there .mobi version of Fulcro Book?

otwieracz20:01:26

Or anything Kindle-friendly?

tony.kay20:01:44

the book is in asciidoc. Download source and use asciidoctor to convert it to whatever you want (assuming there is a plugin)

otwieracz20:01:03

In case I'd do that, should I share it somewhere?

otwieracz20:01:22

Which branch I should use to keep in sync with official book?

tony.kay20:01:41

I don’t tag that repo or anything…just make changes and publish

wilkerlucio20:01:53

@thosmos @tony.kay a simple implementation without adding external deps (using Google Closure Library):

(ns url-routing-with-closure
  (:require [goog.events :as gevents]
            [clojure.string :as str])
  (:import [goog History]))

(defonce page-history
  (doto (History.)
    (.setEnabled true)))

(defn listen-nav-change [f]
  (gevents/listen page-history "navigate" #(f % (.-token %))))

(defn change-route [path]
  (.setToken page-history (str/join "/" path)))

(defn change-route-from-nav-event [app]
  (fn [_ token]
    (dr/change-route app (str/split token "/"))))

👍 3
❤️ 1
wilkerlucio20:01:53

@thosmos @tony.kay a simple implementation without adding external deps (using Google Closure Library):

(ns url-routing-with-closure
  (:require [goog.events :as gevents]
            [clojure.string :as str])
  (:import [goog History]))

(defonce page-history
  (doto (History.)
    (.setEnabled true)))

(defn listen-nav-change [f]
  (gevents/listen page-history "navigate" #(f % (.-token %))))

(defn change-route [path]
  (.setToken page-history (str/join "/" path)))

(defn change-route-from-nav-event [app]
  (fn [_ token]
    (dr/change-route app (str/split token "/"))))

👍 3
❤️ 1
tony.kay20:01:43

I would just add in one more layer: a function that translates the URL to the vector instead of split

tony.kay20:01:47

then you can do route aliasing

tony.kay20:01:57

like / => /main-page

tony.kay20:01:27

also, did you see the new dr/path-to…much better to use that in real code

tony.kay20:01:34

makes things navigable

wilkerlucio20:01:40

I'm using this in combination with path-to

wilkerlucio20:01:51

(change-route (dr/path-to SearchPage))

wilkerlucio20:01:38

yeah, I agree we inprove on the aliasing, that's was just initial URL connection setup, we can go crazy from that 🙂

tony.kay21:01:36

I guess we could add that to Fulcro since ppl inevitably ask about it

❤️ 1
tony.kay21:01:09

you want to make a PR, @wilkerlucio? Some new ns, since we cannot pollute dr with goog.events and History

wilkerlucio21:01:20

I would like to spend more time experimenting with it before adding to the library, find a good API first

❤️ 1
fjolne04:01:53

@wilkerlucio that’s dope, real handy when you need full control, esp so when making Web+React Native in one app (because you can’t just require say accountant in RN, it would crash the app, so you fork it anyway) jfyi smth like accountant also allow for <a href> links to both be routable without page reload and to be a real links in the sense that you can Cmd+Click to open it in a new tab, which might be critical for many apps (as it was for us), but of course that’s just one more fn

👍 1
wilkerlucio21:01:34

hello everyone, as you may know already, the new Fulcro Inspect on electron has a nice new DB Explorer tab, currently its not available on the chrome that's published, the reason is that Google is now making much harder to upload extensions, in the past I could upload and have it updated on the store in about 30 min, now it may take weeks (requires manual checking, because the extensions needs some extensive permissions to work on any page). Given that, the deploys now need to be more careful (if we get a bad version out, it may take a while to get it fixed), also because of that I like to encourage you to build and install the extension yourself, this way we can have more people trying it before the store release, if you wanna do so you can find instructions at https://github.com/fulcrologic/fulcro-inspect#building-chrome-extension. If you do that now you can use the DB Explorer right now! 🙂 Cheers!

👍 9
mss21:01:15

having an issue getting a component to refresh after a load! the component itself queries for a link, and I’m adding a refresh option to the load to update that link. for some reason, although my app db is updated the component doesn’t seem to be re-rendering. any high level ideas about how I might be approaching this incorrectly?

thosmos21:01:01

is your refresh referring to the link or to a key in the parent that contains the link?

mss21:01:28

the link as in the db

mss21:01:37

assuming if the link in the query looks like [:my/thing '_] the options map in my load! would look like {:refresh [:my/thing]}

thosmos21:01:31

does the component have an ident? if so, what if you use that in the refresh?

mss22:01:47

yep, has an ident and that does work. unfortunately quite a few components are changed by the data I’m loading, making sure each has an ident and listing it in the refresh is a little unwieldy

mdhaney22:01:02

Try switching to keyframe renderer, to see if that solves your refresh issues. Then you can optimize it with keyframe2 renderer. http://book.fulcrologic.com/#RenderingOptimizations

🙌 2
mss23:01:57

yep that did the trick. really appreciate the help y’all

👍 1
thosmos00:01:41

yeah I use keyframe2 as well