Fork me on GitHub
#fulcro
<
2018-06-11
>
tony.kay04:06:39

Fulcro 2.5.8 is up on Clojars. Fixes a bug in server-side rendering reported by @levitanong, and a websocket bug that where early sends to the server could cause errors while the websocket was establishing. Also fixes a bug where :component could be nil within mutation handlers if the component had no query.

myguidingstar10:06:48

hmm, I can't use qualified keywords for my route params because the fulcro syntax for routing tree use prefix: param/...

myguidingstar10:06:04

;; current fulcro syntax
(r/routing-tree
  (r/make-route :my-screen
    [(r/router-instruction :router [:my-screen :param/x])]))

;; my dream syntax so qualified keywords work
(r/routing-tree
  (r/make-route :my-screen
    [(r/router-instruction :router [:my-screen {:param :qualified/x}])]))

tony.kay14:06:38

yep. The built-in routing is tuned for use with URI-based parameters, which are not qualified. Feel free to write your own. The code for the existing (non-dynamic at least) routing stuff is very little code.

tony.kay15:06:34

The routing tree is a very simple thing I threw together to set idents on more than one router at once…but it is just that: a mechanism to combine setting multiple idents on routers into a single mutation. There’s nothing magic about it unless you want to integrate with code splitting.

eric.shao19:06:31

(defcard-fulcro repayment-state-card
                Root
                {}
                {:inspect-data true
                 :fulcro       {:started-callback
                                (fn [app] (df/load app :foo loan-comp/RepaymentItem {:target (df/append-to *[:REPAYMENT-LIST :singleton :repayments]*)}))}

                 })
I used initial-state to give this position a [], Why this position is still nil so that it can’t be appended. Which happen first, initialState or :started-callback?🙂

eric.shao19:06:54

Either initial-state or started-callback?

wilkerlucio19:06:39

@eric.shao initialState will happen first since it goes at app initialization process, right after that your started-callback will be triggered

eric.shao19:06:50

@wilkerlucio I want to load one {} or a [] to append to the initial-state’s list. There are three situations 1: when I don’t provide fulcro-started-callback, the initial-state’s list [] will show correctly. 2:when i df/load a {} it will fail 3:when i df/load a [{}] it will replace the initial-state’s list (instead of appending to that list) and report

for append must target an app-state vector.
(vector? (get-in state data-path))

eric.shao19:06:21

If the initialState happen first, there should be a [] , and it should be appended instead of replace, right? where is the problem?

levitanong20:06:29

@tony.kay does fulcro support running the app “server-side”? Like, creating a fulcro client, running loads, fulcro networking etc…

tony.kay20:06:50

@levitanong no, but if you follow the patterns in the book all of your mutations will have helpers that can be used to simulate just about any action on the server

tony.kay20:06:09

the HTML5 routing sections talk about this

tony.kay20:06:33

Not sure why you’d want to “run it”…how would you interact with it? Once it’s on the initial screen events are needed to “drive it” to some state

tony.kay20:06:08

and since those “events” are always mutations, simply having those in functional form on the server gives you exactly what you want without any “machinery” in the way

levitanong20:06:36

@tony.kay The use case is when, for example, I need a set of itineraries that tell the user how to get from one latlng to another latlng. If I want to SSR, then the html I serve should already have those itineraries out. I was thinking that if, when the server receives such a request, it instantiates an app (a client running on the server, in other words), to perform requests from another server (the server the client-client would talk to)

levitanong20:06:59

if I could do that, it would be easier to reason about

levitanong20:06:07

plus, lots of nice code reuse

tony.kay20:06:45

sounds like a nightmare to me 😜

tony.kay20:06:09

think of all of that machinery that can break and make it “not work”…debugging, setup, testing, devops

tony.kay20:06:26

you already have the functions on the server to return the data, right?

levitanong20:06:35

the problem is, i don’t.

levitanong20:06:48

the server is primarily a webserver. it doesn’t hold the routing, reverse geocoding, etc…

levitanong20:06:01

(by routing i mean in the google-maps way)

tony.kay20:06:04

ok, so, do your users have to be logged in for this?

levitanong20:06:21

currently no. that’s something that’s definitely in the roadmap though.

tony.kay20:06:27

so don’t SSR

tony.kay20:06:32

not the logged-in pages

tony.kay20:06:57

you’re creating work that simply isn’t going to do you much good

levitanong20:06:01

the login stuff is primarily for preferences, so it’s safe to be rendering the stuff

tony.kay20:06:03

and is going to cause a lot of pain

levitanong20:06:16

the motivation for SSR right now is SEO

tony.kay20:06:29

right, and SEO someone’s specific iternerary???

tony.kay20:06:32

that’s silly 🙂

levitanong20:06:59

the itinerary thing is a simplification 😛

tony.kay20:06:18

Your best bet is really to use CLJC for the client mutations, and do the manipulation of data and only data on the server, then render that with SSR

tony.kay20:06:50

“loads” will have to be implemented to do JVM-based networking if you need to hit other servers to satisfy external data needs

tony.kay20:06:20

but the merge functions in Fulcro will work on the server against state maps, so you can get very close to complete sharing of code

tony.kay20:06:51

it is the advantage of pure rendering to begin with

tony.kay20:06:16

(and the single language on full stack)

tony.kay20:06:22

you’re already getting a lot 🙂

levitanong20:06:58

i do suppose the statefulness of the instantiated app would be overly complex

tony.kay20:06:37

and maintaining two ways of dealing with networking…along with the alternate paths wthin Fulcro itself…it’d be a constant source of inconsistencies andbugs

levitanong20:06:21

the thing that actually pushed me over into asking about instantiating an app though, is in the case of invented-root-level-keyword loads.

tony.kay20:06:23

and at the end of all of that probably wouldn’t save you hardly any coding, since you could have already used CLJC shared code to “run arbitrary” operations server-side

levitanong20:06:52

because client-side, i have something like :placename->location and :location->placename. Both touch “places”, but fill up complementary deficiencies in information

levitanong20:06:37

as opposed to using an ident

levitanong20:06:13

and i wasn’t sure how to marry those invented keywords with the merge function

levitanong20:06:13

or maybe i know how to make it work, but it’s just one kind of mess that I wanted to cover up with a different kind of mess. 😜

tony.kay20:06:44

you know about merge-component?

tony.kay20:06:56

all of the auto-normalization is available on the server

tony.kay20:06:10

and integrate-ident…both in primitives.

levitanong20:06:22

oh, those seem new!

tony.kay20:06:22

work on a normalized state map

tony.kay20:06:29

nope…been there for a long time 🙂

tony.kay20:06:26

the ! form of them are mutations, and the non-`!` form can be used on server or inside of mutations

levitanong20:06:45

got it! thanks @tony.kay 😄

tony.kay20:06:56

cool…yeah. Instead of a load, you just merge