Fork me on GitHub
#re-frame
<
2020-10-21
>
Racheal08:10:18

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.rychtecky09:10:05

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

Racheal09:10:57

@U6HHQ05GB that still results to the same error

lukas.rychtecky09:10:30

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

Racheal09:10:42

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-himik09:10:59

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?

Racheal09:10:18

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

Racheal09:10:42

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

p-himik09:10:23

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

Racheal09:10:47

cool, let me try that

Racheal11:10:00

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

Endre Bakken Stovner17:10:52

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

p-himik17:10:16

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 Stovner17:10:38

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

Endre Bakken Stovner17:10:46

And yes, without the !

Endre Bakken Stovner17:10:11

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

Endre Bakken Stovner18:10:37

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-himik18:10:44

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

p-himik18:10:11

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

p-himik18:10:23

Consult the docstring of reg-sub for more details.

p-himik18:10:21

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

Endre Bakken Stovner18:10:46

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

p-himik18:10:13

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-himik18:10:51

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-himik18:10:16

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

p-himik18:10:57

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

p-himik18:10:15

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

p-himik18:10:25

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

p-himik18:10:39

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

Endre Bakken Stovner18:10:59

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

Endre Bakken Stovner18:10:10

Sorry, I am a confused n00b

p-himik18:10:21

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 Stovner18:10:05

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

p-himik18:10:46

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.

Endre Bakken Stovner18:10:16

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-himik18:10:33

The error is in this line:

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

Endre Bakken Stovner18:10:06

Now I am embarrassed XD

p-himik18:10:18

Happens. :)

p-himik18:10:48

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

Endre Bakken Stovner19:10:22

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

Endre Bakken Stovner19:10:10

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

p-himik19:10:45

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

Endre Bakken Stovner19:10:16

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

p-himik19:10:36

Yes, subs are not evaluated if not used.

p-himik19:10:58

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

Endre Bakken Stovner19:10:35

Yes, I used the wrong term

Endre Bakken Stovner19:10:34

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

p-himik19:10:57

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 Stovner19:10:07

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

Endre Bakken Stovner19:10:19

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

Endre Bakken Stovner19:10:03

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.