These are chat archives for jdubray/sam

28th
Nov 2016
Jean-Jacques Dubray
@jdubray
Nov 28 2016 01:10
I always wanted to publish a more substantial, full stack, project to show the potential of the SAM pattern. Here it is!
I took the bootstrap Sample Blog and transformed its implementation into a single page modular implementation (with a simple component model).
The back-end fetches the Atom feed of your choice and the SAM pattern renders it into a SPA.
Here is the code
It also supports browser history
Here is an example of the of the component model I picked
Vincent Jo
@chiwoojo
Nov 28 2016 02:46
has anyone done SAM implementation for React Native? I've been working on it and my apps is getting more complicated and the React-only model isn't going to survive much longer..
Fred Daoud
@foxdonut
Nov 28 2016 04:27
@jdubray sounds great, looking forward to having a look! :star:
@chiwoojo try latest Meiosis with this code
Edward Mulraney
@edmulraney
Nov 28 2016 09:09

@foxdonut 1) you don't try to horseshoe side effects into an "action" object (à la redux)

What do you mean?

Edward Mulraney
@edmulraney
Nov 28 2016 09:20

2) you restrict model mutation to a well-defined and clearly-controlled part of the reactive loop (SAM/model.present)

Agreed - same as redux (store.dispatch)

Fred Daoud
@foxdonut
Nov 28 2016 12:50
@edmulraney I was referring to some redux examples I've seen where you have e.g. a promise property on an action and that means a middleware "knows" how to deal with that promise, dispatching _PENDING and _SUCCESS actions when running the promise.
Edward Mulraney
@edmulraney
Nov 28 2016 12:51
yeah thats a convenience wrapper - you can add that into a SAM loop too if you wanted. but you could just use redux-thunk which imposes no convenience upon calling an async api for you
personally I don't see them used too often, most common tends to just be redux-thunk
i think i probably fall down on your side too of preferring to manually state these things myself
present(fetching)
api.get().then(present(success)).catch(present(fail))
Fred Daoud
@foxdonut
Nov 28 2016 13:15
agreed
@edmulraney I did a small proof-of-concept of implementing SAM with redux. Do you think redux is SAM-compatible?
Does redux still require a type property on actions? Seems like this limits you e.g. you couldn't use the union-type library with redux.
Edward Mulraney
@edmulraney
Nov 28 2016 14:14
redux is definitely SAM compatible
SAM offers a better handling of effects IMO. but projects like redux-logic, redux-observable, etc. make it more than managable
Edward Mulraney
@edmulraney
Nov 28 2016 14:38
redux out of the box is SAM compatible
Fred Daoud
@foxdonut
Nov 28 2016 14:50
@edmulraney how does nap() work with redux?
Edward Mulraney
@edmulraney
Nov 28 2016 15:14
store.subscribe(function nap() {
  const model = store.getState()
  if (model.shouldFetchUsers) {
    ajax.get(api.url.users)
      .then(users => store.dispatch({type: "USERS_RECEIVED", users})
      .catch(error => store.dispatch({type: "USERS_FAILED", error}))
  } 
}
something like that. rudimentary example of automatically fetching users
you can have whatever automatic actions you need in there based of model state
there are two other places you could do it
assumed using react: componentDidUpdate
or when you createStore(... middleware) add a nap function as your middleware
Edward Mulraney
@edmulraney
Nov 28 2016 15:23
const nap = store => next => action => {
  const model = store.getState()
  if (model.predicate || action.type === "predicate") {
    ajax.get().then(store.dispatch(whatever)).catch(...)
  }  
}
Fred Daoud
@foxdonut
Nov 28 2016 15:57
I see.. thanks :thumbsup:
Edward Mulraney
@edmulraney
Nov 28 2016 16:14
@foxdonut what are some instances where you've needed nap?
Zach Dahl
@schtauffen
Nov 28 2016 16:14
middleware is a neat concept and allows great flexibility. I chose to use that pattern when building Jackalope
Edward Mulraney
@edmulraney
Nov 28 2016 16:14
it really is, safe flexibility
Zach Dahl
@schtauffen
Nov 28 2016 16:15
I think nap is rarely necessary tbh, but when it is it is nice to have a defined way to handle automatic actions when necessary.
Edward Mulraney
@edmulraney
Nov 28 2016 16:16
agreed
devin ivy
@devinivy
Nov 28 2016 16:18
i agree that it's important for completeness's sake– the totality of the application itself needs to be able to trigger actions, not just components of an application.
Fred Daoud
@foxdonut
Nov 28 2016 16:22
most common is with validation. if there are no errors, nap() triggers the action to actually save the data to the server. not saying it's the only way, but it works well.
Edward Mulraney
@edmulraney
Nov 28 2016 16:27
so like a FORM_SUBMITTED action which eventually triggers SAVE_FORM_DATA effect? cool that makes sense
Edward Mulraney
@edmulraney
Nov 28 2016 16:41
how do you handle local state in sam? say i just want a component which can toggle its visibility
devin ivy
@devinivy
Nov 28 2016 16:48
i usually keep that state within a component when it makes sense. i ask myself: if i were to be able to "save my session" then return to the app later, would it matter if i can render an application directly into this state or not? if it doesn't matter, i think it's okay to put it in local state.
Zach Dahl
@schtauffen
Nov 28 2016 16:48
personally I would have a variable in model and use an action to set it. I'm also of the opinion that model should track input values to be completely compliant, though, so I might be a little crazy
devin ivy
@devinivy
Nov 28 2016 16:51
usually, depending on the platform you're using, it's not hard to port small bits of state from a component into the app model, so it can be done progressively. you run into trouble there when you have complexly determined state more than when you have "lots of state." i think it's much less the amount and more the complexity.
Fred Daoud
@foxdonut
Nov 28 2016 17:31
I use somewhat of a "hybrid" approach, meaning that with Meiosis and the concept of nesting components, a component can manage its own state, this is decoupled from the rest of the app but the state is still part of the single-state tree. so the parent nests the child component's model at a level in the single state tree, but the parent doesn't know or care about the details of what's in the child component's model. The child component only deals with its own state and does not know or care about the nesting, it does not need a reference to where it is nested.
devin ivy
@devinivy
Nov 28 2016 17:33
@foxdonut what about lists of components?
Fred Daoud
@foxdonut
Nov 28 2016 17:33
In this temperatures example, the temperature component only knows about its own value and units property, but the parent creates two instances and nests one at temperature.air, the other at temperature.water within the single state tree.
@devinivy yes good question, the random gif example demonstrates this, scroll to the bottom and see the Random Gif List, you can Add and Remove components. The random-gif component used is not changed, whether it is used in the list, as well as in the Pair and Pair of Pairs.
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 18:52
@foxdonut thanks I will try to integrate with Meiosis
this will allow me to keep a global model is that correct?
and global state?
Fred Daoud
@foxdonut
Nov 28 2016 19:00
@inrix-vincent-jo correct
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 20:31
sweet.. I will give it a go thanks
Edward Mulraney
@edmulraney
Nov 28 2016 21:53
@schtauffen it seems like it will become difficult to maintain this state when you have an enterprise/large app
say you use accordions that have a expanded/contracted state, and navigation that you can show/hide, etc.
i suppose its the inconvenience of having to through the rigmarole of a functional loop (SAM/redux/etc.) to do a simple local state change you have no intention of caching/storing
Edward Mulraney
@edmulraney
Nov 28 2016 22:07
or animations
@foxdonut i had a look at your repo but i couldn't grok it from first glance. feel like i'd need to spend some time looking through that repo and meiosis
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:11
@edmulraney I image that for enterprise apps there are many different SAM components that contain a main SAM component
like the accordion UI component can be managed by SAM.. but it's probably a simple component so it wouldn't need the whole architecture to build it
but for something more complex I figure you can have a parent-child relationship SAM components
Edward Mulraney
@edmulraney
Nov 28 2016 22:13
you need to be able to compose SAM components i suppose
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:13
yea
that's what I think
Edward Mulraney
@edmulraney
Nov 28 2016 22:14
same as react higher order components
problem is buying into the whole SAM loop for something trivial like expand/collapse component
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:14
yea, I remember JJ saying that the SAM loop is a very deliberate process so it is not needed for something simple
Edward Mulraney
@edmulraney
Nov 28 2016 22:22
its tricky to visualise reusable components without vdom lib (react, etc.)
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:25
you can have a html template that can be reusable in some examples JJ put out
I think the fullstack one that he did uses reusable html templates
I glanced through it but I could be wrong
so* I could be
Edward Mulraney
@edmulraney
Nov 28 2016 22:29
i think if its purely presentational (not interactive) its trivial:
function wrapper(component) {
  return `<div class="wrapper">${component}</div>`
}
but if it needs to be interactive (onclick etc.) it gets tricky
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:30
oh yea, you are right
I remember running into this
so I started to experiment with Inferno JS
so much easier to have onclick and stuff like that with it
Edward Mulraney
@edmulraney
Nov 28 2016 22:31
yeah its simple with inferno/react/etc - i suppose there isn't really much value in me figuring it out in vanilla - ill never need it
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:32
probably not... unless you want to write code without a library and just do it in JS
Fred Daoud
@foxdonut
Nov 28 2016 22:32
agreed. meiosis works with vanilla because I didn't want a vdom library to be required, but it's easier with a vdom library.
Edward Mulraney
@edmulraney
Nov 28 2016 22:34
interesting that its only really local state that it proves difficult for. firing actions from vanilla js templates is simple if you just bind the actions to a global (i.e. window)
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:37
I also find it kind of not clean over vdom syntax
function wrapper(component) {
  return `<div class="wrapper" onclick=actions.propose({ add: 1 })>${component}</div>`
}
Edward Mulraney
@edmulraney
Nov 28 2016 22:40
yeah you can't pass the action into the function via props or something
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:42
import actions from './actions';
function wrapper(component) {
  return (<div class="wrapper" onclick={() => actions.propose({ add: 1 })}>{component}</div>)
}
I guess it's not that much different..
it's more a personal preference for me to see an actual function rather than function inside of string..
Edward Mulraney
@edmulraney
Nov 28 2016 22:44
yeah static analysis and all that
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:44
I think I'm missing a couple of other reasons why I prefer vdom over simple html.. because I started to create this app in plain js and I really wanted to keep it plain js because I thought that was cool
but a few reasons got me experimenting with Inferno.. I'm pretty happy with where I ended with it
Edward Mulraney
@edmulraney
Nov 28 2016 22:45
inferno is great
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:45
yea I like it a lot
basically same thing as react but I heard the code is written better
Edward Mulraney
@edmulraney
Nov 28 2016 22:45
this is one way to use dom directly but with react/inferno style bindings/handlers:
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:47
whoa that's really neat
If I found this before, I would have tried this first
because it sucked giving up the simple html templates
Edward Mulraney
@edmulraney
Nov 28 2016 22:48
ive been looking at the choo framework recently that uses it too: https://github.com/yoshuawuyts/choo
very cool project
explicit effects, simple router, tiny api
Vincent Jo
@inrix-vincent-jo
Nov 28 2016 22:49
seems like Redux
is baked into it
reducers and state
Edward Mulraney
@edmulraney
Nov 28 2016 22:50
some of the principles
it picks up where redux misses out
i.e. explicit effects control
Jean-Jacques Dubray
@jdubray
Nov 28 2016 23:45

@edmulraney @inrix-vincent-jo

problem is buying into the whole SAM loop for something trivial like expand/collapse component

no I would not do that. HTML is not 100% declarative, so you cannot express V = f(M) with a 100% precision

Edward Mulraney
@edmulraney
Nov 28 2016 23:45
interesting
Jean-Jacques Dubray
@jdubray
Nov 28 2016 23:45
You might however notify the model where you are if that information is important (say if you needed to regenerate that page as you come back to it)
Take something as trivial as a date picker, my understanding (maybe I am wrong) is that you have have to run something like $('myBeautifulDatePicker').datepicker() ;
There is no amount of V = f(M) that will do that for you
Same thing for managing the history, you could manage the history with SAM, but is it really worth it? maybe.
Jean-Jacques Dubray
@jdubray
Nov 28 2016 23:51
Please note that even React does some direct DOM manipulation (e.g. spinner)
Edward Mulraney
@edmulraney
Nov 28 2016 23:51
yeah - only way datepicker shows and maintains V=f(M) is if you keep show/hide state in model - good point