Skip to content

Instantly share code, notes, and snippets.

View holyjak's full-sized avatar
💓
Loving Clojure

Jakub Holý holyjak

💓
Loving Clojure
View GitHub Profile
@holyjak
holyjak / advanced-minimalist-fulcro-tutorial.adoc
Last active September 17, 2021 21:48
Advanced Minimalist Fulcro Tutorial, a follow-up to the Minimalist Fulcro Tutorial

TODO

  • form state

    • tmpids and entity creation

  • dynamic routing

  • UISM

  • Union, recursive, dynamic query

  • Returning data from mutation

  • component.raw

Notes from playing with Datomic

Many thanks to Francis Avila (favila) and others.

Enums: idents vs. type/keyword

The on-prem docs recommend to use idents to represent enums though this advice likely dates from before d/pull and attribute+entity predicates.

Ident

(defn stateful-map
"Returns a stateful transducer similar to `clojure.core/map-indexed` that
transforms each item with `(f state <the item>)` where `state` is built by
applying `state-building-fn` to the previous state (starting with `init`) and
the transformed item.
Ex., re-implementing map-indexed:
```clojure
(sequence (stateful-map vector (fn build-state [idx _] (if idx (inc idx) 5))) \"abc\")
; => ([nil \\a] [5 \\b] [6 \\c])
(ns catching-transduce
"See [[catching-transduce]] below"
(:require [clojure.core.async :as a :refer [chan to-chan pipeline-blocking <!!]]))
(defmacro err-or
"If body throws an exception, catch it and return it"
[& forms]
`(try
~@forms
(catch Throwable t# t#)))
@holyjak
holyjak / fulcro-gotchas.adoc
Last active March 3, 2021 01:11
WIP Fulcro Gotchas document

Common misconceptions and pitfalls in Fulcro.

General

You query the client DB, not the server!

A common misconception is that the Root’s :query is used to load! the app data, i.e. that something like Root query → load! → Root props → rendered UI is happening. It is not. What is happening is Root query → client DB → Root props → rendered UI. You can use a query to also load some data from the backend to feed the client DB but this is up to you, has nothing to do with the just described cycle, and does not need to happen. Also, you essentially never load! the Root query. Instead, you load data for distinct UI subtrees, i.e. sub-queries. So these are two orthogonal, independent processes: rendering client data into the UI and feeding the client database.

A component’s query is relative to its parent component, only Root can "see" keys at the root of the client DB*

@holyjak
holyjak / rust_factor_out_tuple_issue.rs
Last active February 16, 2021 19:46
Problem with factoring out common code in Rust
// Read from DB, write data to CSV
extern crate csv;
extern crate oracle;
use std::error::Error;
use std::env;
use oracle::Connection;
use oracle::sql_type::FromSql;
use oracle::row
use serde::ser::{ Serialize };
@holyjak
holyjak / Fulcro-router-wrong-target-issue.md
Last active December 15, 2020 20:29
Description of a problem with UI displaying one target, Router beliving it displays another one.

I am running into an issue with Fulcro 3.4 and RAD 1.0.8 where the UI shows the (non-default) router target in an uninitialized state while the router believes that it is displaying the default target. I still cannot figure out why.

I have three nested routers (along with some other components): RootRouter > OrgRouter > OrgDashboard for org id=nnn > DetailsDisplayRouter with :targets [LatestBillRunList SubscriberList] and the URL .../org/123/subscribers and I expect to see the SubscriberList RAD report - which I do, but it is empty, even though the DB has the data, because the parent router believes it is displaying the other report . This only happens when I go to the URL in the browser, not when I click myself through the app to the state.

So how is it possible that DetailsDisplayRouter believes it is displaying LatestBillRunList while it should, and the UI does, show SubscriberList?!

I understand why the report is empty despite the presence of its data - Fulcro believes it is not showi

@holyjak
holyjak / deps.edn
Last active October 30, 2020 10:55
cryogen deps
;; Put this inside your blog and use the clojure CLI instead of leiningen to run `clojure -X:serve`
{:deps {org.clojure/clojure {:mvn/version "1.10.1"}
ring-server/ring-server {:mvn/version "0.5.0"}
ring/ring-devel {:mvn/version "1.7.1"}
compojure/compojure {:mvn/version "1.6.1"}
#_#_cryogen-core/cryogen-core {:mvn/version "0.3.2"}
cryogen-asciidoc/cryogen-asciidoc {:mvn/version "0.3.2"}
cryogen-flexmark/cryogen-flexmark {:mvn/version "0.1.4"}
cryogen-core/cryogen-core {:git/url "https://github.com/cryogen-project/cryogen-core" :sha "17cdf3837f17b9b921dce09e4638495984e65a2a"}
}
@holyjak
holyjak / troubleshooting 404 in Spring MVC.md
Created October 22, 2020 22:13
WIP - troubleshooting 404 in Spring MVC 4

Spring 4 - 404 troubleshooting

See https://www.baeldung.com/spring-handler-mappings - explains BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping

Debug DispatcherServlet - DispatcherServlet.getHandler

Update: This has now been published at https://blog.jakubholy.net/2020/error-handling-in-fulcro/

I present three ways of detecting, handling, and showing server-side errors: globally and at the component level.

By default, Fulcro considers only non-200 HTTP status as an error. It is up to you to tell it what is an error and how to handle it.

This is somewhat controversial - as Programming with Pure Optimism in the Fulcro Developers Guide explains:

A server should not throw an exception and trigger a need for error handling unless there is a real, non-recoverable situation.