Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jun 10 00:21

    dependabot[bot] on npm_and_yarn

    (compare)

  • Jun 10 00:21

    foxdonut on master

    Bump glob-parent from 5.1.1 to … Merge pull request #139 from fo… (compare)

  • Jun 10 00:21
    foxdonut closed #139
  • Jun 10 00:20

    dependabot[bot] on npm_and_yarn

    (compare)

  • Jun 10 00:20
    dependabot[bot] labeled #139
  • Jun 10 00:20
    dependabot[bot] opened #139
  • Jun 10 00:20

    foxdonut on master

    Bump glob-parent from 5.1.1 to … Merge pull request #138 from fo… (compare)

  • Jun 10 00:20
    foxdonut closed #138
  • Jun 10 00:20

    dependabot[bot] on npm_and_yarn

    Bump glob-parent from 5.1.1 to … (compare)

  • Jun 10 00:19
    dependabot[bot] labeled #138
  • Jun 10 00:19
    dependabot[bot] opened #138
  • Jun 10 00:19

    dependabot[bot] on npm_and_yarn

    Bump glob-parent from 5.1.1 to … (compare)

  • Jun 10 00:19

    dependabot[bot] on npm_and_yarn

    (compare)

  • Jun 10 00:19

    foxdonut on master

    Bump harp from 0.32.0 to 0.40.3… Merge pull request #137 from fo… (compare)

  • Jun 10 00:19
    foxdonut closed #137
  • Jun 10 00:19

    dependabot[bot] on npm_and_yarn

    (compare)

  • Jun 10 00:18

    foxdonut on master

    Bump harp from 0.32.0 to 0.40.3… Merge pull request #136 from fo… (compare)

  • Jun 10 00:18
    foxdonut closed #136
  • Jun 07 16:45

    dependabot[bot] on npm_and_yarn

    (compare)

  • Jun 07 16:45
    dependabot[bot] closed #135
Pieter Martin
@pietermartin
thanks, just wanted to make sure there is not some hidden logic I missed
James Ramm
@JamesRamm

Hi!
I have a small dilemma about effects in meiosis.
In all examples, effects are run off the states stream (e.g. states.map(state => effects.forEach(effect => effect(state)));), but often I need to conditionally run effects based on what was updated, which is not clear from the final states stream.

I could just run effects off the updates stream, but generally I need to know what the current state is (i.e. after the states stream has been updated) as well as what the last update was.

Is there a way I can run effects off the updates stream, but being sure that the scan to update the states stream has already been performed?

E.g

updates = stream();
const states = scan(merge, app.initial, updates)
const effects = [ (update) => {
    const currentState = states();
} ]

// Need to be sure that the effect runs after the scan
updates.map(u => effects.forEach(e => e(u))

Ha! Lol as I wrote that question I realised the very obvious answer....run effects off the states stream but just access the updates stream in the effect.
e.g.

const effects = [state=> {
   const lastUpdate = updates();
}]

states.map(s => effects.forEach(e => e(s)));

Since the stream itself is synchronous, I am right in assuming that the value returned by calling updates() would always be the last update (that led to the state that has been passed to the update function)?

Barney Carroll
@barneycarroll
Ha! Yes — very cool
James Forbes
@JAForbes

this should work, but a maybe more idiomatic way would be to explicitly mark both streams as dependencies

m.stream.merge([states, updates]).map( sideEffects )

Fred Daoud
@foxdonut
@JamesRamm sure you could use both streams, but, depending on your use case, @JAForbes can probably suggest a way for what you are trying to achieve, using only the states stream.. : - )
read: I'm interested to see how this would play out : - )
James Ramm
@JamesRamm
@JAForbes thanks that is indeed a better approach - it a makes explicit that you want the data from both streams and you do not need to worry about accessing one (or the other) in your side effect functions.
Side question - 'Meiosis' is pretty much the only functional/reactive state mgmt pattern I have seen for React. At least with clear tutorials/documentation online.
Has anyone come across any other patterns or ideas about using streams in React and how they might fit in, complement or improve Meiosis?
Arthur Clemens
@arthurclemens:matrix.org
[m]
@JamesRamm: You could use a stream library without Meiosis, if the state is simple or local
For this purpose I've created https://github.com/ArthurClemens/use-stream to let React work with steam libraries
Constantin Angheloiu
@cmnstmntmn
how cool is that @arthurclemens:matrix.org :thumbsup: !
Arthur Clemens
@arthurclemens:matrix.org
[m]
thanks!
robinchew
@robinchew
I wonder if there are any mobile developers here who's tried to apply meiosis on either kotlin, swift or dart.
James Forbes
@JAForbes
Yeah that'd be great to hear!
Fred Daoud
@foxdonut
:thumbsup:
robinchew
@robinchew
i guess we won't be hearing any. I basically want to know what's an equivalant to m.render in the Android and iOS world.
im supervising some mobile app development and im working with someone who prefers to use dart/flutter. He is going to employ the BLOC architecture. Here's a list of different state managements. https://flutter.dev/docs/development/data-and-backend/state-mgmt/options
Fred Daoud
@foxdonut
Re: BLoC architecture: I read some articles last night and I watched a video this morning, since I'm always interested in what's being done for state management
Unfortunately, nothing new there, it's essentially rearranged Redux
Patrik Johnson
@orbitbot
reactive programming isn’t really anything new in the mobile native dev world, perhaps more a question of the dev pedigree and age...
Patrik Johnson
@orbitbot
you have a lot more well established libs as alternatives, and depending on the platform some related concept might be adopted as a first party thing, such as kotlin coroutines in current android viewmodels
the analogy is closer to eg. flyd/mithril streams, in the coroutine case, as essentially you easily achieve databindings to UI references
Rx* is a reasonable generic tool with native stuff as well, as you can leverage threading and it’s not necessarily tied to the viewmodel lifecycle like in native android
Patrik Johnson
@orbitbot
having said all that, afaik flutter is basically just a UI wrapper, not sure what the related state management tools might be, don’t have time to go through the link to look
and with the above, fundamentally a lot of state management patterns are more alike than different. Also pretty difficult to tell what makes sense from a distance
robinchew
@robinchew
thanks for your inputs, i didn't expect you all to do the research for me. It's hard to tell from a distance as you say so I just gotta do it and see.
i still wonder whether meiosis is even possible on mobile as everything is so object-oriented and class-based.
robinchew
@robinchew
Without doing much redux, and comparing with meiosis, it just looks like redux keeps local state within each view, whereas meiosis has 1 mega state outside of the views.
Fred Daoud
@foxdonut
@robinchew fwiw I know some people who use Meiosis with React-Native.

I didn't expect you all to do the research for me

To your credit, you did not ask of anyone to do any work for you :) But I did so voluntarily, as I said I'm always interested to see what's out there for state management.

Patrik Johnson
@orbitbot
Don’t know if object orientation really matters, if you like you can still apply functional idioms by separating actions from class instance methods, but it might not be the best way to model anything of itself. The main thing with that in strongly enough typed languages is that you need to start writing interface classes if you want to do that cleanly, which very quickly turns into boilerplate heavy code
personally don’t necessarily feel that there is that much inherent value in being too strict about patterns, and it might be prudent to either wait and see what evolves, or then try to talk about domain modeling up front concretely, if the person you work with is able to
it’s a bit less common than I have inherently expected, to my surprise and IME
Patrik Johnson
@orbitbot
in my limited experience with redux, it may be that people write a lot of stuff by view, but it’s not a hard and fast rule. Additionally, fwict it’s hardly the only state mgmt approach that tends to take that approach by default, and the coroutine/viewmodel stuff mentioned before does that implicitly by deregistering handlers based on UI visibility
robinchew
@robinchew
Back to dart/flutter stuff, I came across this, https://medium.com/flutter-community/use-functional-widgets-in-flutter-to-reduce-boilerplate-code-9e815c2ddb94. With this and streams, I feel like I can do meiosis with dart/flutter, but I'm too lazy to implement though. I'm gonna see if I can convince a contractor to do it.
Pieter Martin
@pietermartin

Hi, I am looking at the meiosis routing helpers on mithril.
So we have a large existing app and we already have global routes defined,

m.route.prefix = '#!';
m.route(document.body, "/dashboards",
    {
        "/authentication/loginForm": {
            onmatch: function () {
                return CmMithrilGlobal.getMessages(['loginForm', 'resetPasswordForm']);
            },
            render: function () {
                return m(LoginForm);
            }
        },
        ...

So how can I plug in the meiosis mithril routes there?

m.route(
  document.getElementById("app"),
  "/",
  router.MithrilRoutes({ states, actions, App })
);

Thanks

Pieter Martin
@pietermartin

To add some more info, I have written a new page using the meiosis pattern

m.route(document.body, "/dashboards",
        ....
        "/netcm/planDiscrepancies": {
            onmatch: function (args, requestedPath) {
                CmMithrilGlobal.checkLoggedIn(requestedPath)
            },
            render: function () {
                return m(MainLayout, {body: m(PlanDiscrepancy2)});
            }
        },

PlanDiscrepancy2 is the new component, I have done all the routing working in there and it works well but I don't know how to get the parameters into the url?

Pieter Martin
@pietermartin
Ok, I got the params into the url calling locationBarSync, missed that somehow, but I still can't work out how to do it in reverse?
i.e. set the state.route from the url params?
Fred Daoud
@foxdonut
Hi @pietermartin
your setup looks good
not sure what you mean by set the state.route from the url params? the state should update automatically when you navigate to a different route
Pieter Martin
@pietermartin

Hi, @foxdonut
Yes I mean updating the state when navigating to a different route.
It looks to me like that happens in the onmatch that router.MithrilRoutes({ states, actions, App }) generates?
However I have not worked out how to include router.MithrilRoutes({states, actions, App}) in my application seeing as the route setting up code already exists and does not have access to my new components {states, actions, App}

Currently the routing code is plain, it does not included meiosis MithrilRoutes
What I have is old school,

        "/netcm/planDiscrepancies": {
            onmatch: function (args, requestedPath) {
                CmMithrilGlobal.checkLoggedIn(requestedPath)
            },
            render: function () {
                return m(MainLayout, {body: m(PlanDiscrepancy2)});
            }
        },

I suspect I need some of router.MithrilRoutes``onmatch magic, just not sure how to get it into my existing application's setup?
Thanks

Pieter Martin
@pietermartin
I got it to work for now by manually updating the state in onmatch,
import {Route, router} from "./modules/netcm/discrepancies/plan2/planDiscrepancy2Routes";
const {states, actions} = PlanDiscrepancyController();

m.route.prefix = '#!';
m.route(document.body, "/dashboards",
...
        "/netcm/planDiscrepancies": {
            onmatch: function(args, requestedPath) {
                CmMithrilGlobal.checkLoggedIn(requestedPath)
                actions.navigateTo(Route.PlanDiscrepancy({accordion: args.accordion, view: args.view}));
            },
            render: function () {
                return m(MainLayout, {body: m(PlanDiscrepancy2, {states: states, actions: actions})});
            }
        },
...
Fred Daoud
@foxdonut

@pietermartin glad you got it working!

Now that I understand your situation a little better, I just wanted to point out that you might try this so that you don't have to do things manually:

m.route(document.body, "/dashboards",
    {
        "/authentication/loginForm": { ... }
        // other existing routes...
        , ...router.MithrilRoutes({ states, actions, App })
    }
);
App would be your top-level component for the routes you want to handle with meiosis routing
N.B. if what you have currently is working well for you, that is fine of course. I just wanted to tell you about the above setup in case you add more meiosis routes and don't want to do things manually for every one.
Pieter Martin
@pietermartin

Ok, I spoke to early, defining const {states, actions} = PlanDiscrepancyController(); globally messed up the idea of PlanDiscrepancy2 being a closure component.
We coded our whole app with closure components, so we never need to do clean up code when navigating away from a component. With the state global it kinda messes with our pattern.

For now I have removed the onmatch logic as can't get it to work. and instead added the logic to the view method,

function PlanDiscrepancy2(ignore) {

    const {Routing} = MeiosisRouting.state;
    const {states, actions} = PlanDiscrepancyController();

    return {
        oninit: ({attrs: {}}) => {
            actions.retrieveNetwork();
            actions.retrievePlanDiscrepancyTree();
        },
        view: ({attrs: {}}) => {
            let params = m.route.param();
            actions.navigateTo(Route.PlanDiscrepancy({accordion: params.accordion, view: params.view}));
            const state = states();
            const routing = Routing(state.route);
            const {accordion, view} = routing.localSegment.params;
            return m("div. ...")
        }
    }
}

I'll keep at its probably better to do the url -> state sync in onmatch

Thanks

Fred Daoud
@foxdonut
welcome, sounds good
Pieter Martin
@pietermartin

Another update({}), spoke to early last time also, setting the state from the url in view does not work.
Turns out that m.route.param() does not yet see url values set viarouter.locationBarSync(state.route);

So my latest strategy is
index.js

m.route.prefix = '#!';
m.route(document.body, "/dashboards",
    {
        "/authentication/loginForm": {
            onmatch: function () {
                return CmMithrilGlobal.getMessages(['loginForm', 'resetPasswordForm']);
            },
            render: function () {
                return m(LoginForm);
            }
        },
        ...
        "/netcm/planDiscrepancies": {
            onmatch: function(args, requestedPath) {
                CmMithrilGlobal.checkLoggedIn(requestedPath)
                $.Topic('/netcm/planDiscrepancies').publish({args, requestedPath});
            },
            render: function (vnode) {
                return m(MainLayout, {body: m(PlanDiscrepancy2)});
            }
        },

planDiscrepancy2.js

function PlanDiscrepancy2(ignore) {

    const {Routing} = MeiosisRouting.state;
    const {states, actions} = PlanDiscrepancyModel();

    let onmatch = (message) => {
        let args = message.args;
        let requestedPath = message.requestedPath;
        let r = Route.PlanDiscrepancy(args);
        actions.navigateTo(r);
    };

    return {
        oninit: ({attrs: {}}) => {
            $.Topic('/netcm/planDiscrepancies').subscribe(onmatch);
            let params = m.route.param();
            let r = Route.PlanDiscrepancy(params);
            actions.navigateTo(r);
        },
        ondestroy: () => {
            $.Topic('/netcm/planDiscrepancies').unsubscribe(onmatch);
        },
        view: ({attrs: {}}) => {
            const state = states();
            const routing = Routing(state.route);
            const {accordion, view, treeId} = routing.localSegment.params;
            return m("div"...);
        }
    }
}

export default PlanDiscrepancy2;

So I setup the state in the closure components oninit and using a jquery pub/sub jol I notify the component about onmatch and set the state from the url.

So far so good.
Thanks

Fred Daoud
@foxdonut
:thumbsup: