I'm trying to script PhantomJS in ClojureScript. I'm targeting Node and using phantomjs-node [1]. I have a basic example working:
(def phantom (js/require "phantom"))
(defn -main [& args]
(-> phantom
(.create (fn [browser]
(-> browser
(.createPage (fn [page]
(-> page
(.open "http://google.com" (fn [status]
(if (= status "success")
(-> page (.render "example.png")))
(-> browser .exit)))))))))))
Now, if I use evaluate function [2] of PhantomJS webpage object, I the following error:
phantom stdout: ReferenceError: Can't find variable: <namespace here>
When compiling into JavaScript the code to be evaluated contains the CLJS namespace and hence doesn't properly eval within the context of PhantomJS' webpage object. Here is an example:
(defn -main [& args]
(-> phantom
(.create (fn [browser]
(-> browser
(.createPage (fn [page]
(-> page
(.open "http://google.com" (fn [status]
(println (str "opened google? " status))
(-> page
(.evaluate #(-> document .-title)
#(do
(println (str "Page title is " %))
(-> browser .exit))))))))))))))
How can I prevent the code to be evaluated within the webpage object of PhantomJS from being namespaced with the CLJS namespace? Or secondly do I have any other options?
[1] https://github.com/sgentle/phantomjs-node
[2] http://phantomjs.org/api/webpage/method/evaluate.html
You need to use js/document instead of document.
document is a reference to clojurescript variable, js/document is a document in js world.
Related
I am trying to use react-native-swipe-list-view inside clojurescript. But I am having some trouble in converting documented js code in cljs code.
Documentations:
import { SwipeRow } from 'react-native-swipe-list-view';
<SwipeRow>
<View>
</View>
</SwipeRow>
My Cljs Code:
(:require [react-native-swipe-list-view :as swipe_list])
(defn item[]
(
[swipe_list/SwipeRow
[:View]]
))
Online tool:
(def SwipeRow (.-SwipeRow (js/require "react-native-swipe-list-view")))
(defn item[]
(
[SwipeRow
[:View]]
))
None of the above worked. I am new to cljs. it will be a big help if someone can tell me how to convert the above lines of js into cljs. Thanks
Reagent Documents: Creating Reagent "Components" from React Components
Here I am going to create two reagent components, view and swipeRow. I am using different ways for both, to show two ways for importing library and creating components. You can use either.
;; Importing Reagent and React Native
(ns type_name_server_here
(:require [reagent.core :as reagent]
["react-native" :as rn]))
;; 1st Way: Importing SwipeRow
(def SwipeRowImport (.-SwipeRow (js/require "react-native-swipe-list-view")))
;; Converting it into Reagent Component
(def SwipeRow (reagent/adapt-react-class SwipeRowImport))
;; 2nd Way: Importing View from already imported react-native library and converting it into reagent component
(def view (reagent/adapt-react-class (.-View ^js rn)))
;; SwipeRow requires two children (Check out documentation)
(defn item[]
(
[SwipeRow
[view] [view]]
))
If you are using shadow-cljs, you can use this table as a reference, for converting ES6 Import statments to CLJS Require
Here’s my code in which I’m trying to create multiple bottom tabs using react navigation
(defn sample-comp []
[:> View [:> Text "Sample Container!"]])
(defn root-comp []
[:> NavigationContainer
[:> SafeAreaView
(let [Tab (createBottomTabNavigator)]
[:> (.-Navigator Tab)
[:> (.-Screen Tab)
{:name "Home"
:component (r/reactify-component sample-comp)}]])]])
(defn init []
;; register error also occurs if there's a non-
;; related error in the code
(dispatch [:register-db])
(render-root "Humboi" (r/as-element [root-comp])))
but I’m getting the following error:
requireNativeComponent: “RNCSafeAreaProvider” was not found in UIManager.
How to fix this error?
I want to use a reagent component I've created in another file/namespace, say this.is.the.namespace, and it contains a component defined like so:
(defn component-name []
; stuff
)
In my entry file, I do the following:
(ns entry.point.namespace.name
(:require [this.is.the.namespace]
))
And when I include [component-name] in a component in the entry file, the component doesn't show. Why might this be?
(ns this.is.the.namespace)
(defn component-name []
[:p "Hello There"])
(ns entry.point.namespace.name
(:require [reagent.core :as reagent]
[this.is.the.namespace :as my-components]))
(reagent/render [my-components/component-name] (js/getElementById "main-div"))
Change "main-div" to id of the div that you are rendering into.
I am new to clojurescript and reagent. I try to use react-navigation in my react-native app but I getting this error
Error rendering component (in env.main.reloader > exp_cljs.core.app_root > reagent2)
This is my code
(def react-navigation (js/require "react-navigation"))
(def StackNavigator (aget react-navigation "StackNavigator"))
(defn Home
[]
[text "Hello Navigator"])
(defn SimpleApp
[]
(StackNavigator
(clj->js {:Home {:screen (r/create-class {:reagent-render (Home)})}})))
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent rn/app-registry "main" #(r/reactify-component app-root)))
This is my app-root
(defn app-root []
(SimpleApp)); -- error
;(r/create-class {:reagent-render SimpleApp}); error
;(r/as-element (SimpleApp)); -- error
;(r/adapt-react-class SimpleApp)); -- error
(ns same.app
(:require [reagent.core :as r]
[same.ui :as ui]
[same.util :as u]
[same.screens.auth :refer [AuthScreen]]
; [same.screens.reg :refer [RegScreen]]
; [same.screens.resend :refer [ResendScreen]]
[same.screens.splash :refer [SplashScreen]]
; [same.screens.drawer :refer [Drawer]]
[same.screens.presentation :refer [Presentation]]))
(def routes #js {;:Drawer #js {:screen (r/reactify-component Drawer)}
:AuthScreen #js {:screen (r/reactify-component AuthScreen)}
;:RegScreen #js {:screen (r/reactify-component RegScreen)}
;:ResendScreen #js {:screen (r/reactify-component ResendScreen)}
:Presentation #js {:screen (r/reactify-component Presentation)}
:Splash #js {:screen (r/reactify-component SplashScreen)}})
(def Routing (ui/StackNavigator.
routes
#js {:initialRouteName "Splash"
:headerMode "none"
:mode "modal"}))
(def routing (r/adapt-react-class Routing))
(defn AppNavigator []
(fn []
[routing]))
and android.core:
(ns same.android.core
(:require [reagent.core :as r :refer [atom]]
[re-frame.core :refer [dispatch-sync]]
[same.ui :as ui]
[same.events]
[same.subs]
[same.app :refer [AppNavigator]]))
(aset js/console "disableYellowBox" true)
(defn app-root []
(fn []
[AppNavigator]))
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent ui/app-registry "Same" #(r/reactify-component app-root)))
The trick is to convert React Native components to Reagent components and back where needed. In the following example definitions of login-screen and main-screen are omitted, they're just regular Reagent components.
(def react-navigation (js/require "react-navigation"))
(def stack-navigator (.-createStackNavigator react-navigation))
(def switch-navigator (.-createSwitchNavigator react-navigation))
; ...
; ...
; ...
(defn application-nav-stack []
(stack-navigator (clj->js { "MainApp" (r/reactify-component main-screen) })))
(defn authentication-nav-stack []
(stack-navigator (clj->js { "Login" (r/reactify-component login-screen) })))
(defn app-navigation-switch []
(switch-navigator
(clj->js { :Auth (authentication-nav-stack) :MainApp (application-nav-stack) })
(clj->js { :initialRouteName :Auth } )))
(defn app-root []
[ (r/adapt-react-class (app-navigation-switch)) ] )
(defn init []
(dispatch-sync [:initialize-db])
(.registerComponent app-registry "MyApp" #(r/reactify-component app-root)))
Whenever you pass a Reagent component to ReactNavigation function you need to use reactify-component to convert it to the native JS form; whenever you need to use ReactNavigation component as a part of Reagent component, you need to use adapt-react-class to convert it back.
Does phantom.js (>= 1.7.0) support multi-lines input on its console? Neither pressing Enter nor META-Enter works below,
phantomjs> function foo() {
Parse error