re-frame

https://github.com/Day8/re-frame/blob/master/docs/README.md https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md
Racheal 2020-10-21T08:58:18.190700Z

Hey, I am having an issue with calling a function in a macros. I have this macro in an utils/vents.clj file

(defmacro reg-event [name kw & opt-map-of-kw]
  `(re-frame/reg-event-db
    ~name
    (fn [db# [_ value#]]
       (merge db#
              {~kw value#}
              (get-map-opt-kw db# value# ~@opt-map-of-kw)))))
I have the get-map-opt-kw in an utils/events.cljs file and used the macro in a different event
(ns quagga.components.header.events
  (:require-macros [quagga.utils.events :as utils-events])
  (:require [clojure.string :refer [blank?]]
            [re-frame.core :as re-frame]
            [day8.re-frame.http-fx]
            [ajax.core :as ajax]
            [chimera.string :refer [substring?]]
            [quagga.utils :refer [label-colors get-project-owner]]
            [quagga.utils.specs.project :refer [check-spec-interceptor]]))

(utils-events/reg-event ::successul-user-profile-response :user-profile)
(utils-events/reg-event ::failed-user-profile-response  :failed-user)
(utils-events/reg-event ::failed-projects-response :failed-projects)
(utils-events/reg-event ::failed-organizations-response :failed-organizations)

(defn filter-string [{:keys [db event-val]}]
  (filter #(substring? event-val
                       (:project-name %)
                       :case-sensitive? false)
          (:nav-bar-projects db)))

(utils-events/reg-event ::filter-nav-projects
                        :project-search-string
                        {:nav-bar-filtered-organizations filter-string})
this is the error I get when I do this. Kindly asking for help to debug this

lukas.rychtecky 2020-10-21T09:03:05.191Z

I am not sure, but you may need to move get-map-opt-kw to clj file or at least to cljc .

Racheal 2020-10-21T09:08:57.191200Z

@lukas.rychtecky that still results to the same error

lukas.rychtecky 2020-10-21T09:11:30.191500Z

Where is a definition of get-map-opt-kw? When you expand the macro, what is the result?

Racheal 2020-10-21T09:18:42.191700Z

this is how it looks like

(defn get-map-opt-kw
  [db event-val opt-map-of-kw]
  (reduce (fn [coll [key value]]
            (let [is-fn? (fn? value)]
              (assoc coll key (if is-fn?
                                (value {:db db :event-val event-val})
                                value))))
          {} opt-map-of-kw))

p-himik 2020-10-21T09:18:59.191900Z

It is trying to find a CLJS function quagga.utils.events/get-map-opt-kw. Do you have a CLJS/CLJC file with that namespace and that function?

Racheal 2020-10-21T09:22:40.192100Z

Yes I do

Racheal 2020-10-21T09:23:18.192300Z

I have that function in a cljs file with quagga.utils.events path

Racheal 2020-10-21T09:23:42.192500Z

should i add that namespace to the clj file that contains the macros?

p-himik 2020-10-21T09:24:23.192700Z

No, it should work just as is. But you can try putting [quagga.utils.events] in the :require list in quagga.components.header.events.

Racheal 2020-10-21T09:24:47.192900Z

cool, let me try that

Racheal 2020-10-21T11:49:00.193100Z

thanks all for your suggestions, adding the namespace in the require list worked

Endre Bakken Stovner 2020-10-21T17:36:52.194600Z

Is it okay to do rf/dispatch! in an :on-change in a text field or is that wasteful?

p-himik 2020-10-21T17:39:16.195Z

You probably mean dispatch without the !. It depends. I don't think it's "wasteful" in any sense, but if you derive the value of the text field from a sub that feeds off of that change, you may have some input issues if you type fast enough. https://day8.github.io/re-frame/FAQs/laggy-input/

Endre Bakken Stovner 2020-10-21T17:40:38.195300Z

Thanks. I'll try. I'm just playing around with re-frame, trying to create something like https://rubular.com/

Endre Bakken Stovner 2020-10-21T17:40:46.195600Z

And yes, without the !

Endre Bakken Stovner 2020-10-21T17:42:11.195800Z

It seems like I'll find a solution in re-com if I run into any problems.

Endre Bakken Stovner 2020-10-21T18:28:37.198200Z

I have two different reg-event-dbs: :fields/path and :fields/structure. I want to create a third thing computed from these. I've tried to do so with a subscription:

(rf/reg-event-db
  :fields/structure
  (fn [db [_ structure]]
    (assoc db :structure structure)))

(rf/reg-event-db
  :fields/path
  (fn [db [_ path]]
    (assoc db :path path)))

(rf/reg-sub
 :result
 
 :<- [:fields/path]
 :<- [:fields/structure]

  (fn [[fields structure]]
    (js/console.log (str "Hi from reg-sub: " fields structure))))
The latter subscription never triggers. What am I misunderstanding?

p-himik 2020-10-21T18:29:44.198300Z

The :<- sugar only works for subscriptions without parameters.

p-himik 2020-10-21T18:30:11.198500Z

Since you have to pass structure and path to the dependencies, you will have to use the desugared version of the signal subs.

p-himik 2020-10-21T18:30:23.198700Z

Consult the docstring of reg-sub for more details.

Endre Bakken Stovner 2020-10-21T18:32:54.199500Z

But this example has parametrized subs, no? https://github.com/day8/re-frame/blob/master/docs/subscriptions.md#syntactic-sugar

p-himik 2020-10-21T18:33:21.199700Z

There are three code blocks on that page. To which one do you refer as the example?

Endre Bakken Stovner 2020-10-21T18:33:46.199900Z

The very last. I tried to link to the exact paragraph

p-himik 2020-10-21T18:34:13.200100Z

I should correct myself - the :<- sugar can accept subs with parameters, but those parameters have to be static, just like 2 in [:b 2].

p-himik 2020-10-21T18:34:51.200300Z

Right, the "Syntactic Sugar" section shows you the sugared version. The :a and :b subs don't accept any parameters from the sub that uses them.

p-himik 2020-10-21T18:35:16.200500Z

You will have to use the Layer 3 sub variant from the second code block.

p-himik 2020-10-21T18:35:57.200700Z

Oh wait, hold on. I have totally misread your original code!

p-himik 2020-10-21T18:36:15.200900Z

You're trying to make a sub depend on events. That has never worked, at least not that way.

p-himik 2020-10-21T18:36:25.201200Z

Subs can receive values from another subs and from app-db, that's it.

p-himik 2020-10-21T18:36:39.201400Z

If you want a sub to change its value in response to some event, that event will have to change app-db.

Endre Bakken Stovner 2020-10-21T18:36:59.201600Z

But I have two reg-event-dbs: those change the app-db, right?

Endre Bakken Stovner 2020-10-21T18:37:10.201800Z

Sorry, I am a confused n00b

p-himik 2020-10-21T18:38:21.202Z

In the examples at the link above, both :a and :b are subs, not events. Yes, those do change app-db. You will have to create subs that extract :structure and :path and use those subs as signals to the :result sub. But if your :result sub doesn't do any heavy computations, you can just avoid the signal subs altogether and just get the values from app-db directly.

Endre Bakken Stovner 2020-10-21T18:39:05.202200Z

Okay. Thanks for your help, I truly appreciate it :thumbsup:

p-himik 2020-10-21T18:39:46.202400Z

And the signature of the :result sub function has to be [[fields structure] _], not [[fields structure]]. Sub functions always accept two arguments, even if the sub itself is never used with any parameters.

p-himik 2020-10-21T18:39:49.202600Z

NP

Endre Bakken Stovner 2020-10-21T18:55:16.206500Z

I have the following code with a subscription that depends on two subscriptions. The console.log never triggers even though I change the :`fields/path` and :fields/structure

(rf/reg-event-db
  :fields/path
  (fn [db [_ path]]
    (assoc db :path path)))

(rf/reg-event-db
  :fields/structure
  (fn [db [_ structure]]
    (assoc db :structure structure)))

(rf/reg-event-db
  :fields/path
  (fn [db [_ path]]
    (assoc db :path path)))

(rf/reg-sub
 :fields/path
 (fn [db _]
 ;  (js/console.log (str "Hello from sub: " (:path db)))
   (:path db)))

(rf/reg-sub
 :fields/structure
 ;(js/console.log (str "Hello from sub: " (:structure db)))
 (fn [db _]
   (:structure db)))

(rf/reg-sub
 :result
 (fn [query-v]
   (js/console.log "Are we ever here?")
   [(rf/subscribe [:fields/path] (rf/subscribe [:fields/structure]))])
 (fn [[fields structure] query-v]
   (js/console.log (str "Hi from reg-sub: " fields structure))
   "mock derived output"))
Can anyone see what is wrong?

p-himik 2020-10-21T18:58:33.206700Z

The error is in this line:

[(rf/subscribe [:fields/path] (rf/subscribe [:fields/structure]))]
Do you see it?

Endre Bakken Stovner 2020-10-21T18:59:06.206900Z

Now I am embarrassed XD

p-himik 2020-10-21T18:59:18.207100Z

Happens. :)

p-himik 2020-10-21T18:59:48.207300Z

Placing signal subs on their own line would help. Also, you can turn that vector into a map and destructure it accordingly.

Endre Bakken Stovner 2020-10-21T19:01:22.207500Z

I think a syntax checker ("wrong number of args") would have caught it. I should set one up.

Endre Bakken Stovner 2020-10-21T19:03:10.207700Z

I fixed that mistake, but still I get no console.log output...

p-himik 2020-10-21T19:03:45.207900Z

Are you actually using :result in some view that gets mounted?

Endre Bakken Stovner 2020-10-21T19:04:16.208100Z

Nope. Are subscriptions lazy? I'll try doing that.

p-himik 2020-10-21T19:04:36.208300Z

Yes, subs are not evaluated if not used.

p-himik 2020-10-21T19:04:58.208500Z

Not the same as lazy per se - more like defining a function and never using it.

Endre Bakken Stovner 2020-10-21T19:06:35.208700Z

Yes, I used the wrong term

Endre Bakken Stovner 2020-10-21T19:07:34.208900Z

How do I use that subscription in hiccup? (rf/<???> :result)

p-himik 2020-10-21T19:08:57.209100Z

It seems like you really should go through the incredibly well-written re-frame documentation and FAQ. It will answer 99% of your questions and in a better fashion than I will, trust me.

Endre Bakken Stovner 2020-10-21T19:10:07.209400Z

I wasn't asking you specifically. Anyways, I found it out

Endre Bakken Stovner 2020-10-21T19:10:19.209600Z

[:div [:p @(rf/subscribe [:result])]]

Endre Bakken Stovner 2020-10-21T19:12:03.209800Z

I am sure the docs are great, but I was too tired to read. I just wanted to play around with code. Now it all works - thanks again. I'll read the docs tomorrow when I am refreshed.