Fork me on GitHub
#clojurescript
<
2020-05-13
>
sofra12:05:05

I am compiling some code using advanced compilation and some of my property access names seem to being munged (aget data "offer") works but `(.-offer data)` gets munged away what is the correct way to access properties? Why does the .- syntax exist if it is not going to work in these situations?

Roman Liutikov12:05:11

Put a type hint (.-offer ^js data)

sofra13:05:54

thanks @roman01la! how do I know when to used that and when to not?

Roman Liutikov13:05:18

use it when it's unkown/runtime JS data

sofra13:05:34

ok, got it thanks

Roman Liutikov13:05:45

also the compiler should print warnings

sofra13:05:54

hmm, I didn’t get warning, I am using shadow-cljs, I wonder if that is it

Roman Liutikov13:05:49

I don't know how shadow works, ask in #shadow-cljs

sofra13:05:12

yep thanks @roman01la, that was a big help :thumbsup:

thheller14:05:38

you can turn on externs inference for cases where you might need to add annotations https://shadow-cljs.github.io/docs/UsersGuide.html#infer-externs

sofra23:05:30

thanks @U05224H0W. I tried that and it worked well.

sofra23:05:46

There was a case where the annotation didn’t help and I ended up using goog.object/get but I think it was because it was inside a go block and something strange was going on

plexus13:05:22

I recently submitted https://clojure.atlassian.net/projects/CLJS/issues/CLJS-3248 , would be awesome if we could get some kind of feedback on that. It would go a long way towards providing people a good testing experience.

dnolen14:05:39

@plexus thanks though better to mentions tickets and patches in #cljs-dev

mfikes14:05:01

For data, you might want to just use the facilities in goog.object @sofra

sofra23:05:20

Yep thanks @mfikes, I found your documentation on this stuff and it was helpful!

👍 4
mfikes23:05:10

The cljs-bean library might be of interest to you as well.

mfikes23:05:39

But, for simple data field access goog.object is sufficient. 🙂

sofra23:05:15

yep, perfect, thanks 🙏

dnolen14:05:30

I like the approach because it's just must simpler, the source mapping stuff not nearly as straightforward for the obvious reasons

mfikes14:05:50

@plexus I'm gonna put that patch through CI and Canary

plexus14:05:39

thanks @mfikes. Got it @dnolen will put a message there in the future

didibus19:05:49

Anyone got this error before: "clojure.lang.ExceptionInfo: Invalid :refer, var cljs.tools.reader.impl.errors/reader-error does not exist in file target/public/cljs-out/dev/cljs/tools/reader/impl/commons.cljs"

thheller19:05:12

looks like a dependency conflict on tools.reader maybe?

didibus21:05:18

Hum.. might be. Deps.edn maybe pulls in a newer version and some function got removed. I'll have a look at that

Lone Ranger19:05:05

is this the correct channel for :target :nodejs questions?

Lone Ranger19:05:07

I'm experiencing some difficulty working with functions that reference this internally.

pesterhazy20:05:46

@goomba sure, what's your question?

noisesmith20:05:13

I bet the FAQ on that one is using this-as

Lone Ranger20:05:50

@noisesmith I think it's the inverse problem. I mean I'm calling a nodejs function that interally binds this. Let me construct a repro...

Lone Ranger20:05:45

(ns some.example
  (:require [cljs.nodejs :as nodejs]
            [cljs.core.async :as a :refer-macros [go go-loop]]
            [cljs.core.async.interop :refer-macros [<p!]]
            cljs.pprint
            ["zlib" :as zlib]
            ["util" :as node-util]
            ["level" :as level]))

(def promisify node-util.promisify)
(def unzip (-> (.-unzip zlib) promisify))
(def db (level. "add-deps-db"))

(defn db-put! [k v]
  (let [put! (promisify db.put)] 
    (go
      (try
        (<p! (put! k v))
        (catch :default e
          (println "Problem: " e))))))

(comment
  (db-put! "name" "bob")
  ;;=> Problem:  #error {:message Promise error, :data {:error :promise-error}, :cause #object[TypeError TypeError: db._isOpening is not a function]}
  )

Lone Ranger20:05:20

the interesting part is that db.__isOpening is, in fact, a function

Lone Ranger20:05:32

(comment
  (db-put! "name" "bob")
  
  ;;=> Problem:  #error {:message Promise error, :data {:error :promise-error}, :cause #object[TypeError TypeError: db._isOpening is not a function]}

  db._isOpening ;;=> #object[Function]
  )

Lone Ranger20:05:02

so I'm wondering if I'm doing something wrong on the invocation of db, perhaps?

pesterhazy20:05:13

that's a classic js mistake

noisesmith20:05:49

what if core.async is resolving its own put! instead of the local binding?

noisesmith20:05:55

n/m it's probably not that

pesterhazy20:05:06

db.put doesn't have the reference to db

4
Lone Ranger20:05:35

I believe this is the code in reference:

LevelUP.prototype.put = function (key, value, options, callback) {
  var self = this
  var promise

  callback = getCallback(options, callback)

  if (!callback) {
    callback = promisify()
    promise = callback.promise
  }

  if (maybeError(this, callback)) { return promise }

  options = getOptions(options)

  this.db.put(key, value, options, function (err) {
    if (err) {
      return callback(new WriteError(err))
    }
    self.emit('put', key, value)
    callback()
  })

  return promise
}

pesterhazy20:05:04

try (.bind (.-put db) db)

Lone Ranger20:05:08

same thing :thinking_face:

Lone Ranger20:05:53

(for reference)

noisesmith20:05:19

what about #(.put db %1 %2)?

Lone Ranger20:05:26

I'll give it a shot!

pesterhazy20:05:40

it has to be (promisify (.bind (.-put db) db))

pesterhazy20:05:52

not just call it in a top level form

Lone Ranger20:05:15

like so?

(defn db-put! [k v]
  (let [put! (promisify (.bind (.-put db) db))] 
    (go
      (try
        (<p! (put! k v))
        (catch :default e
          (println "Problem: " e))))))

Lone Ranger20:05:32

niiiiiiiiiiiiiiiiiiiiice

pesterhazy20:05:38

I'd also go easy on the core.async stuff if you're starting out with cljs/js

Lone Ranger20:05:52

no that was it

Lone Ranger20:05:00

sorry repl output + excitement

Lone Ranger20:05:12

I'm quite familiar with cljs but node is newish to me

pesterhazy20:05:39

I'd study the basics (promises, how does this work) first before getting out the heavy concurrency machinery (core.async)

Lone Ranger20:05:43

ever since I learned about nexe though my mind has been reeling with the possibilities

Lone Ranger20:05:23

I'd wager that's a fairly intermediate/advanced fix 😄

Lone Ranger20:05:32

and yes I couldn't agree more, and thank you 🙂

Lone Ranger20:05:43

any suggested reading, besides the above?

Lone Ranger20:05:24

well the marketing is certainly spot on 😄

Lone Ranger21:05:34

so @pesterhazy after reading that article, I'm wondering why we wouldn't always bind this?

Lone Ranger21:05:45

would be simple enough to make an invocation macro