Fork me on GitHub
#fulcro
<
2018-01-05
>
tony.kay03:01:38

http://book.fulcrologic.com updated with a few more fixes and clarifications. the i18n demos work correctly now

myguidingstar04:01:59

how do I add custom headers to all http requests?

myguidingstar04:01:30

I'm trying to attach csrf tokens

tony.kay04:01:32

you have to create your own networking

tony.kay04:01:46

it isn’t too hard…just duplicate what’s in network.cljc

tony.kay04:01:38

It’s on the TODO list to add a hook to let you rewrite the requests before they’re sent

myguidingstar04:01:26

also, I'm trying to implemet (:column {:with "params"}) in fulcro-sql but don't know where to start

myguidingstar04:01:44

any suggestion?

tony.kay04:01:06

first, what should that do to the query?

tony.kay04:01:52

something or nothing?

tony.kay04:01:00

(to the SQL)

myguidingstar04:01:36

something: filtering (where statements)

myguidingstar04:01:03

but the nothing case is interesting

tony.kay04:01:04

isn’t there already filtering support?

myguidingstar04:01:26

If I understand it correctly, filtering is not part of om.next query

tony.kay04:01:30

The idea is that you send some top-level params with the overall query, then transform them to the general filtering form and then run the query.

tony.kay04:01:13

I see you’d like to embed these as parameters at the keyword level in the graph query itself (not at the top)?

tony.kay04:01:23

Here are the cases I was thinking of: 1. You need to constrain all incoming graph queries. E.g. your schema uses a deleted flag, and you want that to be in the WHERE as deleted = false 2. You have some specific use-case on the client, but the graph query is already on the components. Use (load this :x Comp {:params filtering-params), and then have the server grab the top-level params and use those to convert to the filter general form

myguidingstar04:01:01

I may misunderstand the easy filters. Can you give an example inside a (load ...)?

tony.kay04:01:12

The idea was that for some specific query it was likely you had some combination of filters that you were thinking about at some specific client call site

tony.kay04:01:15

(load this :people Person {:params {:filters {:person/name {:eq "Joe"}}}})

tony.kay04:01:19

then on server:

tony.kay04:01:12

(defquery-root :people
  (value [env {:keys [filters]}] 
    (let [query-filters (sql/filter-params->filters filters)
          ...

myguidingstar04:01:15

let's get back to the "nothing" case mentioned

tony.kay04:01:40

So, for that, fulcro-sql just needs a pre-processing step on the query to strip params

myguidingstar04:01:48

eg: (:column {:unit "cm"})

tony.kay04:01:22

Unforunately I was trying to keep it from having a dep on Fulcro itself….the AST stuff there would make it very easy.

tony.kay04:01:16

One thing that we could do is copy the AST code from Fulcro into fulcro-sql.util

tony.kay04:01:39

then it’s just a simple conversion to an AST, nil out all params recursively, and convert it back to a query

tony.kay04:01:58

it would be a good exercise to see how hard it is to convert fulcro-sql to use pathom

tony.kay04:01:53

it also isn’t that hard with clojure.walk…if you find a list, convert it to it’s first

myguidingstar04:01:05

incoming query -> ast -> collect pairs of [column with params, path to it] while return params stripped-> query non-param version against sql db -> result -> apply some transformations to collected paths

tony.kay04:01:02

not sure what you mean by steps 3 and last

tony.kay04:01:18

(collected stuff?)

tony.kay04:01:59

query -> clojure.walk convert list? elements to (first ele) (this is a query without params) -> run query -> result

tony.kay04:01:20

embed that inside of run-query

tony.kay04:01:34

OH…collected

tony.kay04:01:38

you mean collect up filters

myguidingstar04:01:06

I mean we not only remove params from queries but also save the paths to them for post-processing later

tony.kay04:01:03

what post-processing?

tony.kay04:01:19

so, that is external to fulcro-sql I think

myguidingstar04:01:54

transformations based on params, say convert query result to specicied units (cm)

myguidingstar04:01:05

right, it's external

tony.kay04:01:06

I’d be open to having you be able to use a namespaced keyword in parameters on a property as a way of giving filters, but that could be a rather extensive change…and I’m not sure it even makes sense

tony.kay04:01:59

It may turn out that using something like pathom makes a lot more sense in general (directly)…since it lets you define how your query is processed at every step

tony.kay04:01:49

Remember that each join could be a to-one or to-many…your conversion example is doable, but other things won’t make sense without code to evaluate context

myguidingstar04:01:21

cool, I'm still trying to make sense of pathom

tony.kay04:01:27

so, on fulcro-sql itself, you could do an experimental expansion and see how it goes.

tony.kay04:01:00

stripping the incoming params so it doesn’t crash would be a nice start…

tony.kay04:01:23

Adding something that can gather the params that have the key :fulcro-sql/filter and try to make use of that for filters might be interesting as well, but probably as a pre-processing step outside of run-query to start

tony.kay04:01:55

Both of those are pretty trivial to do with just clojure.walk

tony.kay04:01:31

For a general API, there are some hard cases…like where your graph query has the same subquery in two different branches with two different filters…the only way to deal with that would be to support the filter param during the processing of the query in run-query

tony.kay04:01:09

your conversion example is also one that could be quite useful…say we have a multimethod in fulcro-sql where you can register namespaced keywords with conversion routines.

tony.kay04:01:42

then your units example could be done in an extensible way that just involves data in the query

tony.kay05:01:24

A query like this [(:timeout {:fulcro-sql/conversion ::to-ms})]

tony.kay05:01:35

triggers the multimethod on ::to-ms with the value

tony.kay05:01:27

lots of possibilities…I guess a more general approach would be to have the parameters stay in the query, and run the results of the query through some kind of row filter that triggers on the table name, passes in the row and the parameters keyed by column name, and the row filter can return a modified row

tony.kay07:01:44

I pushed 2.1.0-beta1 to clojars. The most significant thing here is that rendering has been refactoring and improved. There are now render modes. It is a beta because, well, it was an invasive change to rendering 🙂 The big wins: - :ui/react-key is no longer needed, ever. - prim/force-root-render! “just works” - You can set the :render-mode to :keyframe (in reconciler-options) and no longer need follow-on reads. This isn’t as optimized, but will be fine (and simpler) for many apps.

tony.kay07:01:43

The devguide has been revamped as a tutorial (much shorter), and content moved into the new book.

tony.kay07:01:14

The website version of the (live) tutorial should work…but I’m still waiting for github to update the published version

roklenarcic10:01:36

@wilkerlucio https://github.com/fulcrologic/fulcro/issues/118 This repro example for the bug also includes repro for fulcro-inspect bug, transactions conducted by clicking the button don't show up in transactions tab of fulcro inspect

wilkerlucio10:01:57

thanks, I'll take a look, can you please open an issue on inspect as well about it?

wilkerlucio12:01:31

I posted a comment, was just a little issue with the transaction

astrashe14:01:50

How did you make the book? I'm really impressed with it, both as documentation but also as an app.

macrobartfast15:01:29

@tony.kay your getting started dev guide, YouTube videos, and the rest are fantastically helpful. Thank you!

macrobartfast15:01:08

the videos are particularly helpful in getting started.

tony.kay19:01:57

@astrashe It's asciidoc, ditaa (asciidoc-diagram), and some embedded HTML. Thanks, I think it's a big improvement over what I was doing before. The examples are all just one Fulcro build that outputs a bunch of mounts to divs on the HTML.

tony.kay19:01:58

The macros for wrapping the examples are here: https://github.com/fulcrologic/fulcro/blob/develop/src/book/book/macros.cljc and the main for the "app" is here: https://github.com/fulcrologic/fulcro/blob/develop/src/book/book/main.cljc Embedding an example was then just literal blocks of asciidoc (and I admit to using JQuery to implement show/hide...since the book itself is just generated raw HTML):

++++
<div class="example" id="example-1"> </div>
<a class="source-toggle" href="javascript:void(0)" onClick="$('.example-1').toggle()">Show/Hide Source</a>
++++

[source,clojure,role="example-1 source"]
----
include::src/book/book/example_1.cljc[]
----

tony.kay19:01:49

Couple of Live Templates in IntelliJ made typing these out as easy as typing the filename.

astrashe19:01:23

It's really impressive. I've been sending it to non-Clojure people, to show them how cool it is.

tony.kay19:01:52

thanks...plenty of examples of docs on the web with live examples, though, aren't there?

astrashe19:01:14

Yeah, but I think the server stuff is pretty cool

tony.kay19:01:29

oh, I see. Yeah, owning the full stack makes that easy too 🙂

tony.kay19:01:53

about the next 100 lines there...isomorphic in both directions is nice...can embed a server on the client or client on server

tony.kay19:01:40

The server namespace includes a simple pre-written server-for-the-client like this, but it just runs happy path code...no error handling. https://github.com/fulcrologic/fulcro/blob/develop/src/main/fulcro/server.cljs#L82 Oh wait...it looks like I did add in error handling to some extent there 😜

tony.kay19:01:06

so then the normal server macros can be used without change

tony.kay19:01:57

@macrobartfast Thanks....I probably need to redo some of the videos now...I just reorganized all of the docs and they probably refer to old stuff...if you could point out anything like that I'd appreciate it.

mss19:01:58

if I’m loading initial data from a server in my started-callback that’s 1) going to exist at the root of the app db and 2) not cleanly associated with just one component, is it an anti-pattern to dispatch a bunch of loads that look like (df/load app :server-keyword-to-load nil {:post-mutation do-some-data-transformation})? as a follow up, how do you handle normalizing server-returned data assuming it comes from multiple different loads and there isn’t an associated component query to use to normalize the data? am I just thinking about either of these questions wrong?

piotrek19:01:03

@tony.kay the new book is amazing! Would it be possible to make the TOC collapsible as a side menu? It would be much easier to navigate (e.g. jumping between topics/sections).

tony.kay19:01:49

@mss A load without a component loads opaque scalar data. It should not be used to load a "database". The entire story relies on queries with idents to normalize. You can use defsc or defui to create component just for their queries for just this case. http://book.fulcrologic.com/#_using_code_defsc_code_for_server_queries

tony.kay19:01:28

@piotrek Not opposed to the idea. If you want to look into asciidoc options and mess with it as a contribution I'm open. I've got other priorities

tony.kay19:01:57

I think toc left would do the left part...collapsing it would just require a bit of jQuery probably...and perhaps a bit more CSS?

piotrek20:01:18

@tony.kay :toc: left works great - I’ve just checked it locally - and it’s really enough, collapsing is not necessary at all. Shall I open a PR with this or would you handle it by yourself? The patch is trivial:

-:toc:
+:toc: left

piotrek20:01:21

I think that with this it is much better experience as you can start reading immediately without scrolling 10 pages (on my laptop) of TOC 🙂

tony.kay20:01:47

@piotrek no PR needed. I’ll try it out. Anyone have comments on the number of TOC levels? It is set at 5, but that seems kind of deep to me perhaps.

tony.kay20:01:44

2 might be more useful…chapters and major sections

tony.kay20:01:41

I’m going to push an update with toc left and 2 levels. That is what I think is most useful. If you’re searching for something that needs the deeper levels you might as well hit CMD-F and just search for it.

maridonkers20:01:20

Structure and Interpretation of Computer Programs has three levels ;-)

tony.kay20:01:44

😄 I’m not that high brow I don’t think

sundarj20:01:19

@tony.kay Practical Typography recommends two, max three levels: https://practicaltypography.com/headings.html

tony.kay20:01:40

with 3 it’s probably nice if you’re seeing the book for the first time or you just want to review what’s in it, but it’s too much for quick nav

tony.kay20:01:47

with 2 it’s quite useful for quick nav

tony.kay20:01:08

Since there seem to be at least 2 of you with opinions…why don’t I push one, let you look, then push the other? Got time for live feedback?

tony.kay20:01:49

2-left is up on http://book.fulcrologic.com for the moment…

sundarj20:01:10

I'm on mobile I'm afraid

maridonkers21:01:17

Agree with two (SICP almost 700 pages)

piotrek21:01:19

Looks good to me @tony.kay

tony.kay21:01:47

ok, anyone want to see 3?

piotrek21:01:07

Let’s see 3 🙂

piotrek21:01:25

I will leave the version with 2 open in another tab

maridonkers21:01:05

Indeed it does look good on desktop and mobile.

piotrek21:01:52

I prefer version with 2 levels. 3 levels means a lot more scrolling and it’s actually easier to try to search on the page then scan the TOC

tony.kay21:01:27

That was my feeling as well

sundarj21:01:41

Practical Typography wins

tony.kay21:01:15

yeah, I had it set on 5 while I was working on it…don’t remember why…early on it was handy, but I never re-evaluated it 🙂

tony.kay21:01:25

ok, 2-left it is

tony.kay21:01:36

website updated