要点
ライブラリ名に$defaultを付けてrequireすると解決する場合があります。(ns your.some.file
(:require ["react-native-ble-manager$default" :as rn-ble-manager]))
背景
react-native + expo + shadow-cljs環境で作っているandroidアプリでreact-native-ble-managerのstart関数を呼んだところ下記のエラーが発生しました。(ns your.some.file
(:require ["react-native-ble-manager" :as rn-ble-manager]))
(.start rn-ble-manager)
Possible Unhandled Promise Rejection (id: 0):
TypeError: undefined is not a function
上記エラーの調査試行内容と解決方法を共有します。
requireはできているが、何かおかしい
requireしたreact-natibe-ble-managerをjsのconsole.logで表示したところ、start関数は下記の位置にありました。(ns your.some.file
(:require ["react-native-ble-manager" :as rn-ble-manager]))
(.log js/console rn-ble-manager)
// start以外の要素は省略していますobject内のdefaultキーの中にstartがあるので、start関数が見つけられずにundefinedになっていました。
Object {
"default": BleManager {
"_nativeModule": Object {
"start": [Function nonPromiseMethodWrapper]
}
}
}
この問題はcljs環境だけでなく、nodejsの環境でも書き方によって発生する問題でした。
unhandled promise rejection #192
defaultを読み込めば解決
ライブラリのdefaultを読み込む設定を調べたところ、shadow-cljsの説明書で解決方法を見つけました。13.1.1. Using npm packages
ライブラリの末尾に$defaultを付けることでdefaultをimportできます。
(ns your.some.file
(:require ["react-native-ble-manager$default" :as rn-ble-manager]))
これにより、start関数が期待する位置で読み込まれ、start関数がundefinedにならず呼び出し可能になりました。
(なお、関数が期待通りに動くかはandroidの権限付与など別の問題が関係します。)
(ns your.some.file
(:require ["react-native-ble-manager$default" :as rn-ble-manager]))
(.log js/console rn-ble-manager)
(.start rn-ble-manager) ; undefinedエラーを回避
// start以外の要素は省略しています
BleManager {
"_nativeModule": Object {
"start": [Function nonPromiseMethodWrapper]
}
}
おわり
関数呼び出しでundefinedエラーが発生して戸惑いましたが、shadow-cljsの記述方法を把握してライブラリのdefault部分を呼び出したことで、期待通りに実行できました。参考
13.1.1. Using npm packagesunhandled promise rejection #192
0 件のコメント :
コメントを投稿