Fork me on GitHub
#biff
<
2023-11-28
>
Dallas Surewood11:11:53

Is there a legitimate reason to use optional instead of :or for malli specs in Biff? It seems like :or gives you more flexibility with no downside because you can put nil in something, which is what I would expect optional to do. This would be an example of the difference

[:user/foo {:optional true} :string]
[:user/bar [:or :string :nil]]

Martynas Maciulevičius11:11:23

I think there is a difference. In the :or case you will store the nil attribute and in the :optional case you won't need to store it. And I think that nil may even be an invalid attr. I didn't check though. Edit: I validated this and here is the result:

(ns playground.malli
  (:require [malli.core :as m]))

(def schemas
  [[:map [:user/foo {:optional true} :string]]
   [:map [:user/foo [:or :string :nil]]]])

(def values
  [{}
   {:user/foo nil}
   {:user/foo "hi"}])

(for [value values]
  [value (->> schemas
              (map #(m/validate % value)))])
Output:
([{}                (true false)]
 [#:user{:foo nil}  (false true)]
 [#:user{:foo "hi"} (true true)])
So... there is a difference because in the :or case you'd be storing the nil.

ikitommi14:11:04

you can write [:or :string :nil] as [:maybe :string] too

Jacob O'Bryant18:11:33

yeah, basically up to you which you prefer to use; you could even do [:user/foo {:optional true} [:maybe :string]]. I don't have a strong opinion either way; I just kinda like :optional more for some reason

Dallas Surewood13:11:50

Am I missing something about reading after writes in biff? It sounds like biff/submit-tx automatically awaits for the last result. But I am trying to read characters after deleting one and it still contains the missing character unless I read it a little later.

(defn delete-character [{:keys [path-params biff/db] :as ctx}]
  (biff/submit-tx ctx
                  [{:xt/id (parse-uuid (:char-id path-params))
                    :db/op :delete}])
  (character-list (get-characters db)))