Git Product home page Git Product logo

Comments (6)

slorber avatar slorber commented on May 26, 2024 1

@evancz understood that and will post to the discuss group instead. I'd like to explain my ideas better than that before but I don't have time to do so right now.

I have 2 years of production experience with React and something similar to Flux (actually we invented flux before it come out because we have experience with event-sourcing / cqrs and ddd). What my experience show me is that generally when state is updated in a React / Flux application it is mainly for 2 reasons:

Local component update

In this case, only the component has interest in that state mutation and nobody else cares

I mean in React generally if we implement a simple counter we would put the counter value in the component state.

In ELM what I've seen so far is that an event is fired, and wrapped, and wrapped, and wrapped, goes to the "main mailbox" and then is injected into the main update function which propagates progressively to the update function of the counter, and then we redisplay everything.

I like the ELM model better as it permits to externalize the state of the counter to a model, while in the React world we would tend to couple that logic to the view framework. However ELM system has more boilerplate but I'm ok with that as the typesystem is better than javascript

Non-local component update

In this case, the counter should be able to increment its local state, but other views/widgets in the app should be able to update themselves too according to the increment events (like in the weird business rule I designed above)

With React, for that you would use Flux or something similar. To be able to support complex setups like lists of pairs of counters etc, you would probably fire increment actions with a counterId.

The same action/event can be listened from many places (or "stores"/"reducers") to update the state in multiple places.

With ELM, all the examples I've seen so far with counters only mutates the state in a single place: the local counter model. So if we need to plug a new view that depends in the counter increment events, it is not clear how ELM should be used to solve that problem. This need does not happen often in simple examples like TodoMVC or list of counters, but is a real need in complex applications

Imagine a setup like that, where what I want to do is add that weird-count-value div:

<div class="list-of-list-of-counters"></div>
   <div class="list-of-counters">...</div>
   <div class="list-of-counters">...</div>
   <div class="list-of-counters">...</div>
</div>
<div class="pair-of-counters"></div>
   ...
</div>
<div class="weird-count-value"></div>
   something between 0 and 3, based on the interactions with the counters
</div>

I understand that in the ELM counter examples, the events are actually bubbling to the "main mailbox" (at least it is how I suppose StartApp.Simple works). So I guess anyone can plug a new update function here to listen to the events (or signals) and compute a new model called WeirdCountValue from the signals.

However in the examples I've seen, the thing bothering me is that when the mailbox receives the signal they are wrapped, so if I want to know how much increments there are globally in my app (for example), I have to unwrap the actions (sometimes multiple time) before even knowing it's an increment or decrement.

In CQRS / eventsourcing the point is that you should be able to look at some kind of global event log and be able to compute new models from that, without having to understand the implementation details of the existing app. The WeirdCountValue model should not have to assume anything from how the counters are weirdly nested in my app, but should just be able to listen for increments and decrements.

This stuff is easy with Flux because we don't wrap actions as they bubble to the top so we can just plug a new listener like that:

var weirdCountValue = 0;

SomeFluxEventBus.listen(function(event) {
   if ( event.name === "INCREMENT_COUNTER" ) {
      if ( weirdCountValue < 3 ) {
          weirdCountValue = weirdCountValue + 1;
      } 
   }
   if ( event.name === "DECREMENT_COUNTER" ) {
      if ( weirdCountValue > 0 ) {
          weirdCountValue = weirdCountValue - 1;
      } 
   }
});

I would like to do the same with any counter example you've done but I don't know which is the idiomatic way.

I thing the wrapping of actions is good for local state but not really helpful it the app model should be updated in multiple places.

Summary

What I think I want is a mailbox that receives directly actions like Increment or Decrement instead of wrapped actions.

Does it make any sense? What is the idiomatic way to achieve that in ELM?

from elm-architecture-tutorial.

evancz avatar evancz commented on May 26, 2024

Check out my response in this thread. I suspect that's what you want. If not, do you mind emailing elm-discuss with a very specific example of what you need to do? From there, we can help you with the exact code you need.

This is kind of a newer pattern, so it's not "an official thing" by any means. But I bet it'll do what you want.

from elm-architecture-tutorial.

slorber avatar slorber commented on May 26, 2024

Hi,

If you reference the pattern update : Action -> Model -> ( Model, Effects Action, whateverYouWant ) it does not look to solve the problem I try to figure out.

The problem is not in the update function for me, the problem is that I want somehow all counter actions to be fired in a "global" way (like a global business events bus) and to be able to listen from any increment from anywhere in my app without having to touch the existing code: just plug a view and listen from increments.

I will try to make an example but I don't have time right now to do so :'(

from elm-architecture-tutorial.

evancz avatar evancz commented on May 26, 2024

For some additional context, sharing this question with elm-discuss will get it in front of more people who can help out. More people read that.

Also, the thing you want to do feels like a weird thing to me. It sounds like you have a very specific scenario in mind that is motivating this line of questioning. Can you describe that scenario in the elm-discuss post? From there, I think we can help more. I feel like this may be an XY problem where the expected solution may not be the one that makes sense in Elm. I am not sure at all though! Knowing the particular scenario will help us figure out the best way to achieve it in Elm.

from elm-architecture-tutorial.

mbylstra avatar mbylstra commented on May 26, 2024

@sorber did you post this to elm-discuss? Could you please paste a link to the thread here if you did?

from elm-architecture-tutorial.

slorber avatar slorber commented on May 26, 2024

@mbylstra no I did not. Don't hesitate to do so if you want and i'll be happy to join the conversation.

Also note some interesting discussions going on there: jarvisaoieong/redux-architecture#1

from elm-architecture-tutorial.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.