Fork me on GitHub
#clojurescript
<
2023-04-13
>
Leon08:04:44

How to use debounce in search input? I am using reagent framework on clojurescript

p-himik08:04:12

goog.functions.debounce probably. And either make the input an uncontrolled component or a controlled one with an intermediate model where you debounce only the outgoing :on-change call and not changes to the inner model.

Leon08:04:12

[:input {:type "text"
                  :placeholder "Search..."
                  :onChange
                  (fn [e]
                    (let [search-term (.-value (.-target e))]
                      (swap! app-state assoc-in [:customers] [])
                      (http-get "/customers" {:search search-term}
                                (fn [results]
                                  (swap! app-state assoc-in [:customers] results)))))}]

Leon08:04:20

This is my code block, @U2FRKM4TW

p-himik08:04:02

Seems like you can simply extract that http-get call into its own function and debounce that function.

Leon08:04:41

Could you write a bit of code if you don't mind? I am almost newbie...

Leon08:04:18

(swap! app-state assoc-in [:customers] results)
Also, this will work in the other functions as well?

p-himik08:04:48

Sorry, not right now. But you should read the docs of goog.functions.debounce, search publicly available CLJS sources for is usage (GitHub has useful search capabilities for it), an only maybe ask in #C053AK3F9 if you still can't figure it out after that. Also, debounce is quite easy to write. Chances are, you can find one such implementation as well. Regarding the swap! - no idea. It all depends on the rest of the things that aren't in that code block above.

Leon08:04:36

Now I use that inside defn app function, but can we use that swap inside another function?

Leon08:04:45

Okay, thanks for your information

Leon09:04:31

Hello @U2FRKM4TW I tried to implement like this

[:input {:type "text"
                  :placeholder "Search..."
                  :onChange
                  (fn [e]
                    (let [search-term (.-value (.-target e))]
                      (goog.functions.debounce
                       (fn []
                         (swap! app-state assoc-in [:customers] [])
                         (http-get "/customers" {:search search-term}
                                   (fn [results]
                                     (swap! app-state assoc-in [:customers] results)))))))}]

Leon09:04:42

What am I wrong with this way?

Leon09:04:03

I add required at the top

(ns client.core
  (:require [ajax.core :refer [GET POST PUT PATCH DELETE]]
            [goog.functions]
            [reagent.dom :as rdom]
            [reagent.core :as reagent]
            [clojure.string :as s]))

Leon10:04:30

Thank you

Leon10:04:31

[:input {:type "text"
                  :placeholder "Search..."
                  :onChange
                  (fn [e]
                    (let [search-term (.-value (.-target e))]
                      (goog.functions/debounce
                       (fn []
                         (swap! app-state assoc-in [:customers] [])
                         (http-get "/customers" {:search search-term}
                                   (fn [results]
                                     (swap! app-state assoc-in [:customers] results))))
                       1000)))}]
Does this look good to you? @U2FRKM4TW

p-himik10:04:30

Not really. This way, you'll end up creating the inner (fn [] ...) on every change. It will be a different function every time, so debounce won't be able to properly debounce it - it'll simply execute every single call but with the debounce delay. Instead, you need to create that function outside of the component (or when it's first mounted while making sure that the fn is not recreated on each update), pass the search item as an argument, wrap the fn in debounce, and store that wrapped function. The new function will also accept a search item - and that's what you should call inside that (fn [e] ...).

Leon10:04:19

Thanks for that, I should study clojurescript more

p-himik10:04:16

Have fun. :)

❤️ 2
p-himik10:04:53

And definitely drop by #C053AK3F9 - that channel is not only for Clojure but also for ClojureScript and other things.

Leon10:04:14

Sure, I will move to that channel

p-himik10:04:31

Ah, I see that you have already done so and even gotten a useful answer, nice!

Leon10:04:46

Yeah, lol