From 5ac123dc4b1a3979b9b5d5ac5c25761d3a68ee7e Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 21 Sep 2022 09:29:03 +0200 Subject: [PATCH] :sparkles: Improve error handling on onboarding questions form --- frontend/src/app/main/store.cljs | 4 ++ .../src/app/main/ui/onboarding/questions.cljs | 54 ++++++++++++++----- frontend/src/app/util/dom.cljs | 5 ++ 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/frontend/src/app/main/store.cljs b/frontend/src/app/main/store.cljs index c8d274c1c..49f1e752a 100644 --- a/frontend/src/app/main/store.cljs +++ b/frontend/src/app/main/store.cljs @@ -16,6 +16,10 @@ (defonce loader (l/atom false)) (defonce on-error (l/atom identity)) +(defmethod ptk/resolve :default + [type data] + (ptk/data-event type data)) + (defonce state (ptk/store {:resolve ptk/resolve :on-error (fn [e] (@on-error e))})) diff --git a/frontend/src/app/main/ui/onboarding/questions.cljs b/frontend/src/app/main/ui/onboarding/questions.cljs index 7a70b8660..266d0d4bc 100644 --- a/frontend/src/app/main/ui/onboarding/questions.cljs +++ b/frontend/src/app/main/ui/onboarding/questions.cljs @@ -7,35 +7,61 @@ (ns app.main.ui.onboarding.questions "External form for onboarding questions." (:require + [app.main.data.events :as ev] [app.main.data.users :as du] [app.main.store :as st] [app.util.dom :as dom] - [goog.events :as ev] + [goog.events :as gev] + [potok.core :as ptk] [promesa.core :as p] [rumext.alpha :as mf])) (defn load-arengu-sdk [container-ref email form-id] - (letfn [(on-init [] - (when-let [container (mf/ref-val container-ref)] + (letfn [(on-arengu-loaded [resolve reject] + (let [container (mf/ref-val container-ref)] (-> (.embed js/ArenguForms form-id container) (p/then (fn [form] - (.setHiddenField ^js form "email" email)))))) + (.setHiddenField ^js form "email" email) + (st/emit! (ptk/event ::ev/event {::ev/name "arengu-form-load-success" + ::ev/origin "onboarding-questions" + ::ev/type "fact"})) + (resolve))) + (p/catch reject)))) - (on-submit-success [_event] + (mark-as-answered [] (st/emit! (du/mark-questions-as-answered))) + + (initialize [cleaners resolve reject] + (let [script (dom/create-element "script") + head (unchecked-get js/document "head") + lkey1 (gev/listen js/document "af-submitForm-success" mark-as-answered) + lkey2 (gev/listen js/document "af-getForm-error" reject)] + + (unchecked-set script "src" "https://sdk.arengu.com/forms.js") + (unchecked-set script "onload" (partial on-arengu-loaded resolve reject)) + (dom/append-child! head script) + + (swap! cleaners conj + #(do (gev/unlistenByKey lkey1) + (gev/unlistenByKey lkey2))) + + (swap! cleaners conj + #(dom/remove-child! head script)))) + + (on-error [_] + (st/emit! (ptk/event ::ev/event {::ev/name "arengu-form-load-error" + ::ev/origin "onboarding-questions" + ::ev/type "fact"})) + (mark-as-answered)) ] - (let [script (dom/create-element "script") - head (unchecked-get js/document "head") - lkey1 (ev/listen js/document "af-submitForm-success" on-submit-success)] - - (unchecked-set script "src" "https://sdk.arengu.com/forms.js") - (unchecked-set script "onload" on-init) - (dom/append-child! head script) - + (let [cleaners (atom #{})] + (-> (p/create (partial initialize cleaners)) + (p/timeout 5000) + (p/catch on-error)) (fn [] - (ev/unlistenByKey lkey1))))) + (run! (fn [clean-fn] (clean-fn)) @cleaners))))) (mf/defc questions [{:keys [profile form-id]}] diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index 56d8c68a8..32be72f0b 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -264,6 +264,11 @@ (when (some? el) (.appendChild ^js el child))) +(defn remove-child! + [^js el child] + (when (some? el) + (.removeChild ^js el child))) + (defn get-first-child [^js el] (when (some? el)