Fork me on GitHub
#fulcro
<
2021-11-26
>
xceno14:11:37

@tony.kay Would you be fine with allowing to override the :will-leavebehavior in rad forms, just like we can with :will-enter here: https://github.com/fulcrologic/fulcro-rad/blob/develop/src/main/com/fulcrologic/rad/form.cljc#L469 ? I could provide a PR if you want

tony.kay22:11:10

So, you can’t currently override any of the component-level things that RAD uses, except for route-denied, validator, and controls. My general overall intent with RAD is to show how you can use these patterns to build reusable things. In other words, I don’t consider defreport the target of all extensions to RAD, but instead see that you may in fact want/need to create your own macros that create things using the same patterns. That said, I did try to leave gradual escape hatches so that you don’t necessarily ever need to go to that extreme. The behavioral extension point, in my view, is ro/machine…esp since the state machine is just a map, and you can use simple functions like:

(defn augment-event
  "Add `additional-action` to the end of the actions performed by the `base-machine` in `state` for `event`. `event` can
  be nil if there is just a global handler for that state. Returns the modified machine, so more than one of these
  can be threaded together to modify a machine in multiple places."
  [base-machine state event additional-action]
  (let [handler-path     (if event
                           [::uism/states state ::uism/events event ::uism/handler]
                           [::uism/states state ::uism/handler])
        original-handler (get-in base-machine handler-path)]
    (assoc-in base-machine handler-path (fn [env]
                                          (-> env
                                            (original-handler)
                                            (additional-action))))))
so that you can then do something like:
(defstatemachine my-machine
  (-> form/form-machine 
    (augment-event :initial nil load-something-sidebank)))
Of course you can add new states, events, etc. Treat those state machines as example code, not as final swiss army knives of code. If we jam every imaginable feature into these macros and machines they’ll become huge unusable hairballs.

👍 1
xceno12:11:23

> If we jam every imaginable feature into these macros and machines they’ll become huge unusable hairballs. Yes, I very much agree here! > intent with RAD is to show how you can use these patterns to build reusable things And it works well that way, most of my code right now is simply re-using the underlying functions that make up rad. Currently I'm experimenting around with how far I can go the opposite way, so "how little do I need to actually customize to get where I wanna be". TBH I didn't think about extending the state-machine yesterday at all but in hindsight it makes way more sense that way. I'll need to compute/derive stuff later on anyway and I can encapsulate that in my forms state machine as well. Thanks for your time!

tony.kay16:11:09

I think the preferred thing would be to override events on the machine

xceno19:11:48

Ah fair enough

Benjamin C22:11:12

Hello, I would like to use fulcro to build a cross-platform app. I found fulcro-mobile-template, but I ran into serveral issues trying to get it to run with the libraries being out of date.

Benjamin C22:11:30

Updating the clojure libraries was easy enough, but trying to get all the npm models working has been difficult.

tony.kay22:11:21

I don’t have the time to maintain everything, and the stuff I don’t currently use gets out of date. Open to contributions, but I just can’t do everything 🙂

tony.kay22:11:37

perhaps some other ppl using mobile can help

Benjamin C22:11:51

@tony.kay No worries, I understand that completely.

tony.kay23:11:41

The cljs itself should be pretty close given that RN hasn’t changed their entry point. So, really, its just getting the project set up. You might try using the RN js project setup instructions to get an up-to-date baseline, then work on integrating shadow-cljs as the build tool for the target js.

Benjamin C02:11:15

Seems like I might be getting close. now I am getting this: 17:19 Unable to resolve module native-base from /home/pacman/projects/fulcro-real-world/mobile/app/index.js: native-base could not be found within the project or in these directories: node_modules ../node_modules $CLJS.shadow$js["react-native"] = function() { return require("react-native"); }; 1485 | $CLJS.shadow$js["react-dom"] = function() { return require("react-dom"); }; > 1486 | $CLJS.shadow$js["native-base"] = function() { return require("native-base"); }; | ^ From what I can tell, it is loading everything fine, until it tries to load one of the project-local "modules". Perhaps a missing config entry to to tell it where to look?

tony.kay03:11:56

native-base is an addon…you could try dropping it from the code/deps

Benjamin C04:11:30

Ah, that makes sense. I had assumed it was mobile_ui/native_base.cljs. Had I looked a little more carefully, I would have seen the "native-base" require in the namespace. Thanks!

Benjamin C21:11:03

@tony.kay So now I am running into this:

Re-mounting
2021-11-27T21:14:00.139Z DEBUG [com.fulcrologic.fulcro.algorithms.indexing:61] - (Re)indexing application query for prop->classes
Android Running app on Moto G (5) Plus
2021-11-27T21:14:00.413Z DEBUG [com.fulcrologic.fulcro.ui-state-machines:?] - Trigger :app.model.session/session :com.fulcrologic.fulcro.ui-state-machines/started
(node:23866) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 change listeners added to [HasteMap]. Use emitter.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

This error is located at:
    in Unknown (created by ExpoRoot)
    in ExpoRoot
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer

tony.kay22:11:29

Something is using a component that is undefined. If you took out native base, but left it in the code perhaps it would happen

Benjamin C23:11:50

The hard part seems to be figuring out which "something" is missing. I don't think it is a native-base problem; I added native-base back in with yarn add native-base. I wish I could find a stacktrace. Without it, I'm just trying to pair things down until it works.

tony.kay23:11:21

It's saying that ExpoRoot is rendering something that is undefined. So out provided UI and add stuff back in. Could be expo has changed in some way that changes how the root is defined

Benjamin C23:11:14

I think I may have found the culprits:

Picker has been extracted from react-native core and will be removed in a future release. It can now be installed and imported from '@react-native-picker/picker' instead of 'react-native'. See 
at node_modules/react-native/Libraries/Utilities/warnOnce.js:27:2 in warnOnce
at node_modules/react-native/index.js:170:12 in module.exports.get__Picker
at app/index.js:489:2 in goog.globalEval
at app/index.js:1445:8 in env.evalLoad
at app/index.js:1690:0 in <global>
at node_modules/metro-runtime/src/polyfills/require.js:349:11 in loadModuleImplementation
at node_modules/metro-runtime/src/polyfills/require.js:201:44 in guardedLoadModule
at  in global code

PickerIOS has been extracted from react-native core and will be removed in a future release. It can now be installed and imported from '@react-native-picker/picker' instead of 'react-native'. See 
at node_modules/react-native/Libraries/Utilities/warnOnce.js:27:2 in warnOnce
at node_modules/react-native/index.js:180:12 in module.exports.get__PickerIOS
at app/index.js:489:2 in goog.globalEval
at app/index.js:1445:8 in env.evalLoad
at app/index.js:1690:0 in <global>
at node_modules/metro-runtime/src/polyfills/require.js:349:11 in loadModuleImplementation
at node_modules/metro-runtime/src/polyfills/require.js:201:44 in guardedLoadModule
at  in global code

ProgressViewIOS has been extracted from react-native core and will be removed in a future release. It can now be installed and imported from '@react-native-community/progress-view' instead of 'react-native'. See 
at node_modules/react-native/Libraries/Utilities/warnOnce.js:27:2 in warnOnce
at node_modules/react-native/index.js:203:12 in module.exports.get__ProgressViewIOS
at app/index.js:489:2 in goog.globalEval
at app/index.js:1445:8 in env.evalLoad
at app/index.js:1690:0 in <global>
at node_modules/metro-runtime/src/polyfills/require.js:349:11 in loadModuleImplementation
at node_modules/metro-runtime/src/polyfills/require.js:201:44 in guardedLoadModule
at  in global code

SegmentedControlIOS has been extracted from react-native core and will be removed in a future release. It can now be installed and imported from '@react-native-community/segmented-control' instead of 'react-native'. See 
at node_modules/react-native/Libraries/Utilities/warnOnce.js:27:2 in warnOnce
at node_modules/react-native/index.js:225:12 in module.exports.get__SegmentedControlIOS
at app/index.js:489:2 in goog.globalEval
at app/index.js:1445:8 in env.evalLoad
at app/index.js:1690:0 in <global>
at node_modules/metro-runtime/src/polyfills/require.js:349:11 in loadModuleImplementation
at node_modules/metro-runtime/src/polyfills/require.js:201:44 in guardedLoadModule
at  in global code

Slider has been extracted from react-native core and will be removed in a future release. It can now be installed and imported from '@react-native-community/slider' instead of 'react-native'. See 
at node_modules/react-native/Libraries/Utilities/warnOnce.js:27:2 in warnOnce
at node_modules/react-native/index.js:234:12 in module.exports.get__Slider
at app/index.js:489:2 in goog.globalEval
at app/index.js:1445:8 in env.evalLoad
at app/index.js:1690:0 in <global>
at node_modules/metro-runtime/src/polyfills/require.js:349:11 in loadModuleImplementation
at node_modules/metro-runtime/src/polyfills/require.js:201:44 in guardedLoadModule
at  in global code 

Benjamin C01:11:08

@tony.kay I finally got it to work. Native base has changed a lot, so I replaced most of the components with their generic Box component. The other thing I had to change was this render-root function (on the left) to the one on the right:

Benjamin C01:11:50

Still not quite sure why the old function doesn't work. Later I will dig into it a little more.

tony.kay02:11:51

yeah, the typical js landscape: break everything every 2 months