I have problems with with some data types and transit. There are some similar questions in this channel, but I don't understand how to solve it in my case. Here is the example of resolver. I understand that java.time.Instant need own serializer. But BigInteger and BigDecimal are not properly deserialized and are displayed as [TaggedValue f, n
(pc/defresolver foo [env params]
{::pc/output [{:foo [:foo/bint]}]}
{:foo #:foo{:bint (java.math.BigInteger. "0")
:ts (java.sql.Timestamp. 0)
:dt (java.util.Date. 0)
; Instant is not transit compatible?
; :inst (.toInstant (java.util.Date. 0))
:int 1
:float 0.1
:bdec (java.math.BigDecimal. 0)}})
In Fulcro inspect
{:foo
{:foo/bint #n 0,
:foo/ts #inst "1970-01-01T00:00:00.000-00:00",
:foo/dt #inst "1970-01-01T00:00:00.000-00:00",
:foo/int 1,
:foo/float 0.1,
:foo/bdec #f 0}}
This is of course just an example, the real data is from postgresql table. All the casting or remapping to make resultset transit friendly makes code ugly. And it is far from it just works.Fulcro inspect is a chrome plugin. What you see there is a side-effect of display, not of real type in transit. BigI and BigD definitely work on the wire…so I think you’re just confusing yourself. The Instant support you want is just to install your own additional type handler in Fulcro’s https://book.fulcrologic.com/#_custom_type_support. You’ll encode that with a new namespaced tag you invent, and whatever data you need (e.g. ms epoch time or whatever). Inspect will show the tag and raw data, but the front/back end will work with the new type.
I just figured out for Instant -> #inst:
(def writer (transit/writer out :json
{:handlers {java.time.Instant
(transit/write-handler "m" #(-> % .toEpochMilli Long/toString) )}}))I just have to insert it into fulcro.
but f is not deserialzed in frontend. bacause it is report rendered as [TaggedValue: f, 32592165.00]
read my response, and the book
I think that I understand for Instant, it works by the book, I just reused m.
(fulcro-transit/install-type-handler!
{:writer {java.time.Instant (transit/write-handler "m" #(-> %
.toEpochMilli
Long/toString))}
:reader {}})
I am confused about BigD which is not decoded on client.RAD has a numeric ns for using Big.js to implement BigDecimal on the client.
Transit jsut sends a tagged value, but if you want to actually use it, you need to support it like that
because js has no BigD or BigI data type.
All Fulcro guarantees is you’ll get the data transmitted in a way that if Fulcro were to send it back, you’d get a correct round trip. If you want to manipulate the data, then you have to make sure you have functions that can correctly do so, while keeping it in a format that transit can understand.
so clj backend will write "f" tagged when BigDecimal, but I have to install own reader in cljs to display it as number. com.fulcrologic.rad.type-support.decimal/numeric is support lib? Currently I am solving render with column-formatter, but I don't like it, I would like that it just works.
(defn- cell-fmt-decimal [report-instance ^js value row-props attribute]
(when value
(.-rep value)))
But I can't solve it without formatters, bacause f 22 will be 22M 🙂Yes, numeric is the support lib.
These are the built-in formatters:
(defn built-in-formatter [type style]
(get-in
{:string {:default (fn [_ value] value)}
:instant {:default (fn [_ value] (dt/inst->human-readable-date value))
:short-timestamp (fn [_ value] (dt/tformat "MMM d, h:mma" value))
:timestamp (fn [_ value] (dt/tformat "MMM d, yyyy h:mma" value))
:date (fn [_ value] (dt/tformat "MMM d, yyyy" value))
:month-day (fn [_ value] (dt/tformat "MMM d" value))
:time (fn [_ value] (dt/tformat "h:mma" value))}
:keyword {:default (fn [_ value _ column-attribute]
(if-let [labels (::attr/enumerated-labels column-attribute)]
(labels value)
(some-> value (name) str/capitalize)))}
:enum {:default (fn [_ value _ column-attribute]
(if-let [labels (::attr/enumerated-labels column-attribute)]
(labels value) (str value)))}
:int {:default (fn [_ value] (str value))}
:decimal {:default (fn [_ value] (math/numeric->str value))
:currency (fn [_ value] (math/numeric->str (math/round value 2)))
:percentage (fn [_ value] (math/numeric->percent-str value))
:USD (fn [_ value] (math/numeric->currency-str value))}
:boolean {:default (fn [_ value] (if value (tr "true") (tr "false")))}}
[type style]))
(in RAD report.cljc)
if you’re using RAD. If you are NOT using RAD, then look at those for examples
I see, wow! there is also install-formatter! Really great. I think that I understand how you designed the RAD. Instead of hacking transit and risk to corrupt the data, you have created an extensible rendering based on attributes. This is the reason why you are encouraging custom types in transit not coercing as I did with Instant. I got a gut feeling that I am doing something fishy. I am again very impressed.
Great, yeah. I figured you were missing something. In my own systems, I've got things installed so that I can use cljc Java time on The wire and in reports or forms. That way I can use local date, zoned date time, etc
Your system must be another layer of wonders.