Fork me on GitHub
#cljsrn
<
2016-05-30
>
pesterhazy07:05:42

@kenny: are you starting the dev env using boot dev? How/where do you call myns.core.main?

savelichalex10:05:11

guys, anyone have example of PanResponder usage with cljs?

vikeri11:05:28

@misha: I think it might have to do with sourcemaps. Did you run re-natal enable-source-maps?

misha11:05:37

gentlemen, I sort of found input with custom keyboard and suggests component: https://github.com/nulrich/RCTAutoComplete which is a wrapper around https://github.com/EddyBorja/MLPAutoCompleteTextField However I can't get it to actually show any suggests, and the only anomaly I see is very similar to https://clojurians-log.clojureverse.org/cljsrn/2016-02-14.html The symptoms are: 1. set breakpoints inside native objective c code, e.g. in

//  MLPAutoCompleteTextField.m
- (void)expandAutoCompleteTableViewForNumberOfRows:(NSInteger)numberOfRows
2. start typing into Autocomplete input ==> nothing 3. delete everything in that input ==> breakpoint is hit.

misha11:05:16

@vikeri I probably did not. thanks

misha11:05:39

react bridge event gets sent on every key stroke though.

misha11:05:14

note: to make it compile I did:

//node_modules/react-native-autocomplete/RCTAutoComplete.ios.js, line 1
- var React = require('react-native');
+ var React = require('react');

misha12:05:23

@savelichalex: @vikeri is right, it is source maps related, has nothing to do with the component above

misha12:05:37

@savelichalex: how do I do equivalent of this in cljs?

var RCTAutoCompleteApp = React.createClass({
...
    onTyping: function (text) {
        this.setState({data:  ["a", "b", "c"]});
    },
...
the this.setState() part

misha12:05:04

no, but show me at least reagent

pesterhazy12:05:06

@misha, use a private atom bound in a clojure

misha12:05:39

@pesterhazy: I am using RCTAutoCompleteApp, not writing it

misha12:05:33

so i need to:

(RCTAutoCompleteApp {:onTyping #(<call this.setState() here>)})

misha12:05:28

(defn my-handler [e]
  (this-as this
    (.setState this #js [1 2 3])))

(RCTAutoCompleteApp {:onTyping my-handler})
?

pesterhazy12:05:39

you can do something like that yes, though it seems a hacky api on the library author's part

savelichalex12:05:07

this is with r/atom

savelichalex12:05:03

hm, understand you)

savelichalex12:05:10

wait a minute)

misha12:05:56

@savelichalex: I know how to do it, when I am the author of a component. What I need instead – is to be able to call someone else's component's method from my own function which I pass in props

misha12:05:46

@savelichalex: do you have an example? how does it work? do I assign ref to a component myself, and then use it? how do I access it later?

pesterhazy12:05:42

@sam.roberton: hey, I saw that you contribute some code to boot-react-native. Moving everything to a boot tempdir is a good idea, but it breaks the simple example app. Any idea how I can get around https://github.com/mjmeintjes/boot-react-native/issues/50 ?

misha13:05:19

@savelichalex: rum version:

(defn get-ref [state ref-name]
  (aget (aget (:rum/react-component state) "refs") ref-name))

(rum/defcs page [state]
  (let [pr-ref #(js/console.log (get-ref state "yoyo"))]
      (rum/with-ref
        (rn/Autocomplete {:onFocus pr-ref, ...})
      "yoyo")

savelichalex13:05:36

@misha: got it) need repo with cheatsheets)

debug16:05:05

Is lein figwheel android the only way to locate errors?

debug16:05:54

"Waiting for figwheel to load files.." didn't go away so tried manually invoking functions from the repl

debug16:05:00

future-app.android.core=> (init)
#object[Error Error: schema check failed: {:data (not (sequential? a-object))}]

debug17:05:56

;; schema of app-db
(def schema {:greeting s/Str
             :data [s/Str]})

;; initial state of app-db
(def app-db {:greeting "Hello Clojure in iOS and Android!" :data (into-array (map str (range 1 100)))})
Isn't :data compatible with what's defined in the schema?

caio17:05:18

i think the right way is (into [] (map …))

debug17:05:08

May I ask what's the difference between those two?

debug17:05:18

Because the app does respond differently

debug17:05:10

One returns a js version and the other doesn't?

caio17:05:17

idk… in clojure it seems some interop fn, as it returns #object["[Ljava.lang.String;" 0x72c1be38 "[Ljava.lang.String;@72c1be38”]

plexus17:05:33

yeah, into-array is for interop

debug17:05:11

future-app.android.core=> (into [] (map str (range 1 100)))
["1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" "90" "91" "92" "93" "94" "95" "96" "97" "98" "99"]
future-app.android.core=> (into-array (map str (range 1 100)))
#js ["1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" "90" "91" "92" "93" "94" "95" "96" "97" "98" "99"]

plexus17:05:30

into-array (into-array aseq) Returns a new JavaScript array from the elements of aseq.

debug17:05:31

The purpose of #js still confuses me

debug17:05:50

Does it mean it will get translated to js?

plexus17:05:08

#js is a reader tag, it means, read the thing that comes next as a JS array or JS object instead of a vector/map

plexus17:05:14

if you use it in clojurescript code it will output JS with a literal array/object instead of a vector/map

plexus17:05:44

vs if you do this (clj->js [1 2 3]) then the compiled JS will have a clojurescript vector, plus a function call to covert it

caio17:05:46

there’s even cljs->js and js->cljs helper fns to convert between both types

plexus17:05:41

hate to plug too shamelessly but I just did a whole screencast on all these things (paywall) https://lambdaisland.com/episodes/clojurescript-interop

plexus17:05:41

long story short: clj-js and js->clj will convert recursively between array/object and vector/map

plexus17:05:57

whereas #js only works on a single level

plexus17:05:42

so (clj->js {:foo [:bar]}) would equal #js {:foo #js [:bar]}

plexus17:05:27

also two tips: avoid using js->clj on large data structures, it's not designed for that and will not perform well

debug17:05:39

Will be needing all the help I can get to understand these 🙂

plexus17:05:44

and secondly, beware of strings vs keywords

debug17:05:53

Therefore, no plug is shameless to me 😛

plexus17:05:37

(clj->js {:foo :bar}) will do what you want, i.e. create a js object with a "foo" key

debug17:05:53

The error that's popping up now is "Requested keys of a value that is not an object"

plexus17:05:09

but (js-obj :foo :bar) will create a ":foo" key, so in JSON {":foo": ":bar"}

debug17:05:31

Wow, those are very informative, a beginner like me would certainly trip over

plexus17:05:08

from a quick google it seems that's a JS error message, not a ClojureScript error message

plexus17:05:35

I think it means Object.keys is being called with something that isn't a JS object, like a primitive or an array

debug17:05:15

This doesn't work:

[listview {:style {:paddingLeft 8 :paddingRight 8 :flex 1}
                   :dataSource (.cloneWithRows (datasource. #js {:rowHasChanged not=}) (clj->js @data))
                   :renderRow get-row}]])))
But a plain array like ["test"] instead of @data works

debug17:05:56

The function containing that snippet has subscribed to data

pesterhazy17:05:32

not that the literal [1 2 3] creates a vector, not an array. Important distinction (the latter is mutable)

debug17:05:24

My bad, it was working just fine, that error is from a different section

debug17:05:35

Thank you very much everyone, I really appreciate the help I'm getting here 🙂

pesterhazy17:05:45

eponysterical!

caio17:05:06

do you guys know any project aiming to be a RN-compatible cljs-ajax-like library? i’m really sad for having to use js/fetchfor this 😞

pesterhazy17:05:21

Let's just fix cljs-ajax, or rn

pesterhazy17:05:41

Surely there just is a bug somewhere in the android code

pesterhazy17:05:59

Have you tried the latest RN?

caio17:05:53

yep, 0.26.0

pesterhazy18:05:31

Maybe a custom back end for cljs-ajax based on fetch?

caio18:05:09

yeah, that’s what I was thinking. there’s also xmlhttprequest polyfill

pesterhazy18:05:55

I thought fetch was a polyfill implemented on top of xhr, in RN at least

caio18:05:57

idk how’s fetch implemented, but as xhr is already there, it may be an easier starting point (but there’s already limitations: see https://github.com/facebook/react-native/issues/5347 and https://github.com/JulianBirch/cljs-ajax/blob/master/src/ajax/xml_http_request.cljs#L20

debug18:05:32

Why does the println not get called?

debug18:05:34

future-app.android.core=> (.then (js/window.fetch "") #(println %))
#object[Promise [object Object]]

savelichalex18:05:13

@debug: are you use (enable-console-print!) ?

debug18:05:49

I didn't know about it, just did that but still it doesn't work

debug18:05:07

Regular println works though

debug18:05:41

future-app.android.core=> (println "Hello")
Hello
nil

savelichalex18:05:07

hm, you tryied in repl?

debug18:05:16

yes in the repl

plexus18:05:01

and you're sure your promise resolves and doesn't reject?

plexus18:05:32

(.then (js/window.fetch "") #(println %) #(println "rejected" %))

pesterhazy19:05:40

println can sometimes be a little bit flaky in RN in my experience

debug19:05:42

future-app.android.core=> (.then (js/window.fetch "") #(println %) #(println "rejected" %))`
#object[Promise [object Object]]
That's all I get

pesterhazy19:05:56

try calling console.log directly (and make sure you're tailing the right log)

pesterhazy19:05:02

also try non-https

debug19:05:22

future-app.android.core=> (.then (js/window.fetch "") #(js/console.log %) #(js/console.log "rejected" %)) 
#object[Promise [object Object]]

debug19:05:24

Still the same

pesterhazy19:05:31

try explicitly setting the method to GET, or POST (to see if you at least get an error)

pesterhazy19:05:34

also use .then and .catch instead of passing two args to .then

pesterhazy19:05:10

^^ here's what I use

kenny19:05:02

@pesterhazy: Sorry for the delayed response.. I’m just going to ignore that problem until I figure out how to get the example project working… I am able to run the project and see the app in my emulator, however, if I can the hello world text it does not update in the app. Is there any additional steps I need to do in order to see the app updated?

pesterhazy19:05:37

no, it should work (if you're using boot dev)

pesterhazy19:05:53

do you see messages about reloading in the debug output?

kenny19:05:14

Yes I am. The cljs recompiles. Nothing about reloading the app

pesterhazy19:05:57

is this ios or android?

kenny19:05:45

I have not changed anything from the example project.

kenny19:05:52

Besides the hello world text.. 🙂

pesterhazy19:05:05

if you reload (shake the device and click reload), does it refresh then?

kenny19:05:29

How would I do that in an emulator?

pesterhazy19:05:44

there's a menu item (hardware?)

kenny19:05:59

Ah I see it.Reload JS?

kenny19:05:17

Oh wait there is an option called “Enable Live Reload"

kenny19:05:36

Lol that solved it

kenny19:05:01

Maybe worth adding that to the docs if you are using Genymotion emulator

pesterhazy19:05:38

I think that option didn't used to exist

pesterhazy19:05:53

I think it was enabled by default

kenny19:05:13

Not anymore 🙂 Brand new laptop and installed everything fresh yesterday

kenny19:05:01

Do you know if boot-react-native works with boot 2.6.0?

pesterhazy19:05:16

I don't see why not

pesterhazy19:05:41

haven't tried it though

pesterhazy19:05:09

boot-react-native badly needs updating, code and docs

kenny19:05:10

It’s just the example project has a boot.properties with an explicit BOOT_VERSION=2.5.5

kenny19:05:33

Though that is probably just old as 2.6.0 is relatively new

pesterhazy19:05:33

yeah maybe it's worth removing that explicit line

kenny19:05:00

Do you use boot-react-native?

pesterhazy19:05:25

yes, extensively

pesterhazy19:05:49

we're relying on it for building our app

kenny19:05:36

I really want to use it but the lack updates and docs make it difficult for someone new to react native. I really don’t want to use re-natal because of leiningen.

pesterhazy19:05:01

I propose to add things to the ticket, I plan to work on brn in the next weeks and to bring it into shape

kenny19:05:28

Do you have a more up to date example project?

debug19:05:31

(-> (js/fetch "") (.then #(js/console.warn %)))
Just noticed, doing that causes a yellow bar to popup on the phone, no console output however

pesterhazy19:05:01

yeah, React Native takes over console.warn sometimes

pesterhazy19:05:49

@kenny: that's part of what I want to work on

pesterhazy19:05:12

I tried to update to React Native 0.26 but ran into issues unfortunately

pesterhazy19:05:10

I really like BRN's approach of leveraging the RN packager

kenny19:05:48

I really think that re-natal and BRN need to come together. If we are to make a great cljsrn library there needs to not be fragmentation.

kenny19:05:08

Looks like there is discussion about this: https://github.com/drapanjanas/re-natal/issues/53

pesterhazy19:05:04

yeah, I've commented there

pesterhazy19:05:34

need to take some time to understand the pros and cons of brn vs re-natal

pesterhazy19:05:37

but yeah it'd be nice to get more overlap

pesterhazy19:05:22

I guess only the "live dev env" part actually differs, whereas building offline bundles is pretty similar

kenny19:05:02

Seems like it. boot reload vs figwheel.

kenny19:05:16

Do you know how willing mjmeintjes is to accept PRs?

pesterhazy19:05:28

He's always been helpful and quick to respond

savelichalex19:05:34

Guys what’s wrong with leiningen? There is smth that I don’t know? Are you have some explanation about boot vs lein?

kenny19:05:31

@savelichalex: There is an inherent problem with declarative DSLs. It is trying to be a build tool by creating an all encompassing DSL, however, the problem is solved much better by just doing things through code: boot.

savelichalex19:05:15

looks like gulp vs webpack in js world:smile:

pesterhazy19:05:32

boot is particularly well suited for this type of problem: continuously updating files as a result of file watch events

pesterhazy19:05:27

you can also, conceivably, run the backend and frontend in the same boot instance

pesterhazy20:05:19

I've wasted too much of my life running "npm install"

kenny21:05:33

Has anyone used Rum with boot-react-native? I seem to be having problems getting it to work:

(set! js/React (js/require "react-native/Libraries/react-native/react-native.js"))
(defonce react (js/require "react-native/Libraries/react-native/react-native.js"))

(defn create-element [rn-comp opts & children]
  (apply js/React.createElement rn-comp (clj->js opts) children))

(def app-registry (.-AppRegistry react))
(def view (partial create-element (.-View react)))
(def text (partial create-element (.-Text react)))

(defc AppRoot
      [state]
      (view {:style {:flexDirection "column" :margin 40 :alignItems "center"}}
            (text {:style {:fontSize 30 :fontWeight "100" :marginBottom 20 :textAlign "center"}} "CHANGE THIS: HELLO WORLD")))

(defn mount-app [] (support/mount (AppRoot app-state)))
(defonce root-component-factory (support/make-root-component-factory))
(defn ^:export main
  []
  (enable-console-print!)
  (js/console.log "MAIN")
  (.registerComponent (.-AppRegistry react)
                      “MyApp"
                      (fn [] root-component-factory))
  (mount-app))
The error I’m getting is No protocol method IInterpreter.interpret defined for type object: [object Object]. This is coming from Sablono not being able to render an object instead of hiccup. It must be able to handle it though because re-natal is able to do it.

kenny21:05:10

Actually figured it out.. You need to copy re-natal’s “hack.”