Repository: penpot/penpot
File: frontend/src/app/main/data/workspace/variants.cljs (ClojureScript)

Code before:
        (when (not= val (dm/get-in component [:variant-properties pos :value]))
          (let [current-page-objects   (dsh/lookup-page-objects state)
                variant-id             (:variant-id component)
                component-file-data    (dm/get-in libraries [(:component-file shape) :data])
                component-page-objects (-> (dsh/get-page component-file-data (:main-instance-page component))
                                           (get :objects))
                variant-comps          (cfv/find-variant-components component-file-data component-page-objects variant-id)
                target-props           (-> (:variant-properties component)
                                           (update pos assoc :value val))
                valid-comps            (->> variant-comps
                                            (remove #(= (:id %) component-id))
                                            (filter #(= (dm/get-in % [:variant-properties pos :value]) val))
                                            (reverse))
                nearest-comp           (apply min-key #(ctv/distance target-props (:variant-properties %)) valid-comps)
                shape-parents          (cfh/get-parents-with-self current-page-objects (:parent-id shape))
                nearest-comp-children  (cfh/get-children-with-self component-page-objects (:main-instance-id nearest-comp))
                comps-nesting-loop?    (seq? (cfh/components-nesting-loop? nearest-comp-children shape-parents))

                {:keys [on-error]
                 :or {on-error rx/throw}} (meta params)]

            ;; If there is no nearest-comp, do nothing
            (when nearest-comp
              (if comps-nesting-loop?
                (do
                  (on-error)
                  (rx/empty))
                (rx/of (dwl/component-swap shape (:component-file shape) (:id nearest-comp) true))))))))))

(defn variants-switch
  "Switch each shape (that must be a variant copy head) for the closest one with the property value passed as parameter"
  [{:keys [shapes] :as params}]
  (ptk/reify ::variants-switch
    ptk/WatchEvent
    (watch [_ _ _]
      (let [ids (into (d/ordered-set) (map :id shapes))
            undo-id (js/Symbol)]
        (rx/concat
         (rx/of (dwu/start-undo-transaction undo-id))
         (rx/from (map  #(variant-switch % params) shapes))
         (rx/of (dwu/commit-undo-transaction undo-id)
                (dws/select-shapes ids)))))))



Review comment (suggestion):
The main idea behind this pattern is `on-error` should return a stream of events, so here yo just can call on-error.


Code after:
        (when (not= val (dm/get-in component [:variant-properties pos :value]))
          (let [current-page-objects   (dsh/lookup-page-objects state)
                variant-id             (:variant-id component)
                component-file-data    (dm/get-in libraries [(:component-file shape) :data])
                component-page-objects (-> (dsh/get-page component-file-data (:main-instance-page component))
                                           (get :objects))
                variant-comps          (cfv/find-variant-components component-file-data component-page-objects variant-id)
                target-props           (-> (:variant-properties component)
                                           (update pos assoc :value val))
                valid-comps            (->> variant-comps
                                            (remove #(= (:id %) component-id))
                                            (filter #(= (dm/get-in % [:variant-properties pos :value]) val))
                                            (reverse))
                nearest-comp           (apply min-key #(ctv/distance target-props (:variant-properties %)) valid-comps)
                shape-parents          (cfh/get-parents-with-self current-page-objects (:parent-id shape))
                nearest-comp-children  (cfh/get-children-with-self component-page-objects (:main-instance-id nearest-comp))
                comps-nesting-loop?    (seq? (cfh/components-nesting-loop? nearest-comp-children shape-parents))

                {:keys [on-error]
                 :or {on-error rx/throw}} (meta params)]

            ;; If there is no nearest-comp, do nothing
            (when nearest-comp
              (if comps-nesting-loop?
                (do
                  (on-error)
                  (rx/empty))
                (rx/of (dwl/component-swap shape (:component-file shape) (:id nearest-comp) true))))))))))

(defn variants-switch
  "Switch each shape (that must be a variant copy head) for the closest one with the property value passed as parameter"
  [{:keys [shapes] :as params}]
  (ptk/reify ::variants-switch
    ptk/WatchEvent
    (watch [_ _ _]
      (let [ids (into (d/ordered-set) d/xf:map-id shapes)
            undo-id (js/Symbol)]
        (rx/concat
         (rx/of (dwu/start-undo-transaction undo-id))
         (->> (rx/from shapes)
              (rx/map #(variant-switch % params)))
         (rx/of (dwu/commit-undo-transaction undo-id)
                (dws/select-shapes ids)))))))