Tensegritics / ClojureDart

Clojure dialect for Flutter and Dart
1.43k stars 92 forks source link

How to pass dart method as a parameter? #61

Open D00mch opened 2 years ago

D00mch commented 2 years ago

I write wrappers over http.dart, and can't figure out how to pass http/<method-name> as an argument to the function.

For example, I have my post method as:

(defn post [url {:keys [headers on-success on-error body params]}]
  (. (http/post 
       (.parse Uri (if params (str url "?" (params->query-string params)) url)) 
       :body (some-> body stringify-keys convert.json/encode) 
       :headers (when headers ^#/(Map String String) headers)) 

     (then #(when-let [callback (if (= (.-statusCode %) 200) on-success on-error)]
              (callback (-> % .-body utils/keywordize-blunt))))

     (catchError #(when on-error (on-error %)))))

Having this, I want to avoid writing the same stuff for get, put, delete, and instead use one function and pass 'method' to it like:

;; as previous, but 'method' is used instead of 'http/post' 
(defn request [method url {:keys [headers on-success on-error body params]}]
  (. (method 
       ... 
       ) ...))

(defn post [url args]
  (request http/get url args))
logs ``` You rock! 🀘 Performing hot reload... ══║ EXCEPTION CAUGHT BY WIDGETS LIBRARY β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• The following NoSuchMethodError was thrown building Builder(dirty): Closure call with mismatched arguments: function 'get' Receiver: Closure: (Uri, {Map? headers}) => Future from Function 'get': static. Tried calling: get(Instance of '_SimpleUri', Instance of 'Keyword', null) Found: get(Uri, {Map? headers}) => Future The relevant error-causing widget was: MaterialApp MaterialApp:file:///Users/m1/IdeaProjects/clojure/lconvex/lib/cljd-out/lconvex/main.dart:30:37 When the exception was thrown, this was the stack: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5) #1 _objectNoSuchMethod (dart:core-patch/object_patch.dart:85:9) #2 request (package:lconvex/cljd-out/lconvex/sdk.dart:172:33) #3 post (package:lconvex/cljd-out/lconvex/sdk.dart:131:22) #4 init (package:lconvex/cljd-out/lconvex/sdk.dart:34:22) #5 accounts_page (package:lconvex/cljd-out/lconvex/main.dart:12:15) #6 MaterialPageRoute.buildContent (package:flutter/src/material/page.dart:53:55) #7 MaterialRouteTransitionMixin.buildPage (package:flutter/src/material/page.dart:106:27) #8 _ModalScopeState.build.. (package:flutter/src/widgets/routes.dart:872:55) #9 Builder.build (package:flutter/src/widgets/basic.dart:7398:48) #10 StatelessElement.build (package:flutter/src/widgets/framework.dart:4827:28) #11 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4754:15) #12 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #13 StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5) #14 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) derObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #16 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #17 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #18 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #19 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #20 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #21 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #22 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) #23 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #24 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #25 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) gets/framework.dart:6291:14)ectElement.update (package:flutter/src/wid #27 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #28 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #29 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #30 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #31 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) #32 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #33 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #34 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #35 StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5) #36 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #37 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) utter/src/widgets/framework.dart:4928:11)ackage:fl #39 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #40 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) #41 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #42 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #43 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #44 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #45 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #46 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #47 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #48 ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5) #49 _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:111:11) ateChild (package:flutter/src/widgets/framework.dart:3501:15) #51 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #52 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #53 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #54 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #55 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #56 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) #57 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #58 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #59 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #60 ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5) #61 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) ntElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #63 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #64 ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5) #65 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #66 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #67 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #68 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #69 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) #70 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #71 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #72 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #73 StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5) ateChild (package:flutter/src/widgets/framework.dart:3501:15) #75 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #76 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #77 StatelessElement.update (package:flutter/src/widgets/framework.dart:4834:5) #78 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #79 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6291:14) #80 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #81 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #82 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #83 ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5) #84 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #85 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) nt.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #87 ProxyElement.update (package:flutter/src/widgets/framework.dart:5108:5) #88 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #89 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #90 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #91 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #92 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) #93 Element.updateChild (package:flutter/src/widgets/framework.dart:3501:15) #94 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #95 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #96 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #97 StatefulElement.update (package:flutter/src/widgets/framework.dart:4960:5) ateChild (package:flutter/src/widgets/framework.dart:3501:15) #99 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4780:16) #100 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4928:11) #101 Element.rebuild (package:flutter/src/widgets/framework.dart:4477:5) #102 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2659:19) #103 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21) #104 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5) #105 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15) #106 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9) #107 SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:862:7) (elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch) �════════════════════════════════════════════════════════════════════════════════════════════ Reloaded 4 of 940 libraries in 775ms. ```
D00mch commented 2 years ago
full code to reproduce: ```clojure (ns (:require [cljd.walk :refer [stringify-keys]] [clojure.string :refer [join]] ["dart:convert" :as convert] ["package:http/http.dart" :as http])) (defn params->query-string [m] (join "&" (for [[k v] m] (str (name k) "=" v)))) (defn keywordize-blunt [entry] (cond (dart/is? entry Map) (loop [result {} entries (seq entry) ] (let [[k v] (first entries)] (if k (recur (assoc result (keyword k) (keywordize-blunt v)) (rest entries)) result))) (dart/is? entry List) (map (fn [e] (keywordize-blunt e)) entry) :else entry)) (defn request [method url {:keys [headers on-success on-error body params]}] ;; dart: result.then((value) => ...).catchError((error) => ...); (. (method (.parse Uri (if params (str url "?" (params->query-string params)) url)) :body (some-> body stringify-keys convert.json/encode) :headers (when headers ^#/(Map String String) headers)) (then #(when-let [callback (if (= (.-statusCode %) 200) on-success on-error)] (callback (-> % .-body keywordize-blunt)))) (catchError #(when on-error (on-error %))))) (defn post [url args] (request http/post url args)) (defn init [] ;; call it from anywhere (post "https://convex.world/api/v1/faucet" {:body {:address 1371 :amount 1997} :on-success (fn [result] (dart:core/print result)) :on-error (fn [result] (dart:core/print result))})) ```
D00mch commented 2 years ago

And I am not sure if it should be possible

cgrand commented 2 years ago

In your case it’s not even possible (short of Function.apply) because the http methods functions don’t have the same signature: body and encoding are not present on all methods.

D00mch commented 2 years ago

Ah, that was stupid mistake, that I tried to pass http/get as method. But if I pass http/post or http/put, it doen't work either. And with the put and post β€” should it work?

cgrand commented 2 years ago

(method url .& :encoding XX :body YY) may work. Issue #9 is related I believe.