[elm-discuss] Re: Tour of an open-source 4,000 LoC Elm SPA

2017-05-08 Thread Erik Lott
A great many folks are going to be thankful for this SPA example... You are 
a saint good sir.

On Monday, May 8, 2017 at 3:59:16 AM UTC-4, Richard Feldman wrote:
>
> I get asked if there are any sizeable open-source Elm SPA examples out 
> there...so I made one!
>
> Hope it's useful: https://dev.to/rtfeldman/tour-of-an-open-source-elm-spa
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] New guidelines for posting on Elm-discuss

2017-05-07 Thread Erik Lott
Noah, a general code of conduct is a great idea, even if nothing other than 
to point at if a sensitive topic begins to get heated. Great job bud.

I tend to have the same opinion of Slack (we use it in house). Slack is an 
indispensable collaboration tool, but it makes a less than perfect message 
board - everything being so ephemeral. I think this is why most communities 
tend to have both. They're both solid tools for their intended usage.

Keep it up!

On Sunday, May 7, 2017 at 7:43:27 AM UTC-4, Noah Hall wrote:
>
> Please move this discussion to another thread. 
>
> On Sun, May 7, 2017 at 1:29 PM, Rex van der Spuy  > wrote: 
> > 
> > 
> > On Sunday, May 7, 2017 at 1:06:14 AM UTC-4, Dave Rapin wrote: 
> >> 
> >> The problem with slack is that discussions are lost after you hit their 
> >> limit (which wasn't terribly high last time I checked). So instead of 
> >> finding / googling for an answer / question that had previously been 
> >> covered, you must ask again, which is of course async and therefor more 
> time 
> >> consuming. 
> >> 
> >> I don't mean to seem anti-social, but if I'm in the middle of solving a 
> >> problem and run into an issue, I reach for Google way before I'd post 
> on 
> >> Slack. Slack just feels like a black hole where information goes to 
> die. 
> > 
> > 
> > I agree 100%. 
> > The other problem is that there are so many channels that you never know 
> > where to post your question. 
> > And, you have to hope there is someone online at that very moment with 
> the 
> > skills or interest to help you, otherwise your question scrolls away 
> into 
> > eternity. 
> > So far, I've found Reddit to be the best forum for Elm Q - questions 
> > always net some big fish and petty quibbles get down-voted out of the 
> way. 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> Groups 
> > "Elm Discuss" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> an 
> > email to elm-discuss...@googlegroups.com . 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Poll for Intermediate to Advanced topics that people struggle with

2017-05-02 Thread Erik Lott
For the folks who are struggling with authentication, are you having issues 
with authentication in general (elm, javascript, other), or is there an 
issue implementing authentication specifically in Elm? 

On Tuesday, May 2, 2017 at 10:10:03 AM UTC-4, Alan McCann wrote:
>
> I echo Peter Damoc's entry + authentication (e.g. JWT)
>
> On Monday, April 24, 2017 at 10:06:53 AM UTC-4, Jeff Schomay wrote:
>>
>> Hello,
>>
>> I am considering doing some training material on working with Elm in 
>> production.  I want to focus on areas that people struggle with after they 
>> are already familiar with Elm.  What concepts continue to confuse you? 
>>  What product requirements have been difficult to achieve with Elm?  What 
>> is most painful about your Elm codebase?
>>
>> Some topics I have already thought of:
>>
>> - decoders
>> - debouncing (http autocomplete input field for example)
>> - scroll to element
>> - testing
>> - unwieldy update functions
>> - api design
>>
>> If you have anything you'd like me to consider, please add it to the 
>> list.  Thank you!
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Ports seem contrived when trying to format a value as money

2017-04-30 Thread Erik Lott
Noah is right. You don't want to reach for Native for this type of 
integration. If this can't be smoothly integrated with ports (we've all 
felt that pain), the next best option is to write the elements of the 
plug-in that you need in elm.

On Sunday, April 30, 2017 at 1:37:04 PM UTC-4, Noah Hall wrote:
>
> Witold, with all due respect, I am one of the people who has written 
> the _most_ Native code. I know a thing or two about it. You do not 
> need to lecture me, and my warning should be heeded. 
>
> Like I said, there are _some_ cases where a Native binding makes 
> sense. They are few and far between.  These problems are best 
> discussed on Slack, where we can drill down into the exact use case. 
> For example, is it only one currency format? If it is, re-writing in 
> Elm should be trivial. 
>
> On Sun, Apr 30, 2017 at 7:30 PM, Witold Szczerba  > wrote: 
> > Noah, this is exactly the kind of problem to be solved by native 
> binding. 
> > Dwayne wants to use his formatting library. This is a classic example of 
> > pure function. Nothing is going to crash if you wrap exception in Result 
> and 
> > check types. 
> > 
> > Good advices of self reimplementig everything from scratch in Elm or 
> using 
> > subscriptions for pure functions is nothing but making Elm people suffer 
> > instead of getting things done. 
> > 
> > Native bindings are not bad per se. Just use it wisely, be pragmatic or 
> we 
> > will read another "Moving on", by Dwayne Crooks" this time. 
> > 
> > 30.04.2017 7:07 PM "Noah Hall"  
> napisał(a): 
> >> 
> >> Witold, this it not the advice that we give to people exploring such 
> >> problems in Elm. There are many reasons why Native bindings are bad. A 
> >> single error in your JS will cause the _entire_ application to crash 
> >> unrecoverably. Wrapping things as a result will not help you catch 
> >> those errors. Writing carefully thought out and tested code will. 
> >> While there are cases where a Native function helps out a lot, it 
> >> should _never_ be the first thing to reach for. 
> >> 
> >> 
> >> Dwayne, I suggest discussing things on the Elm Slack. It will be 
> >> easier to get to the exact use case you have for your formatting 
> >> issue. 
> >> 
> >> 
> >> On Sun, Apr 30, 2017 at 7:03 PM, Witold Szczerba  > 
> >> wrote: 
> >> > Ports and subscriptions are for executing actions with effects, in my 
> >> > opinion. Native bindings for pure functions are nothing bad. Just 
> keep 
> >> > away 
> >> > from exceptions, use Result in case of possible troubles. 
> >> > 
> >> > 30.04.2017 4:00 PM "Dwayne Crooks"  
> napisał(a): 
> >> >> 
> >> >> Thanks guys. 
> >> >> 
> >> >> I explored Noah's approach to see how the solution would turn out. 
> But 
> >> >> I 
> >> >> didn't like it. The code change required to format a list of floats 
> as 
> >> >> money 
> >> >> is ridiculous. Here's what I started with 
> >> >> 
> >> >> 
> https://gist.github.com/dwayne/550341a5b27ba3c03ce7eba92d33873d#file-0-start-elm.
>  
>
> >> >> And here's what I ended up with 
> >> >> 
> >> >> 
> https://gist.github.com/dwayne/550341a5b27ba3c03ce7eba92d33873d#file-1a-useports-elm,
>  
>
> >> >> 
> >> >> 
> https://gist.github.com/dwayne/550341a5b27ba3c03ce7eba92d33873d#file-1b-useports-html.
>  
>
> >> >> 
> >> >> P.S. The solution still doesn't quite work because all money 
> receives 
> >> >> the 
> >> >> first incoming subscription message causing them to display the same 
> >> >> formatted value. I didn't bother to fix it because the solution is 
> bad 
> >> >> enough. 
> >> >> 
> >> >> I think we can safely rule out ports. Noah, do you have any thoughts 
> on 
> >> >> the code? Did I miss anything? 
> >> >> 
> >> >> That leaves us with: 
> >> >> 
> >> >> Using a Native module. (Looks like the best compromise for my needs 
> in 
> >> >> the 
> >> >> short-term.) 
> >> >> Rewrite in pure Elm. (Looks like the best long-term solution.) 
> >> >> 
> >> >> Next step: I will write up a Native solution and see how that goes. 
> >> >> 
> >> >> -- 
> >> >> You received this message because you are subscribed to the Google 
> >> >> Groups 
> >> >> "Elm Discuss" group. 
> >> >> To unsubscribe from this group and stop receiving emails from it, 
> send 
> >> >> an 
> >> >> email to elm-discuss...@googlegroups.com . 
> >> >> For more options, visit https://groups.google.com/d/optout. 
> >> > 
> >> > -- 
> >> > You received this message because you are subscribed to the Google 
> >> > Groups 
> >> > "Elm Discuss" group. 
> >> > To unsubscribe from this group and stop receiving emails from it, 
> send 
> >> > an 
> >> > email to elm-discuss...@googlegroups.com . 
> >> > For more options, visit https://groups.google.com/d/optout. 
> >> 
> >> -- 
> >> You received this message because you are subscribed to the Google 
> Groups 
> >> "Elm Discuss" group. 
> >> To unsubscribe from this group and stop receiving emails from 

Re: [elm-discuss] Re: Moving on

2017-04-30 Thread Erik Lott

>
>  I'm going to call out the air of ungratefulness and animosity in this 
> thread. Evan is giving you software for free, and it's software that's good 
> enough that you invest your time into writing it and commenting about it. 
> You should not expect Elm to move at the same pace as Angular (backed by 
> Google) or React (backed by Facebook). Calling out that you want something 
> done faster or differently, when you are not a financial backer or core 
> contributor (to be fair, there aren't any of those besides Evan), comes off 
> as extremely petulant.


Respectfully, nobody forced Evan to release and promote a programming 
language; the community that's formed around Elm is entirely of his own 
making. If there is a feeling of animosity in the community and Evan wants 
to dedicate resources to improving it, he can choose to... or he can choose 
not to... that's his choice, but the atmosphere of the community will in 
part be a reflection of how he is allocating his time and energy towards 
supporting and maintaining it. 



On Sunday, April 30, 2017 at 11:43:30 AM UTC-4, Max Goldstein wrote:
>
> First, I'm going to call out the air of ungratefulness and animosity in 
> this thread. Evan is giving you software for free, and it's software that's 
> good enough that you invest your time into writing it and commenting about 
> it. You should not expect Elm to move at the same pace as Angular (backed 
> by Google) or React (backed by Facebook). Calling out that you want 
> something done faster or differently, when you are not a financial backer 
> or core contributor (to be fair, there aren't any of those besides Evan), 
> comes off as extremely petulant.
>
> Second, as for elm-community hosting the "greylisted" packages. I'm a core 
> member of elm-community, although obviously I don't speak for the group and 
> opinions are subject to change. I think that elm-community is doing a good 
> job of providing high-quality packages, which largely means they are 100% 
> Elm and have the reliability and free distribution that comes from that. 
> Almost all of our packages are in maintenance mode, stewarded for people 
> who left the community but who wrote useful packages that need to keep pace 
> with language version bumps (oh hello original thread topic). With a small 
> number of exceptions, most of our packages aren't actively developed.
>
> Third, regardless of who hosts the greylist, there are other problems. 
> When Evan removed the old graphics library from core and spun it off as a 
> separate package, he inadvertently added or multiple 
>  runtime 
>  errors 
>  (or perhaps the 
> surfaced later). This was a well-used library with native code, meant to 
> not change as it was extracted, by Elm's creator, and runtime errors still 
> happened. It is very easy to break everything that makes Elm nice with 
> native code. Using ports means that you're writing more-or-less normal 
> JavaScript, and it's yours to debug, lint, and fit to your needs, rather 
> than be stuck on a broken library. The open source dream of a project with 
> 100 stars and recent commits is appealing, but what happens during the 
> bring-up when no such project exists? What happens if it never does? What 
> happens if multiple projects look good?
>
> Fourth, web components were briefly mentioned. Richard gave a talk on 
> these  last year and it 
> seems like everything you need already works.
>
> Fifth and finally, to say something positive. (*If you're skimming, 
> please read this part.*) The greylist is built on the idea that the best 
> way to help is by writing code. Instead, let me suggest a collection of 
> markdown documents that research a particular proposed addition and say why 
> it would be useful. This is like doing the lit review before getting to 
> work, and will be helpful to both Evan, anyone pressing ahead with the 
> greylist, any anyone on the list confused as to what a task port is (for 
> example). I think these documents should, for a topic X, define X, say why 
> X is useful, describe the best way(s) to do X in Elm today, describe how 
> other ML-family and JS-ecosystem languages do X, and finally include a 
> brief, "first draft" of an interface or API for X in Elm. I think this will 
> work well for "web platform" things (audio playback, binary data) much 
> better than language features (type classes).
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Moving on

2017-04-26 Thread Erik Lott

>
> Better javascript interop to allow the community to provide the missing 
> web APIs and effect managers (task ports have been mooted on several 
> occasions)


I'd much rather have the web APIs available natively within Elm, so that 
javascript interops are minimal/unnecessary. 

On Wednesday, April 26, 2017 at 7:08:08 PM UTC-4, Oliver Searle-Barnes 
wrote:
>
> I've been using Elm for about 10 months now and have had an app in 
> production for the last 2, I share the general feeling of this thread. 
>
> I've addressed Evan directly here because it's impossible not to when 
> discussing these topics, I hope my thoughts are taken as sincere and full 
> of respect.
>
> Currently under development are: Elm the language, Elm the web platform 
> APIs, Elm tooling and effect managers. Evan is an absolute hero for taking 
> on the challenge to reimagine and build all of these different aspects of 
> web development and his success to date has inspired a lot of enthusiasm in 
> this fledgling community. The challenge can not be overstated though, this 
> is a gigantic undertaking, and it currently feels like too much for a 
> single individual. 
>
> It seems clear that the community has many experienced and talented 
> developers within it's ranks. They've all bought into Evan's vision and I 
> believe would be willing to go to great lengths in support of it. While I 
> can understand that Evan wants to retain control over what represents his 
> gold standard there does seem to be an opportunity to help other developers 
> help Evan. At a practical level I see two parts to this:
>
> 1) Better javascript interop to allow the community to provide the missing 
> web APIs and effect managers (task ports have been mooted on several 
> occasions)
>
> 2) A development process that encourages the use of packages from the 
> wider community _before_ they've had sufficient design attention and 
> matured to the point where they may be considered gold standard. The 
> exceptionally high quality of the solutions that Evan puts out is a 
> destination that we all aspire to. Getting there may take a while though, 
> in the mean time people are building apps and having to settle with their 
> own half baked solutions which are difficult to share with the community. 
> This situation is particularly grevious because the time spent building 
> these half baked solutions takes time away from focusing on a single aspect 
> that they could develop to a higher standard and share with the community. 
> As an engineer it's hard to see this process as efficient and optimal. 
>
> I don't want to be too prescriptive here but one suggestion might be to 
> introduce the concept of a quality or status metric for each package e.g. 
> exploratory, draft, candidate, ready (those were chosen purely for 
> illustrative purposes). This would allow the community to benefit from each 
> other's work without requiring any compromise in standards. Versus forcing 
> every team to reimplement the same things with ports this seems like a 
> distinct improvement (IMHO). Potentially packages could even be kept in an 
> entirely different package site until they'd graduated to 
> http://package.elm-lang.org/. (this would allow beginners to be kept in a 
> safer environment until they needed to reach into the community packages)
>
> Hopefully my thoughts will be taken in the postive light that they're 
> intended, I'm a huge fan of Elm and would love to see it go from strength 
> to strength. As the opportunity doesn't often present itself I'd like to 
> extend a huge thankyou to Evan for all the great work you've been putting 
> in!
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Moving on

2017-04-25 Thread Erik Lott

>
> Does anybody has an idea how other languages/platforms manage to get 
> community involved?


The elm community will grow organically if it's given the chance. However, 
to have a thriving and exciting community, at a minimum, developers need to 
be able to actively write, contribute and share packages with each other, 
without the language creators being involved in that loop.

Unfortunately, the only solutions to the current holes and under-developed 
areas of the web api are either to use ports or native modules (hack), 
neither of which are acceptable solutions for developing blessed community 
packages. So we're blocked...

The foundation of the language isn't quite ready for explosive community 
growth yet, so expect to see a lot of pitch forks and torches until it is.





On Tuesday, April 25, 2017 at 9:27:49 AM UTC-4, Wojtek Piekutowski wrote:
>
> The number of similar voices regarding community process and amount of 
> frequently requested missing features/native libraries (like binary support 
> and better JS interop) show a problem. No matter how amazing and performant 
> Elm will ever be, newcomers will be discouraged by everlasting begging for 
> native APIs support.
>
> Does anybody has an idea how other languages/platforms manage to get 
> community involved? I think it could be beneficial to learn from, for 
> example Elixir community, and borrow some good practices that could work 
> for Elm too.
>
> On Tue, 25 Apr 2017 at 05:22, Duane Johnson  > wrote:
>
>> As several have asked, and Peter Damoc kindly reached out off-list, I'll 
>> post here what I wrote to him. Please know that I do appreciate what 
>> everyone has worked on, but this hasn't worked for me for the reasons I 
>> outline. I've started auto-archiving email from elm-discuss, so if you have 
>> any questions, please reach out to me off-list. Thanks.
>>
>> Hi Peter, that's kind of you to follow up off-list.
>>
>> I've had several pain points. I'll go over the technical ones first and 
>> the community ones second.
>>
>> In the two (and a half) projects that failed, they failed for different 
>> reasons but in general, because of JS interop issues. In the first project, 
>> I was unable to access binary data in order to represent compiled hex blobs 
>> as visual SVG (see https://github.com/canadaduane/elm-hccb/tree/master). 
>> I made a use case post here 
>> https://groups.google.com/d/msg/elm-discuss/spr621OlUeo/awhuqzpzBgAJ.
>>
>> In the second case, I was trying to create custom elements that could be 
>> embedded inside the QuillJS rich text editor--in other words, it wasn't 
>> enough just to treat Javascript as an external API, I needed to embed elm 
>> "things" inside a JS component inside elm.
>>
>> I made a third attempt to convert an AngularJS app to Elm, but didn't get 
>> very far in and gave up, in part because of the attitude I've felt from the 
>> Elm community that components are bad and have no place here (when 
>> everything I'm seeing in Angular is trying to be more like a component, and 
>> interact with the world like a component).
>>
>> The community aspect that has weighed heavily on me is the feeling that 
>> I'm not a participant in the decision-making or priority-setting. I feel 
>> more like a distant user, or maybe an interesting use case, from which data 
>> is gathered and decisions are made (by someone else, somewhere else).
>>
>> I hope that helps!
>>
>> Thanks again for your reaching out. I really look up to you and eeue56.
>>
>> Take care,
>> Duane
>>
>>
>> On Monday, April 24, 2017 at 4:31:08 PM UTC-6, Joe Andaverde wrote:
>>>
>>> Duane,
>>>
>>> I'm curious what the roadblocks were in the 2 of 3 you didn't have 
>>> success with? This could definitely help others when making their decision. 
>>> Also, it may provide helpful feedback to more appropriately prioritize 
>>> future elm platform development.
>>>
>>> Thanks!
>>>
>>> On Monday, April 24, 2017 at 8:45:57 AM UTC-5, Duane Johnson wrote:

 Hi all,

 I've decided to move on from Elm. I've only been successful in 1 of 3 
 projects. I'm now in a role where I need to make an important decision 
 regarding the transition of a codebase from Angular to something else, and 
 I don't feel like I can responsibly recommend Elm as the replacement. So I 
 need to focus my time and effort elsewhere.

 If someone could please remove me as a moderator of elm-discuss it 
 would be appreciated.

 If anyone is interested in taking the `canadaduane/typed-svg` project 
 over, I'd be happy to help transition it to willing hands.

 Thanks,
 Duane Johnson
 aka canadaduane

 -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit 

[elm-discuss] Re: view function to call other view function with different Msg type

2017-04-24 Thread Erik Lott
Whoops. Html.map is correct... 

view : Model -> Html Msg
view model =
div []
(model.items
  |> List.map itemView 
  |> List.map (Html.map ItemMsg)
)

On Sunday, April 23, 2017 at 1:49:22 PM UTC-4, Max Goldstein wrote:
>
> Yes, Ian is correct.
>
> Html.Attributes.map 
> 
>  : 
> (a -> msg) -> Attribute a -> Attribute msg
>
> Html.map  
> : (a 
> -> msg) -> Html a -> Html msg
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: view function to call other view function with different Msg type

2017-04-22 Thread Erik Lott
view : Model -> Html Msg
view model =
div []
(model.items
  |> List.map itemView 
  |> List.map (Html.Attributes.map ItemMsg)
)




On Saturday, April 22, 2017 at 5:25:41 PM UTC-4, Vardhan wrote:
>
> [ Pardon if this appear twice ]
>
> hi,
>   this is my  toy 1st elm app.
>i'm trying to keep the 'item' of the list as a seperet module.
>
> so i have in module Item:
> -
> type alias ItemModel= { ... }
> type ItemMsg = .. | .. | ..
> itemView : ItemModel -> Html ItemMsg
> -
>
> And in the top level App  module:
> -
> type alias Model = { items: List ItemModel }
> type Msg = ItemMsg ItemMsg | ...
> view : Model -> Html Msg
> view model =
> div []
> (List.map itemView model.items )
> --
>
> Well, the problem is itemView can't be used , as it is 'Html ItemMsg', and 
> not 'Html Msg'
> However, the Item module doesn't have access to 'Msg' ( which is top level 
> ),
>
> How should I use itemView in the view function ?
>
> -Regards
> Vardhan
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Comments on the TEA Components package

2017-04-21 Thread Erik Lott

>
> To recap:
>
>1. Earlier 
> I 
>said "between 0.16 and today, *we learned that a Model-View-Update 
>triplet is the wrong unit of composition for Elm applications...composing 
>individual functions* was both simpler and consistently led to a much 
>better experience. I've laid out my advice for specifically how to do that 
>here 
>
> 
>."
>
>
>1. Later 
> I 
>pointed out an example of when it would be useful to use Html.map and 
>Cmd.map to make a reusable signup form, and for that use case it 
>happened to make sense to have a separate model, view, and update.
>
>
Richard, I think it's only your broad use of the word "*Elm Applications*" 
that is a little misleading for some folks.  When you say "Elm 
Application", maybe you mean: Elm applications like we write at NoRedInk 
(non-SPA applications). ie. each page of the web app is served from a ruby 
on rails server, and that page may include an Elm app(s). In your context, 
I agree with your advice.

When other folks are talking about "*Elm Applications*", they're talking 
about Single Page Applications. In the context of an SPA, the 
Model-View-Update triplet will indeed be a unit of composition for an app - 
each logical page within the app will likely be a triplet. Of course, your 
advice still applies to the individual "pages" within an SPA, but not 
necessarily the overall architecture itself.

The distinction is important, because it's obviously confusing folks. This 
isn't the first time I've seen a dev misunderstand your statement - 
*Model-View-Update 
triplet is the wrong unit of composition for Elm applications *- and 
attempt to write an entire SPA without using a triplet. Very painful stuff. 

I know that's not what you're advising, but without stating that 
explicitly, devs are left to fill in the blanks themselves.



On Wednesday, April 19, 2017 at 1:27:09 PM UTC-4, Richard Feldman wrote:
>
> so, the Model-View-Update triplet *is NOT* the wrong unit of composition 
>> for Elm applications? :) 
>>
>> > How do you propose to split the functionality one has in a highly 
>>> complex app with a lot of pages without using those triplets?
>>>
>>> I don't haha...I just defended their use a few posts ago, complete with 
>>> the specific example of the reusable signup form.
>>
>>
> To recap:
>
>1. Earlier 
> 
>I said "between 0.16 and today, *we learned that a Model-View-Update 
>triplet is the wrong unit of composition for Elm applications...composing 
>individual functions* was both simpler and consistently led to a much 
>better experience. I've laid out my advice for specifically how to do that 
>here 
>
> 
>."
>2. Later 
> 
>I pointed out an example of when it would be useful to use Html.map 
>and Cmd.map to make a reusable signup form, and for that use case it 
>happened to make sense to have a separate model, view, and update.
>
> In (1) I am saying that I expect you'll have a better time if you think 
> about building Elm applications in terms of *composing individual 
> functions*, not in terms of composing Model/View/Update triplets.
>
> In (2) I am giving an example of a very specific set of circumstances in 
> which a separate Model/View/Update makes sense.
>
> In summary: "Here is a useful but complex tool. Always reach for a simpler 
> one first." 
>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Scaling Elm

2017-04-19 Thread Erik Lott
Marek, about the tea-component package: If you're discouraged by the 
boilerplate for nested update and view functions, you can clean-up the 
boilerplate with a single function each... no need to create an entire 
abstraction package.

On Wednesday, April 19, 2017 at 3:34:31 PM UTC-4, Marek Fajkus wrote:
>
> Marek,
>>
>> One difference might be that we don't deal with sign-in in SPA itself. 
>>> We're using Html.programWithFlags and passing user info to elm on 
>>> embedding. 
>>
>>
>> Good stuff. Less work when you don't have to worry about auth states.
>>
>
> it's helping us a lot. Anyway this architecture is used even in js app and 
> predates me joining project. Whole login happens on different domain with 
> different service. Anyway it also means we have to do one XHR request 
> before starting app.
>
> this is example of idea I'm experimenting with: 
> https://github.com/turboMaCk/elm-app-composition-example
> that led to: https://github.com/turboMaCk/tea-component
>
> we're not using exactly that right now. Also package itself is removed 
> from package.elm-lang.org. It will be republished once I manage to change 
> name + docs and I don't really enjoy doing that so I'm taking my time:D
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Scaling Elm

2017-04-19 Thread Erik Lott
Marek,

One difference might be that we don't deal with sign-in in SPA itself. 
> We're using Html.programWithFlags and passing user info to elm on 
> embedding. 


Good stuff. Less work when you don't have to worry about auth states.


On Wednesday, April 19, 2017 at 1:48:39 PM UTC-4, Marek Fajkus wrote:
>
> That appears to have much in common with our app. It seems useful to 
>> compare what people building SPAs are currently doing so here's a rough 
>> gist of the folder/file structure that we're using 
>> https://gist.github.com/opsb/d0977bcb30b42302f3f2dc3daf0befec. There's a 
>> few differences worth pulling out
>>
>> 1) We have the Store abstraction that I mentioned for data synchronisation
>> 2) We have two different top level modules depending on whether or not 
>> you're logged in (AppState)
>> 3) We split our larger pages into sections which function as separate 
>> mini apps 
>>
>> I've found myself thinking in terms of mini apps a lot lately. Each Page 
>> and each page Section functions as a separate mini app, notably they don't 
>> interact with each other, the only communication between them is via data 
>> in the Store which they all share.
>>
>
> We're using similar approach and are happy as well. One difference might 
> be that we don't deal with sign-in in SPA itself. We're using 
> Html.programWithFlags and passing user info to elm on embedding. Some more 
> info here https://groups.google.com/forum/#!topic/elm-dev/iqErmKHnLDY and 
> here https://groups.google.com/forum/#!topic/elm-discuss/Lo6bG96zotI
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Scaling Elm

2017-04-19 Thread Erik Lott
Oliver,

We have the Store abstraction that I mentioned for data synchronisation


Sure. I'm sure this isn't too different - conceptually - from what we're 
doing. Although our app manages some complicated processes, the 
communication with the backend server is as simple as it gets - json gets 
and posts.

>
> We have two different top level modules depending on whether or not you're 
> logged in (AppState)


It's interesting that you mention that, because we also experimented with 
separating our Auth and Public sides of the app via the type system. I 
can't remember why we chose to flatten the app instead... but we did. 

We split our larger pages into sections which function as separate mini 
> apps 


Yeah, we do the same when necessary, although we use different naming. A 
"Page" in our applications always represent a single onscreen page - so 
routes and pages are always mapped one to one. When we have multiple 
components/widgets on a page, those are broken into separate modules 
(mini-apps as you say) and likely stored in the components/widget folder, 
or broken out into a standalone package. 

I've found myself thinking in terms of mini apps a lot lately. Each Page 
> and each page Section functions as a separate mini app, notably they don't 
> interact with each other, the only communication between them is via data 
> in the Store which they all share.


Exactly. 


On Wednesday, April 19, 2017 at 12:52:11 PM UTC-4, Oliver Searle-Barnes 
wrote:
>
> That appears to have much in common with our app. It seems useful to 
> compare what people building SPAs are currently doing so here's a rough 
> gist of the folder/file structure that we're using 
> https://gist.github.com/opsb/d0977bcb30b42302f3f2dc3daf0befec. There's a 
> few differences worth pulling out
>
> 1) We have the Store abstraction that I mentioned for data synchronisation
> 2) We have two different top level modules depending on whether or not 
> you're logged in (AppState)
> 3) We split our larger pages into sections which function as separate mini 
> apps 
>
> I've found myself thinking in terms of mini apps a lot lately. Each Page 
> and each page Section functions as a separate mini app, notably they don't 
> interact with each other, the only communication between them is via data 
> in the Store which they all share.
>
>
>
> On Wednesday, 19 April 2017 17:57:28 UTC+2, Erik Lott wrote:
>>
>> I'm a little pressed for time, but I'll try to give a general 
>> architecture outline that works really well for us. Our primary elm SPA is 
>> a customer facing administrative control panel that communicates with a 
>> backend api server and amazon S3. The app manages authentication, 
>> authorization, subscription status, and currently has 17 'pages'. This 
>> particular app is a Static SPA (currently served from s3-cloudfront combo).
>>
>> *Backend API Client*
>> We have an api client written in elm that resides with the api server. 
>> The api-client elm module can be pulled into any elm project that needs to 
>> communicate with the backend server, and includes all http requests, model 
>> types, model json decoders, and any necessary model helpers. Importantly, 
>> this is where authorization and authentication is handled as well. A user 
>> who successfully signs-in via the api will be granted an authorization 
>> token. The authorization token must be provided with each following request 
>> to the api. 
>>
>> example: 
>> https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c
>>
>> *SPA*
>> The folder structure for the majority of our elm SPA's end up as follows:
>>   - Component (folder)
>>   - Pages (folder)
>>   - Main.elm
>>   - Route.elm
>>   - Routing.elm
>>   .. any other app/infrastructure related modules
>>
>> *Route.elm*
>> Module encapsulating functions relating to routes:
>>
>> https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-route-elm
>>
>> *Routing.elm*
>> The routing module holds the state of the current page, and isolates 
>> logic pertaining to which page is displayed for each route
>>
>> https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-routing-elm
>>
>> *Main.elm*
>> This is where the top level modules are wired together. It's difficult to 
>> create a generate example for this since your Main.elm will be application 
>> specific. Here is a hacked together example of a Main that you can sift 
>> through and try to understand what's going on in this specific application:
>>
>> https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-main-elm
>>
>> Some thin

[elm-discuss] Re: Scaling Elm

2017-04-19 Thread Erik Lott
I'm a little pressed for time, but I'll try to give a general architecture 
outline that works really well for us. Our primary elm SPA is a customer 
facing administrative control panel that communicates with a backend api 
server and amazon S3. The app manages authentication, authorization, 
subscription status, and currently has 17 'pages'. This particular app is a 
Static SPA (currently served from s3-cloudfront combo).

*Backend API Client*
We have an api client written in elm that resides with the api server. The 
api-client elm module can be pulled into any elm project that needs to 
communicate with the backend server, and includes all http requests, model 
types, model json decoders, and any necessary model helpers. Importantly, 
this is where authorization and authentication is handled as well. A user 
who successfully signs-in via the api will be granted an authorization 
token. The authorization token must be provided with each following request 
to the api. 

example: https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c

*SPA*
The folder structure for the majority of our elm SPA's end up as follows:
  - Component (folder)
  - Pages (folder)
  - Main.elm
  - Route.elm
  - Routing.elm
  .. any other app/infrastructure related modules

*Route.elm*
Module encapsulating functions relating to routes:
https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-route-elm

*Routing.elm*
The routing module holds the state of the current page, and isolates logic 
pertaining to which page is displayed for each route
https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-routing-elm

*Main.elm*
This is where the top level modules are wired together. It's difficult to 
create a generate example for this since your Main.elm will be application 
specific. Here is a hacked together example of a Main that you can sift 
through and try to understand what's going on in this specific application:
https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-main-elm

Some things to note: The client configuration is stored in the main model 
and passed down into the pages. When a page triggers a logout or login, 
that fact must travel back up to the main module so the client 
configuration state can be adjusted accordingly. If you need to know how to 
do this, I'm happy to explain.

*Pages*
Here is an example page:
https://gist.github.com/eriklott/812a63be9d9cfd6a949cccaa94e6790c#file-page-apples-elm

*Components* 
There are mostly shared headers, footers,menus, that are shared across 
various pages. Some have their own state, but most are simple reusable view 
helpers. 

Sorry for being short on descriptions. Hopefully the examples are enough to 
give you a sense of direction and organization. Happy to answer any 
questions.

On Wednesday, April 19, 2017 at 5:11:05 AM UTC-4, Peter Damoc wrote:
>
> Hello community, 
>
> Scaling Elm apps seams to be a recurring topic. 
>
> I was wondering if maybe we could negotiate a minimal set of 
> functionality, something similar to ToDoMVC, that could be implemented 
> using different approaches to explore what could be the best way to 
> structure the code. 
>
> What should this minimal example cover and what this minimal example 
> should be (topic)?
>
> I'll start the list with some bits of functionality that I would like: 
>
> - multiple pages with common structure (sidebar/navbar)
> - navigation without reloading the app (SPA routing without the hash) 
> - authentication 
> - complex widget reuse (a module/widget that generates side-effects; e.g. 
> a weather widget, some stock ticker, an ad provided by a third party)
> - styling (CSS)
>
> I would also like the example to cover real world concerns of: 
> - using a build manager to integrate with other technologies 
> - development mode - deployment build
> - testing 
>
> As for topic, I was thinking about an interface to the MusicBrainz 
> Database (a simplified interface).
>
> What do you think? 
> What bits of functionality would you like to see exemplified? 
> Are you aware of any other project (in other languages) that exemplifies a 
> minimal set of functionality and could be used as a template?  
>
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Managing global state in Elm

2016-12-02 Thread Erik Lott

>
> The problem i see with this approach is that in hierarchy of deeply nested 
> components, the whole ancestry would need to know about the intention of 
> the leaf.


Sort of. Each module only needs to consider it's direct child/children. So, 
to use a module, you have to use it's API.

I understand your concern, from a theoretical standpoint, but having a 
large complex elm spa ourselves, this just isn't an issue. Depending on how 
you choose to build your application (I assume you're building an SPA), it 
is very likely that *every* main architectural module (page modules) will 
have a nicely developed API that allows the enclosing module (main module) 
to "hook-in" to events that are happening internally to it. It's actually 
very pleasant to manage once you get used to it.

For example, here is an imaginary module:

MyModule.elm

type Model =
  Model {..}


type alias Config msg = 
  { onClick : msg }

view : Config msg -> Model -> Html msg
view config model =
  button [onClick config.onClick] [text "Submit"]

The view function allows parent modules to configure the view to return 
parent messages. Here is an example of a parent hooking into the view 
function

Parent.elm

type alias Model =
  { myModuleModel : MyModule.Model }

type Msg 
  = ChildClicked

view : Model -> Html Msg
view model =
  MyModule.view myModuleConfig model.myModuleModel


myModuleConfig : MyModule.Config Msg 
myModuleConfig =
  {onClick -> ChildClicked}

Forgive any mistakes - I'm coding this quickly. So, that is just a tiny 
example. You can do the same thing with your update functions (passing in 
an update config) but the arrangement is a little different. Does that help?








On Friday, December 2, 2016 at 9:25:48 AM UTC-5, Birowsky wrote:
>
> The problem i see with this approach is that in hierarchy of deeply nested 
> components, the whole ancestry would need to know about the intention of 
> the leaf. I was hoping towards more of a command-like approach.
>
>
> On Dec 2, 2016, at 14:45, Erik Lott <mreri...@gmail.com > 
> wrote:
>
> Birowsky, your leaf component will need return messages to the parent, and 
> the parent can act on those messages to update it's state. There's no magic 
> to it unfortunately. Do you have a specific problem you're trying to solve?
>
> On Wednesday, November 30, 2016 at 12:04:08 PM UTC-5, Birowsky wrote:
>>
>> Hey Eric, please elaborate on this one. How do you envision leaf 
>> component triggering global state update?
>>  
>>
>>> The second problem becomes: *how do we load this global state/business 
>>> data into the application and cache it?* This requirement is now fairly 
>>> easy to wire-up in elm since the http requests and data cache all live at 
>>> the same level of the application (the top level). If anyone wants more 
>>> details on how to do this, let me know.
>>>
>>
>>  
>>
>>
> -- 
> You received this message because you are subscribed to a topic in the 
> Google Groups "Elm Discuss" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/elm-discuss/j-Wa6NGiYUM/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to 
> elm-discuss...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Managing global state in Elm

2016-12-02 Thread Erik Lott
Birowsky, your leaf component will need return messages to the parent, and 
the parent can act on those messages to update it's state. There's no magic 
to it unfortunately. Do you have a specific problem you're trying to solve?

On Wednesday, November 30, 2016 at 12:04:08 PM UTC-5, Birowsky wrote:
>
> Hey Eric, please elaborate on this one. How do you envision leaf component 
> triggering global state update?
>  
>
>> The second problem becomes: *how do we load this global state/business 
>> data into the application and cache it?* This requirement is now fairly 
>> easy to wire-up in elm since the http requests and data cache all live at 
>> the same level of the application (the top level). If anyone wants more 
>> details on how to do this, let me know.
>>
>
>  
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: How to use Navigation library

2016-11-26 Thread Erik Lott
that should say :
Simon, I'm just glancing at this code, but this page *shouldn't*  perform 
page refreshes at all. It should only fire UrlChange events without reload 
the browser. Am I missing something?

On Saturday, November 26, 2016 at 5:59:56 PM UTC-5, Erik Lott wrote:
>
> The aim is to get the navigation history ticking along properly without 
>> page refreshes.
>
>
> Simon, I'm just glancing at this code, but this page should perform page 
> refreshes at all. It should only fire UrlChange events without reload the 
> browser. Am I missing something?
>
> On Saturday, November 26, 2016 at 10:54:53 AM UTC-5, Simon wrote:
>>
>> Here is some code to make things more concrete
>> https://gist.github.com/simonh1000/9368f9dbd7f93646207ec27fdf3662a2
>>
>> It is based on the example from the Navigation library, but with the 
>> links changed from # to (I think they are called) HTML5 links.
>>
>> I added an onClick handler to provide a preventDefault as otherwise the 
>> links 404, but with this handler the links don’t navigate instead
>>
>> The aim is to get the navigation history ticking along properly without 
>> page refreshes.
>>
>> I know its possible as I’ve seen it in other routers
>>
>> Simon
>>
>> On Saturday, 26 November 2016 13:44:20 UTC+1, Wouter In t Velt wrote:
>>
>> Thank you for the explanation Erik! With the upgrade to 0.18 and the 
>>> changes in navigation, I was wondering which route (pun intended) to follow 
>>> with the upgrade. Not sure I follow completely though.
>>>
>>> In option 1, could you deal with redirect-like scenario's inside the SPA?
>>> Like
>>>
>>>1. user is on the "/apples" page, showing all available apples.
>>>2. user types "/apples/234"  in the url-bar
>>>3. there happens to be no such apple
>>>4. I want the user to stay on the "/apples" page, and get a message 
>>>like "this apple is forbidden fruit"
>>>5. at this point, I would want the url-bar to also say "/apples"
>>>
>>> Can this work with option 1? Or is this only possible with option 2?
>>>
>> ​
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: How to use Navigation library

2016-11-26 Thread Erik Lott

>
> The aim is to get the navigation history ticking along properly without 
> page refreshes.


Simon, I'm just glancing at this code, but this page should perform page 
refreshes at all. It should only fire UrlChange events without reload the 
browser. Am I missing something?

On Saturday, November 26, 2016 at 10:54:53 AM UTC-5, Simon wrote:
>
> Here is some code to make things more concrete
> https://gist.github.com/simonh1000/9368f9dbd7f93646207ec27fdf3662a2
>
> It is based on the example from the Navigation library, but with the links 
> changed from # to (I think they are called) HTML5 links.
>
> I added an onClick handler to provide a preventDefault as otherwise the 
> links 404, but with this handler the links don’t navigate instead
>
> The aim is to get the navigation history ticking along properly without 
> page refreshes.
>
> I know its possible as I’ve seen it in other routers
>
> Simon
>
> On Saturday, 26 November 2016 13:44:20 UTC+1, Wouter In t Velt wrote:
>
> Thank you for the explanation Erik! With the upgrade to 0.18 and the 
>> changes in navigation, I was wondering which route (pun intended) to follow 
>> with the upgrade. Not sure I follow completely though.
>>
>> In option 1, could you deal with redirect-like scenario's inside the SPA?
>> Like
>>
>>1. user is on the "/apples" page, showing all available apples.
>>2. user types "/apples/234"  in the url-bar
>>3. there happens to be no such apple
>>4. I want the user to stay on the "/apples" page, and get a message 
>>like "this apple is forbidden fruit"
>>5. at this point, I would want the url-bar to also say "/apples"
>>
>> Can this work with option 1? Or is this only possible with option 2?
>>
> ​
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: How to use Navigation library

2016-11-26 Thread Erik Lott
Wouter, in regards to that sequence of events, I would reduce sequence to 
the following question: What does my elm app do when the address bar is 
"/apples/234" ? If apple 234 exists, show the apple page. If apple 234 does 
not exist, show a "Not Found" page. 

IMHO if the user types the url "/apples/234" into the address bar, then I 
must consider that url to be correct, and it is the job of my elm 
application to respond to that url - even if only to show a NotFound 
page/message.

With that said, it would also be fairly trivial to, rather than displaying 
a NotFound page,  redirect the user to "/apples" if the user is trying to 
visit the url of an apple that doesn't exist i.e "/apples/234". You can 
easily do that using Option 1.


On Saturday, November 26, 2016 at 7:44:20 AM UTC-5, Wouter In t Velt wrote:
>
> Thank you for the explanation Erik! With the upgrade to 0.18 and the 
> changes in navigation, I was wondering which route (pun intended) to follow 
> with the upgrade. Not sure I follow completely though.
>
> In option 1, could you deal with redirect-like scenario's inside the SPA?
> Like
>
>1. user is on the "/apples" page, showing all available apples.
>2. user types "/apples/234"  in the url-bar
>3. there happens to be no such apple
>4. I want the user to stay on the "/apples" page, and get a message 
>like "this apple is forbidden fruit"
>5. at this point, I would want the url-bar to also say "/apples"
>
> Can this work with option 1? Or is this only possible with option 2?
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: How to use Navigation library

2016-11-26 Thread Erik Lott

>
> With option 1 how do you stop the page reloading on each click on an 
> anchor?


I'm not sure I understand. I would think that you would want a UrlChange 
msg to be fired each time one of these anchors were clicked. I think I'm 
missing the point, so let me know.

Another Con of option 1 might be that it can't cover so many scenarios. 
> Suppose that you have a form, click submit and then - on successful 
> completion of some persistence stage - you want to redirect to another 
> page. (Or is that possible by combining some kind of redirect command with 
> the confirmation from the server, and again here how would you prevent page 
> reloading?)


Yes, your last sentence is correct. So, if I were in your shoes, I'd do 
something like this:

   1. Click on submit button fires FormSubmit msg
   2. Update handles FormSubmit msg and fires some http command to your 
   backend server.
   3. The http command completes and again your Update function handles the 
   response msg from the http command. HERE is where I would fire a 
   Navigation.newUrl command to change the address bar. 
   4. A UrlChange msg is produced in the root of your application (by the 
   navigation package) and arrives at your root Update function. These is 
   where you can change the page/adjust your root model.



On Saturday, November 26, 2016 at 1:19:09 AM UTC-5, Simon wrote:
>
> With option 1 how do you stop the page reloading on each click on an 
> anchor?
>
> Another Con of option 1 might be that it can't cover so many scenarios. 
> Suppose that you have a form, click submit and then - on successful 
> completion of some persistence stage - you want to redirect to another 
> page. (Or is that possible by combining some kind of redirect command with 
> the confirmation from the server, and again here how would you prevent page 
> reloading?)
>
> On Friday, 25 November 2016 23:29:49 UTC+1, Erik Lott wrote:
>>
>>  Is there any reason to favour one over the other, otherwise I'm likely 
>>> to go with 2.
>>
>>
>> Yeah, I would say stick with option 1. Our large SPA in elm has used 
>> option 2 for the past 5 months, and we've recently swapped over to option 
>> 1. Here are some pros & cons:
>>
>> Option 1:
>> Pros
>>
>>- Embraces the browser by creating real clickable links. I can CMD + 
>>click on a link and open it in a new tab, I can CTRL + click and open it 
>> in 
>>a new window.
>>- Easier to implement in Elm (not necessarily better, just easier) 
>>compared to option 2
>>- Easier to maintain to understand. 
>>- Routing state does not need to be stored in the root model. This is 
>>tough to explain. Using option 1, If someone navigates to "/apples/234" 
>> in 
>>your elm app, your app would parse that url and generate a Msg like 
>>"AppleRoute 234", send the msg to update func, fetch the "apple" resource 
>>id=234 from the backend server via http, and use that data to display the 
>>"ApplePage". Done. Although we needed id "234" to load the apple data, 
>>there is no reason for us to store that id in the root model of our 
>>application - After it's been used to load the page, it can be discarded. 
>>Not so, however, for option 2. You're forced to store that ID in your 
>> root 
>>model so that you can derive the address bar url from it.  
>>
>> Cons
>>
>>- Even though it is easier to maintain, read, and write (hahaha) I 
>>strongly dislike one aspect of option 1. Why should I use the browser to 
>>pass messages around my app (click an html link > the browser updates the 
>>address bar > elm root receives url change msg) when elm can pass 
>> messages 
>>internally  just fine. Arg...
>>
>>
>> Option 2
>> Cons
>>
>>- Lots of msg translating and indirection - There will be a healthy 
>>amount of upward messaging from child to parent (notify root that a 
>>navigation link in the child was clicked). I wouldn't recommend this to 
>>anyone just getting started with elm, but if you already have experience 
>>with elm, go for it.
>>- You need to store routing state in the root model, specifically for 
>>the address bar representation.
>>- Links in your html view will not be real href links, so you lose 
>>some functionality mentioned in the option1 pros.
>>
>> Pro
>>
>>- All aspects of the application are driven by elm. The internal 
>>messaging is done in elm. Address bar changes are driven by Elm. You 
>> could 
>>easil

[elm-discuss] Re: How to use Navigation library

2016-11-25 Thread Erik Lott

>
>  Is there any reason to favour one over the other, otherwise I'm likely to 
> go with 2.


Yeah, I would say stick with option 1. Our large SPA in elm has used option 
2 for the past 5 months, and we've recently swapped over to option 1. Here 
are some pros & cons:

Option 1:
Pros

   - Embraces the browser by creating real clickable links. I can CMD + 
   click on a link and open it in a new tab, I can CTRL + click and open it in 
   a new window.
   - Easier to implement in Elm (not necessarily better, just easier) 
   compared to option 2
   - Easier to maintain to understand. 
   - Routing state does not need to be stored in the root model. This is 
   tough to explain. Using option 1, If someone navigates to "/apples/234" in 
   your elm app, your app would parse that url and generate a Msg like 
   "AppleRoute 234", send the msg to update func, fetch the "apple" resource 
   id=234 from the backend server via http, and use that data to display the 
   "ApplePage". Done. Although we needed id "234" to load the apple data, 
   there is no reason for us to store that id in the root model of our 
   application - After it's been used to load the page, it can be discarded. 
   Not so, however, for option 2. You're forced to store that ID in your root 
   model so that you can derive the address bar url from it.  

Cons

   - Even though it is easier to maintain, read, and write (hahaha) I 
   strongly dislike one aspect of option 1. Why should I use the browser to 
   pass messages around my app (click an html link > the browser updates the 
   address bar > elm root receives url change msg) when elm can pass messages 
   internally  just fine. Arg...


Option 2
Cons

   - Lots of msg translating and indirection - There will be a healthy 
   amount of upward messaging from child to parent (notify root that a 
   navigation link in the child was clicked). I wouldn't recommend this to 
   anyone just getting started with elm, but if you already have experience 
   with elm, go for it.
   - You need to store routing state in the root model, specifically for 
   the address bar representation.
   - Links in your html view will not be real href links, so you lose some 
   functionality mentioned in the option1 pros.

Pro

   - All aspects of the application are driven by elm. The internal 
   messaging is done in elm. Address bar changes are driven by Elm. You could 
   easily swap this app to a different platform (anything that is not the 
   browser), make a few changes to your view layer, and blammo - the app would 
   run.






On Friday, November 25, 2016 at 11:22:01 AM UTC-5, Simon wrote:
>
> Erik,
> that makes such a lot of sense. Thanks for spelling it out. Is there any 
> reason to favour one over the other, otherwise I'm likely to go with 2.
> Simon
>
> On Friday, 25 November 2016 16:52:20 UTC+1, Erik Lott wrote:
>>
>> When you're creating an SPA in elm, you'll generally need to choose one 
>> of two navigation styles:
>>
>> *1. Allow the address bar to drive your model*
>> The standard Navigation package provides this type of functionality. Your 
>> model will respond to changes in the address bar, and your views will 
>> (generally) use view links (a tags) to change the address bar. You may have 
>> a few sprinkles of manual url changing commands throughout the app for 
>> redirection, but for the most part, the majority of url changes are caused 
>> by users clicking on html links in your view.
>>
>> The changes flow like this : View --> Address Bar --> Model --> View 
>>
>> *2. Allow your model to drive the address bar*
>> In this case, the address bar is simply a reflection of the current state 
>> of your model. There is no need to update the address bar manually, because 
>> it will keep itself in sync with your model. Try using a routing package 
>> like Elm Route Url (
>> http://package.elm-lang.org/packages/rgrempel/elm-route-url/latest). 
>> Take a moment and read the package readme. It clearly explains the 
>> difference between the 2 styles of routing. If you use this style of 
>> navigation, you'll need to build your application in such a way that the 
>> navigation is kept within elm and does not require the address bar. For 
>> example, rather than including a tag links in your html view to change the 
>> url directly, your a-tags or buttons will trigger Msg's that will update 
>> your model, and then the address bar will respond to the model change.
>>
>>
>>
>>
>>
>>
>>
>> On Friday, November 25, 2016 at 4:32:50 AM UTC-5, Simon wrote:
>>>
>>> OK, I just don’t quite understand, even while I have working code!
>>>
>>> I have an app w

[elm-discuss] Re: How to use Navigation library

2016-11-25 Thread Erik Lott

>
> One of the main benefits of routing/navigation is that a user can bookmark 
> or send a URL to someone else, and the website loads up in the correct 
> state. Option number 1 seems like it would handle this case naturally. I'm 
> not sure how it would work for option number 2.


The Elm-route-url package also take into account the initial application 
load, and changes to the url that occur outside of elm (e.g. the browser 
back button is clicked). Regardless of which navigation type you choose, 
these concerns are not an issue - bookmarks, etc can be done with both.

On Friday, November 25, 2016 at 11:27:15 AM UTC-5, Max Goldstein wrote:
>
> One of the main benefits of routing/navigation is that a user can bookmark 
> or send a URL to someone else, and the website loads up in the correct 
> state. Option number 1 seems like it would handle this case naturally. I'm 
> not sure how it would work for option number 2.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: How to use Navigation library

2016-11-25 Thread Erik Lott
When you're creating an SPA in elm, you'll generally need to choose one of 
two navigation styles:

*1. Allow the address bar to drive your model*
The standard Navigation package provides this type of functionality. Your 
model will respond to changes in the address bar, and your views will 
(generally) use view links (a tags) to change the address bar. You may have 
a few sprinkles of manual url changing commands throughout the app for 
redirection, but for the most part, the majority of url changes are caused 
by users clicking on html links in your view.

The changes flow like this : View --> Address Bar --> Model --> View 

*2. Allow your model to drive the address bar*
In this case, the address bar is simply a reflection of the current state 
of your model. There is no need to update the address bar manually, because 
it will keep itself in sync with your model. Try using a routing package 
like Elm Route Url 
(http://package.elm-lang.org/packages/rgrempel/elm-route-url/latest). Take 
a moment and read the package readme. It clearly explains the difference 
between the 2 styles of routing. If you use this style of navigation, 
you'll need to build your application in such a way that the navigation is 
kept within elm and does not require the address bar. For example, rather 
than including a tag links in your html view to change the url directly, 
your a-tags or buttons will trigger Msg's that will update your model, and 
then the address bar will respond to the model change.







On Friday, November 25, 2016 at 4:32:50 AM UTC-5, Simon wrote:
>
> OK, I just don’t quite understand, even while I have working code!
>
> I have an app where, as the model changes (in particular the value 
> representing the ‘page’ of my single page app), the Url is updated with 
> this task
>
> Navigation.newUrl (toUrl model)
>
> But as the Url changes, I get a new message from Navigation because of:
>
> main =
> Navigation.programWithFlags
> (Routing.urlParser RouteTo)
> { init = initWithFlags
> , update = Routing.update
> , view = view
> , subscriptions = subscriptions
> }
>
> When first loading the app, this message is useful and I can use it to 
> direct to the appropriate opening page. But thereafter this message is 
> redundant - I already made all the model changes I wanted before and that 
> caused the Url update. Without some care I even get a loop of each Routing 
> message causing the 
>
> *I suspect I am missing something rather important, but am not sure what?*
>
> One option would be to use anchor tags to cause the switch pages, and only 
> do model changes when I get a RouteTo message, but even then I have some 
> url changes resulting from the clicking on an element within a page, and I 
> don’t think that is a place for anchors. (As I use html urls, rather than 
> # ones I also have to be careful not to let the page get reloaded)
> ​
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Structure for large Elm apps

2016-10-24 Thread Erik Lott

>
> Above all of this, the other key subdivision we are making in our SPA and 
> that I would recommend having seen where other programmers often first 
> head, is having a top layer that handles overall app state — e.g., logged 
> in v not logged in — as a type union. This can also often be where the 
> routing logic plugs in. 


This is exactly what we do throughout our entire SPA app. We use union 
types to manage overall state and protect our invariants, making it 
impossible for the app to be in an invalid state at any time. The union 
types may get a little deep at times, but the payoff is more than worth it. 

On Sunday, October 23, 2016 at 3:29:23 PM UTC-4, Mark Hamburg wrote:
>
> We're just getting into having an app where this is likely to matter, but 
> if you have multiple views onto the same data, then the pattern that would 
> seem to apply is to have a single data model and multiple view models. The 
> data model handles the shared part. The view models handle things specific 
> to the particular view — e.g., is a spin down open, what's the scroll 
> position, etc. The view functions would take the data model and their 
> particular view model as parameters and would generate appropriately tagged 
> messages back. This avoids significant nesting while still providing some 
> structure to keep pieces that can be separated separate.
>
> There are then a couple ways to structure the multiple view models. One is 
> to have a view selector but keep all of the view models alive all the time. 
> The benefit of this is that when you switch back to a view, it will 
> remember where you were. The downside is that one is carrying around — and 
> potentially updating if the view model depends on the data model — an 
> increasing number of view models if you have an increasing number of views. 
> The alternative is to put the view models into a union type and have one 
> model entry that serves as both view selector and view model storage. This 
> keeps things lighter weight but means that you have nowhere to maintain 
> context when switching back and forth.
>
> Above all of this, the other key subdivision we are making in our SPA and 
> that I would recommend having seen where other programmers often first 
> head, is having a top layer that handles overall app state — e.g., logged 
> in v not logged in — as a type union. This can also often be where the 
> routing logic plugs in. People who haven't spent a lot of time thinking in 
> terms of type unions tend to load their model up with a lot of fields that 
> only have meaning in certain states. This then leads to more invariants 
> about the state that can't be enforced by the compiler. Breaking things up 
> into different type cases for different states allows one to make more bad 
> states simply impossible. For example, our logging in state has a 
> RemoteData.WebData User reflecting whether we've gotten valid user data 
> back from the server but our logged in state simply has a User. The top 
> level event dispatcher works with the following type signature on the log 
> in state update:
>
> update : Login.Msg -> Login.Model -> ( Login.Model, Cmd Login.Msg, Maybe 
> User )
>
>
> After each call to update, it can check to see whether we now have a valid 
> user and if so switch to the logged in state, initializing it with the 
> supplied user.
>
> This isn't as flat as some people go, but it doesn't spread things out 
> into lots of components and the top layer(s) are pretty simple.
>
> Mark
>
>
> On Sun, Oct 23, 2016 at 11:39 AM, Francois  > wrote:
>
>> Hi,
>>
>> I'm really new to Elm. I'm not good enough to propose a guideline about 
>> Elm app structure but as a novice a guideline can help lots of people.
>>
>> I worked / works on a large angular application and John Papa Styleguide 
>> has been really helpful at the beginning.
>> So writing a community guideline can be a great resource. (there is 
>> another thread inter component that seems related)
>>
>> For example, on the server side, structuring domain core by features is 
>> good thing (for me). Help define some boundaries and help maintability. 
>> Grouping all Java classes by technical aspect at the project root : all 
>> services in one package, all models in one package can be tedious.
>>
>> On the front, if I correctly understood this thread :
>> - a unique Msg / Model inside Main.elm can be a good starting point and 
>> easy to refactor later. 
>> - separating the view per feature (only view functions) : advice taken 
>> from Dave
>> - break Model / Msg when too big (definition of "too big" is perhaps not 
>> easy, or someone can give some advices to detect "a too big Msg"). At this 
>> point, break Msg / Model / Update by feature. It is not all or nothing, 
>> just extract at first one feature and put them inside a file. Then the Main 
>> module wraps the feature (using map inside the Update).
>>
>> Can we imagine starting a community guideline 

Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-10-23 Thread Erik Lott
If you need to communicate between 2 or more enclosed pieces of 
functionality/modules, you'll need to orchestrate that communication via their 
parent.

Like I said, I regret posting the original solution that I did, since it was 
essentially circumventing the elm language. You should try to stay within elm 
as much as possible, unless you're truly missing a piece of functionally, such 
as working with files, etc.

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-10-22 Thread Erik Lott
You're such a jerk Richard :)

On Saturday, October 22, 2016 at 1:21:44 PM UTC-4, Richard Feldman wrote:
>
> Oh man, now I feel like a total jerk for my harsh tone.
>
> My apologies, and thank you for the update Erik! <3
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-10-22 Thread Erik Lott
Problem solved! Post deleted (thumbs up)

On Saturday, October 22, 2016 at 10:50:38 AM UTC-4, Richard Feldman wrote:
>
> On Friday, July 15, 2016 at 9:49:41 PM UTC-7, Erik Lott wrote:
>>
>> Max, build a non-trival 15+ page SPA within a single elm component, and 
>> tell me how that goes :)
>>
>> On Friday, July 15, 2016 at 8:08:23 PM UTC-4, Max Goldstein wrote:
>>>
>>> Allow me to suggest that this approach is *totally overkill*. It might 
>>> not be, but this is something Richard and I were discussing last night at 
>>> the meetup. If you come from React, everything is a component, so you reach 
>>> for them. But, for many uses cases, nesting TEA is unnecessary. Go ahead 
>>> and make Model and Msg huge types. The compiler will keep you from breaking 
>>> things.
>>
>>
> I agree with Max's original statement. I would give each logical "page" 
> its own Model, View, and Update, and that's probably it.
>
> This is effectively what we've done at NoRedInk with our *50,000 lines of 
> production Elm code*, and it has been extremely rare to find examples 
> where nesting an entire model, view, and update further than that was a 
> good idea.
>
>> When you're building something at a larger scale like a single page app, 
>> that contains various layouts, menus, &  pages - which contain several 
>> components per page - you'll need components to keep your code organized, 
>> maintainable, and easy to understand.  
>
> I strongly disagree with this.
>
> Every time I've followed this approach I've regretted it. It introduced 
> substantial communication overhead, making my code harder to work with, and 
> got me vanishingly little in return. When I've chosen not to do this, and 
> to instead focus on localized refactors like "this record is too big, so 
> I'll split it into a few smaller records" or "this Msg is too big, so I'll 
> split into a few smaller union types," the code has ended up much easier to 
> maintain at scale.
>
> My strong impression is that the pattern presented in OP is a band-aid 
> over a self-inflicted wound. I would advise against using it, and instead 
> *choosing 
> not to self-inflict that communication overhead in the first place*. 
> Scaling by thinking in terms of "components" is a natural fit for React, 
> and an extremely poor fit for Elm.
>
> Don't do this to yourself!
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-10-22 Thread Erik Lott
As the OP, I agree. Don't do this. We quickly abandoned this functionality 
after we wrote it. One of those posts I would I could remove...




On Saturday, October 22, 2016 at 10:50:38 AM UTC-4, Richard Feldman wrote:
>
> On Friday, July 15, 2016 at 9:49:41 PM UTC-7, Erik Lott wrote:
>>
>> Max, build a non-trival 15+ page SPA within a single elm component, and 
>> tell me how that goes :)
>>
>> On Friday, July 15, 2016 at 8:08:23 PM UTC-4, Max Goldstein wrote:
>>>
>>> Allow me to suggest that this approach is *totally overkill*. It might 
>>> not be, but this is something Richard and I were discussing last night at 
>>> the meetup. If you come from React, everything is a component, so you reach 
>>> for them. But, for many uses cases, nesting TEA is unnecessary. Go ahead 
>>> and make Model and Msg huge types. The compiler will keep you from breaking 
>>> things.
>>
>>
> I agree with Max's original statement. I would give each logical "page" 
> its own Model, View, and Update, and that's probably it.
>
> This is effectively what we've done at NoRedInk with our *50,000 lines of 
> production Elm code*, and it has been extremely rare to find examples 
> where nesting an entire model, view, and update further than that was a 
> good idea.
>
>> When you're building something at a larger scale like a single page app, 
>> that contains various layouts, menus, &  pages - which contain several 
>> components per page - you'll need components to keep your code organized, 
>> maintainable, and easy to understand.  
>
> I strongly disagree with this.
>
> Every time I've followed this approach I've regretted it. It introduced 
> substantial communication overhead, making my code harder to work with, and 
> got me vanishingly little in return. When I've chosen not to do this, and 
> to instead focus on localized refactors like "this record is too big, so 
> I'll split it into a few smaller records" or "this Msg is too big, so I'll 
> split into a few smaller union types," the code has ended up much easier to 
> maintain at scale.
>
> My strong impression is that the pattern presented in OP is a band-aid 
> over a self-inflicted wound. I would advise against using it, and instead 
> *choosing 
> not to self-inflict that communication overhead in the first place*. 
> Scaling by thinking in terms of "components" is a natural fit for React, 
> and an extremely poor fit for Elm.
>
> Don't do this to yourself!
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Http 401 Interceptor? My 3rd Elm Project - authentication

2016-09-18 Thread Erik Lott
I'm not sure what the outmessage package is that you linked to, but you 
don't need a package to manage this. An outmsg is just a messge that is 
returned from the update function, to notify the function caller of 
something important that happened internally. If you're new to elm, it's 
probably better to wire an OutMsg yourself, just so you know exactly what's 
going on with the code. If you haven't yet seen the Sortable Table Example 
<https://github.com/evancz/elm-sortable-table>, you should have a close 
look at the code. You'll see great examples of the update and view method 
returning useful messages.

On Saturday, September 17, 2016 at 1:50:26 PM UTC-4, Rupert Smith wrote:
>
> On Saturday, September 17, 2016 at 2:01:54 AM UTC+1, Erik Lott wrote:
>>
>> No, our pages make their own HTTP requests from within the page, and do 
>> not delegate the top layer to make requests. The majority of our api 
>> requests are done from within pages, and I think that's likely the case for 
>> most apps. Each of our "pages" manage their own http errors through the use 
>> of a reusable view module that displays errors in a popup modal. We COULD 
>> pass 401 errors upwards to the top layer to initiate a re-route to login, 
>> but we don't - If a 401 hasn't been caught during the initial transition to 
>> a page, it's unlikely that one is going to occur during the lifetime of a 
>> single page. If a 401 does occur during a page api request, it's simple to 
>> display a "please login" message in the  popup error modal.
>>
>> If you absolutely need to communicate all 401's upwards, just make that 
>> part of the API of your page modules - that will involve sending an 
>> 'OutMsg' from your page's "update" function.
>>
>
> Thanks. Never heard of OutMsg until now...
>
> http://package.elm-lang.org/packages/folkertdev/outmessage/1.0.2
>
> Basically achieves the same thing that I did with ports, but without the 
> need to resort to ports. 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Http 401 Interceptor? My 3rd Elm Project - authentication

2016-09-16 Thread Erik Lott
No, our pages make their own HTTP requests from within the page, and do not 
delegate the top layer to make requests. The majority of our api requests 
are done from within pages, and I think that's likely the case for most 
apps. Each of our "pages" manage their own http errors through the use of a 
reusable view module that displays errors in a popup modal. We COULD pass 
401 errors upwards to the top layer to initiate a re-route to login, but we 
don't - If a 401 hasn't been caught during the initial transition to a 
page, it's unlikely that one is going to occur during the lifetime of a 
single page. If a 401 does occur during a page api request, it's simple to 
display a "please login" message in the  popup error modal.

If you absolutely need to communicate all 401's upwards, just make that 
part of the API of your page modules - that will involve sending an 
'OutMsg' from your page's "update" function.

Happy to explain further if anything is unclear.

On Friday, September 16, 2016 at 6:17:24 PM UTC-4, Rupert Smith wrote:
>
> On Friday, September 16, 2016 at 6:07:42 PM UTC+1, Erik Lott wrote:
>>
>> Rupert, here is a high level overview of how we currently structure our 
>> elm SPAs:
>>
>>1. Top layer: This layer manages routing, page changes, and page 
>>resource loading, and current user state
>>2. Page layer: These are individual pages - typically one page for 
>>each url. There may be deeper levels of widgets/views within each 
>>page, but we don't have pages nested within pages.
>>
>>
>> When the top layer is notified of a page change (this mechanism can vary 
>> from app to app), it first communicates with the backend server to load any 
>> resources that are needed to display that page. If the resource load 
>> succeeds, the page is displayed by changing the 'currentRoute' to the new 
>> routing state, and providing the loaded resources to the new page. If the 
>> load fails, however, you can check the http error to determine why. If 
>> you're received a 401 failure, you can quickly change to your "login route" 
>> and ask the user to login.
>>
>> Keep in mind that method allows you to catch and mange http errors that 
>> occur during page transitions, and not from http requests made from within 
>> a page. We're fine with that tradeoff, because 99% of the time, you'll only 
>> need to catch 401 during page transitions anyways.
>>
>> Hopefully that helps.
>>
>
> Very enlightening thanks.
>
> What about POSTs from pages? For example, I have a page which shows user 
> accounts (to an admin), and will also allow a new user account to be 
> created. It would seem natural to POST the new account from within that 
> page. Or do you do that from the top-level too? 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: elm-mdl and sub modules

2016-09-02 Thread Erik Lott
Mario, just keep a Material.Model in the model of each sub-page.

On Friday, September 2, 2016 at 6:18:55 PM UTC-4, Mario Sangiorgio wrote:
>
> Hello everybody,
>
> I've been experimenting for a while with elm. Previously I tried plain elm 
> and I found it very effective to have a module for each sub-page of my 
> applications and a root module holding everything together.
>
> I'm trying to follow the same approach with an app using elm-mdl but I 
> found this model is clashing a bit with the fact that elm-mdl requires to 
> pass an instance of Material.Model to some of the rendering function and 
> wants a custom message.
>
> I’d normally have the classic `view : Model -> Html Message` function and 
> in the root module I’d put everything together doing `Html.App.map 
> MyPageMessage <| MyPage.view model.myPage`.
>
> elm-mdl changes this a bit and it makes it hard to follow the same 
> pattern. I can make this work with a more convoluted view function but it 
> feels less clean than using `Html.App.map`. The signature of the view 
> method on my pages would be something like
>
> view : Material.Model -> (Material.Msg a -> a) -> (Message -> a) -> Model 
> -> Html a
>
> That way I can inject the mdl model, the constructor to create the 
> root-level messages (which include the MdlMessage).
>
> I suspect there is a better approach but I'm struggling to find it.
> What are the patterns you use with elm-mdl?
>
> Thanks,
> Mario 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Design of Large Elm apps

2016-08-30 Thread Erik Lott
@JoshAdams has been kind enough to share a simple single level SPA example 
on another thread that might be of use to some folks arriving here.

Here's what I've been working on.  The recent git history is all about 
> refactoring.  Haven't introduced 'sub-components with state' or w/e and 
> don't see it coming soon.  It's an Elm-SPA with a Phoenix backend: 
> https://github.com/knewter/time-tracker 
> 




On Thursday, August 4, 2016 at 6:15:53 PM UTC-4, Ryan Erb wrote:
>
> Got a few questions regarding the best way, or what options there are for 
> scaling up to a large site.
> If i have a site with lots of features what is the best way to orgainze 
> everything?
>
> *One Elm page to rule them all?* With this approach you only have to deal 
> with one update happening, you can separate code into different modules, 
> but the update function would be HUGE. Guess this would be the same as a 
> single page application?
>
> *One Elm page per HTML page?* This way every page deals with only what it 
> is used for. You can write common things in reusable modules. One problem 
> might be switching to other elm pages. The only really good way right now 
> that i have is using a port to "window.locaion.href" to another elm page. 
> Then pulling all the data it requires from the server using more ports.
>
> *One Elm page per feature?* This way you can write separate apps for each 
> part of your page. One for the header menu bar, one for a sidebar, and one 
> for each main feature. This way you can mix and match and piece together 
> for a full page. BUT you might have to do a lot of port talking between 
> each section.
>
> *Some other way?*?
>
> Been searching around a cant seem to find any blogs or topics on this 
> subject. Our stack is Elm/Phoenix/Elixir/Postgres.
>
> If anyone has created a large application using Elm would happy to have 
> your input on what worked/ didn't work for you.
>
> Thanks,
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] A more concrete question about API design

2016-08-30 Thread Erik Lott

>
> As a newbie, I struggle to grasp whether I should tap into the Cmd module, 
> and if so, how to do that.


If by "tap into the Cmd module" you mean messing around with the Native Cmd 
code, or creating your own effects manager, than no, don't reach for that - 
it's not necessary to solve your problem. Without knowing more about your 
app architecture, my first thought would be this: if you really need access 
to the websocket in both the parent and the child (and there can be 
situations where you might), extract the websocket plumbing into a module, 
and include it in these other 2 modules (your parent and child).

The thing to watch out for is storing your main business/domain records is 
multiple places throughout the app - if you catch yourself doing this, you 
should stop and take a close look at your architecture.


On Tuesday, August 30, 2016 at 6:14:26 AM UTC-4, Alessandro Mencarini wrote:
>
>
>
> On Friday, August 26, 2016 at 9:38:23 PM UTC+1, Nick H wrote:
>>
>> So I agree that Cmd itself is not suitable for this more complex version 
>> of the queue problem. But that's fine. If you feel that the way Elm is 
>> being presented, that it is encouraging (or pressuring?) us to solve every 
>> problem with commands, then maybe we need to change the text of the 
>> guide/documentation/website.
>>
>  
> Newbie's opinion here, hopefully this can steer the discussion in a 
> helpful way. 
>
> In Elm tutorial you can read this:
>
> In Elm, commands (Cmd) are how we tell the runtime to execute things that 
>> involve side effects. 
>
>
> This caused me to look into Cmd as a first reaction when trying to build 
> something where a child had to communicate state changes through websockets 
> (only present in the parent). 
> I hit a rubber wall and only found a good way of handing the situation 
> when Josh pointed me to the "OutMsg pattern" he used.
>
> As a newbie, I struggle to grasp whether I should tap into the Cmd module, 
> and if so, how to do that.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Do the counters in the Guide teach us a wrong scaling approach?

2016-08-30 Thread Erik Lott

>
> @Erik Lott, did you mean:
> view : Msg -> Msg -> Int -> Html Msg
> Or did I miss something?


Yeah, just a typo. Thanks for catching that. 

On Tuesday, August 30, 2016 at 5:27:06 AM UTC-4, Wouter In t Velt wrote:
>
> @Erik Lott, did you mean:
>
> view : Msg -> Msg -> Int -> Html Msg
>
> Or did I miss something?
>
> @Peter Damoc, yeah the flat solution would be simpler (I actually did do a 
> flat counter list before separating out the CounterView ;).
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Do the counters in the Guide teach us a wrong scaling approach?

2016-08-29 Thread Erik Lott
Wouter, looks good. Yeah, it's not a big deal if the counter is nested or 
not in this case. Just one thought - I'm not sure that the generic 
signature of the CounterView.view is useful here:

view : msg -> msg -> Int -> Html msg

Yes, keeping the signature generic allows you to avoid importing Msg into 
this module, but it's better to use generic signatures when the function 
truly needs to accept generic arguments. In this case, you actually only 
ever plan to use a single incrementMsg (Increment) and single decrementMsg (
Decrement), so you might as well be specific:

view : Msg -> Msg -> Int -> Html msg

After that, you'll need to move CounterView.view into the main file with 
the rest of the code, or pull Msg into it's own file and import where 
needed.


On Monday, August 29, 2016 at 5:35:38 PM UTC-4, Wouter In t Velt wrote:
>
> I would love to know how to do this!
>> Can anyone point me to a brain-dead-simple practical and working example 
>> for a non-expert Elm user like myself?
>
> OK, so here is my take at an alternative multiple counters approach.
> {- Model needs to hold a list of counter values
> Any counter in the list is simply identified by its index
> -}
> type alias Model =
>   List CounterValue
>   
> type alias CounterValue =
>   Int
>
> -- the defaultmodel is simply an empty list
> defaultModel : Model
> defaultModel = 
>   []
>
> {- Original Msg type needs to be expanded to include the ID of the counter
> to update. So our update function knows which counter to change.
> We could have done something like a nested Msg structure.
> But no need to make things more complicated than needed, so we keep 
> things simple 
> -}
> type Msg =
>   AddCounter
>   | Increment CounterId
>   | Decrement CounterId
>   
> type alias CounterId =
>   Int
>
> {- Update uses helper function to update the right counter (indicated by 
> index from Msg)
> -}
> update : Msg -> Model -> Model
> update msg model =
>   case msg of
>
> AddCounter ->
>   -- add new counter with default value of zero to our list
>   model ++ [ 0 ]
>   
> Increment counterId ->
>   -- invoke helper to increment item at index
>   changeItemInList counterId (\item -> item + 1) model
>
> Decrement counterId ->
>   -- invoke helper to decrement item at index
>   changeItemInList counterId (\item -> item - 1) model
>
> -- helper to update an item in any list, applying a function to item at 
> index
> changeItemInList : Int -> (a -> a) -> List a -> List a
> changeItemInList idToUpdate itemUpdate someList =
>   List.indexedMap (setItemAtIndex idToUpdate itemUpdate) someList
>   
> -- apply itemUpdate function if index matches idToUpdate
> setItemAtIndex : Int -> (a -> a) -> Int -> a -> a
> setItemAtIndex idToUpdate itemUpdate index a =
>   if (idToUpdate == index) then
> itemUpdate a
>   else
> a
>
> {- view renders a button to add a counter + list of counters from model -}
> view : Model -> Html Msg
> view model =
>   let
> countersHtml =
>   List.indexedMap counterView model
>   in
> div []
>   [ button [ onClick AddCounter ] [ text "Add counter" ]
>   , div [ style [("display","flex")] ]
>   countersHtml
>   ]
>
> -- helper to render a counter, we need the index to include in message
> counterView : Int -> CounterValue -> Html Msg
> counterView index counterValue =
>   CounterView.view (Increment index) (Decrement index) counterValue
>
> A note here: Looping over the entire list of counters to update one 
> single counter, with the update helpers, feels inefficient. An alternative 
> is to use Dict, and get the item to update. But then each branch in the 
> update is around 10 instead of 1 line, because get returns a Maybe type, 
> and we have to factor this in.
>
> The separated CounterView.elm module is:
> module CounterView exposing (..)
> import Html exposing (Html)
>
> {- our view function takes 3 arguments:
>   1. some Increment message (of any type, therefore in lowercase)
>   2. some decrement message
>   3. an Int with the counter value to display
> The output is Html + the msg type of the 2 input messages.
> So our view function, and this module do not own the message type.
> Could have put the static parts (the 2 messages) in a config record, like 
> the elm-sortable-table,
> but for just 2 input variables, a record feels like overkill
> -}
> view : msg -> msg -> Int -> Html msg
> view incrementMsg decrementMsg counterValue =
>   div [ style [("flex","0 0 32px")]]
> [ button [ onClick incrementMsg ] [ text "+" ]
> , div [] [ text (toString counterValue) ]
> , button [ onClick decrementMsg ] [ text "-" ]
> ]
>
> Note here: The API of this view function is msg -> msg -> Int, so the 
> importing module needs to know to pass these three variables + what they 
> are supposed to do + what type they should be.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this 

[elm-discuss] Re: Do the counters in the Guide teach us a wrong scaling approach?

2016-08-29 Thread Erik Lott

>
> Here's what I've been working on.  The recent git history is all about 
> refactoring.  Haven't introduced 'sub-components with state' or w/e and 
> don't see it coming soon.  It's an Elm-SPA with a Phoenix backend: 
> https://github.com/knewter/time-tracker


Josh, make sure to share this example in the other threads. Clean spa 
examples like this will help other folks find their elm legs. Good stuff..

On Monday, August 29, 2016 at 4:03:12 PM UTC-4, Josh Adams wrote:
>
> Here's what I've been working on.  The recent git history is all about 
> refactoring.  Haven't introduced 'sub-components with state' or w/e and 
> don't see it coming soon.  It's an Elm-SPA with a Phoenix backend: 
> https://github.com/knewter/time-tracker
>
> On Monday, August 29, 2016 at 11:37:10 AM UTC-5, Rex van der Spuy wrote:
>>
>>
>>> For newcomers to Elm, *wouldn't it be better to change the scaling from 
>>> 1 to multiple counters in the guide in a different way? *
>>> E.g.
>>>
>>>1. Build everything in 1 module, e.g. save a copy of counter.elm as 
>>>counter-list.elm
>>>2. Change every building block (Model, Msg, update, view) one at a 
>>>time, and upgrade each to handle multiple counters
>>>   - Suggested order: Model, view, Msg, update
>>>3. After that, separate out the view (and only the view) of an 
>>>individual counter, with signature like "msg -> msg -> Int -> Html msg"
>>>   - with the two msg's being for increment and decrement
>>>
>>>
>>>
>> I would love to know how to do this!
>> Can anyone point me to a brain-dead-simple practical and working example 
>> for a non-expert Elm user like myself?
>>
>> I, like Wouter, have modelled all the Elm apps I've built over the last 9 
>> months on the counter-list example - commonly nesting 3 layers deep.
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Do the counters in the Guide teach us a wrong scaling approach?

2016-08-28 Thread Erik Lott

>
> It's like I keep falling whenever I try to ride this new elm-bike. 
> And I keep hearing from others that they just get up and go and don't fall,
> so I should also just go and don't fall, or be very specific at which 
> point in my process I fall off my bike.
> (Sorry if the analogy is somewhat far fetched).


That's an honest reply. I certainly did not have this effortless learning 
experience. I've been programming applications for a long time, and Elm 
made me feel like a noob again. Very very humbling. 

Back in the days, when I learned react, I found this page 
> 
>  very 
> helpful. It explains how to structure in react. What state is, and where to 
> put it.
> Maybe a similar "thinking in elm" page will 
> a) help folks like me learn how to structure their apps in elm and 
> b) reduce unwanted/ vague questions about components on this forum.


+10 agree. I think at this point, its becoming obvious that there needs to 
be a more thorough "on-ramp" post(s) to ease folks' minds' into "thinking 
in elm". Without that, it's like the wild west - everyone is trying to 
figure out how to structure an app, and the only thing they can reach for 
is previous mental models - React folks try to apply react ideas to elm; 
Angular people try to apply angular ideas to elm, etc.. 

On Sunday, August 28, 2016 at 5:43:11 PM UTC-4, Wouter In t Velt wrote:
>
> Thanks for the feedback folks. Really helpful and got me thinking. Will 
> definitely dive into the links @NickH shared.
> And @ErikLott's example of a multi-page SPA (forgive the oxymoron) was 
> also helpful. This is one of the places I run into issues: my top level 
> update is already huge and growing.
>
> Also, I take the advice to heart to share/ ask questions on concrete and 
> practical cases.
>
> That said, for me, scaling Elm remains a struggle, and I find it hard to 
> pinpoint specific use cases to share here as a question.
>
> I really believe it when more experienced people say that elm scales, I am 
> just struggling with the "how".
>
> It's like I keep falling whenever I try to ride this new elm-bike. 
> And I keep hearing from others that they just get up and go and don't fall,
> so I should also just go and don't fall, or be very specific at which 
> point in my process I fall off my bike.
> (Sorry if the analogy is somewhat far fetched).
>
> This was different when I learned react some years ago.
> And I was just wondering why it was such a different experience.
>
> And it occurred to me that some of the "why does everyone insist on asking 
> about components"-meme may have been triggered because the counter example 
> is a very prominent (if not the most prominent) example in the Guide.
>
> I agree with Nick H that adding more examples is probably more helpful 
> than rewriting existing ones. 
>
> Back in the days, when I learned react, I found this page 
>  very 
> helpful. It explains how to structure in react. What state is, and where to 
> put it.
> Maybe a similar "thinking in elm" page will 
> a) help folks like me learn how to structure their apps in elm and 
> b) reduce unwanted/ vague questions about components on this forum.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Design of Large Elm apps

2016-08-28 Thread Erik Lott
Mark, tell me about this code:

type APICommand msg
= AddForum (Error -> msg) (ForumID -> msg) String
| DeleteForum (Error -> msg) (() -> msg) ForumID
| PostMessage (Error -> msg) (() -> msg) ForumID String


type APISubscription msg
= ForumList (List (ForumID, String) -> msg)
| MessageList (Array.Array String -> msg) ForumID


Conceptually, I appreciate what you're trying to do here (create a simple 
system driven by domain messages - AddForum, DeleteForum, etc) , but the 
actual implementation worries me. I'm wondering why you're not simply 
creating an API module instead:

module API exposing(addForum, deleteForum, postMessage)

addForum: String -> Task Http.Error Forum
// code here...

deleteForum: String -> Task Http.Error Never
// code here

etc
 

I know that you mentioned that you have some additional complexity (task 
queue, websockets,etc), but I haven't actually seen anything that would 
cause me to abandon the built-in command/subscriptions system. What if you 
need to do something in the page that is not necessarily domain related, 
but requires a task/command - e.g. generate a random number? Are these 
types of situations factored into your design?




On Saturday, August 27, 2016 at 6:14:41 PM UTC-4, Mark Hamburg wrote:
>
> I'm working on some example code. I'm varying between a moderately fleshed 
> out example of the plumbing but with little backing it up and a fully 
> worked but trivial to the point of not being interesting example. The 
> general model, however, works as follows:
>
> • We have a service model and a client model. The idea is that after 
> agreeing on an API, these can then undergo independent development. 
> Furthermore, we should be able to do things like mock the service rapidly 
> and then fill it in with a version that talks to the web service or 
> whatever is needed. Similarly, we could mock the client side quickly if we 
> just wanted to test the service APIs.
>
> • The API is represented by a union type: APICommand clientMsg. A typical 
> entry would be something like:
>
> | PostMessage (Error -> clientMsg) (() -> clientMsg) ForumId String
>
>
>
> • APICommand clientMsg is wrapped up inside a ClientCommand clientMsg type 
> that provides standard Cmd-style functionality (batch, map). It also 
> provides a way to embed non-API commands of type Cmd clientMsg. I would 
> have liked to just use a different type of message within Cmd to do this 
> rather than reconstructing map and batch — trivial though they may be — 
> but mapping for platform commands is built around tagging results as they 
> come back and we need to adjust the tagging functions on API commands 
> before they get to the service.
>
> • The update function for the client has the signature:
>
> clientMsg -> clientModel -> (clientModel, ClientCommand clientMsg) 
>
> This gets applied at the "root" level when processing messages destined 
> for the client. On the way back, it can turn the client commands into 
> platform commands of type Cmd (RootMsg serviceMsg clientMsg) where the 
> RootMsg type provides for messages bound for the client, messages bound 
> for the service, and API commands bound for the service.
>
> • The service processes both its own messages and API commands (in 
> separate update functions in my latest code). Service updates return 
> (serviceModel, 
> ServiceCommand serviceMsg clientMsg) where ServiceCommand again mirrors 
> Cmd in terms of providing batch and map support. (This could actually be 
> represented as a Cmd (Either serviceMsg clientMsg) but I'm not sure that 
> leveraging Cmd in that case provides more clarity.)
>
> • The root update function again maps the service commands appropriately 
> to generate commands of type Cmd (RootMsg serviceMsg clientMsg) which 
> route to the service and client as appropriate.
>
> The amount of code is actually pretty small and as discussed above, it 
> provides a very nice separation of concerns between the client side and the 
> server side and allows each to be coded following standard Elm architecture 
> patterns with the caveat that one doesn't actually use Cmd during 
> propagation.
>
> So, with that, I would be happy were it not for the fact that it's dawned 
> on me that subscriptions are going to be more difficult because I can't 
> simply wait for the runtime to ask the root model for subscriptions and 
> then plumb it appropriately. This is because the service model will almost 
> certainly need to adjust its state based on the client subscription 
> requests — see some effects managers for examples — and when asked for 
> subscriptions we can't update the root model. So, I will need to perform an 
> internal subscription update after every client model update. This isn't 
> fatal but I could imagine it being inefficient. I could also send a strobe 
> to do this but that might introduce more delay than I'd like. That said, 
> I've wondered whether subscriptions need lazy support akin to what we have 
> 

[elm-discuss] Re: Do the counters in the Guide teach us a wrong scaling approach?

2016-08-28 Thread Erik Lott
Folks, Elm scales just fine. We're at the tail-end of a large SPA front-end 
build in Elm... lots of complexity, and it's been wonderful.

The counter examples, sortable table, and autocomplete are fine examples of 
how to modularize elm code. They don't lead you down the wrong path, nor do 
they disagree with Richards advice to start simple (model/update/view). If 
you find this confusing, it just means you need to lay down a little more 
code first, and really internalize the simplicity of Elm... ultimately, 
regardless of how many modules you have, it's just functions all the way 
down, and a *single* state tree.

You won't build a large multipage app in a single module, nor does Richard 
ever promote that idea. You DO need to create modules to separate your app 
into pieces of functionality, and I'm not talking about Model, Update 
andView module (although you might decide to do this). The Counter module 
is a good example of a concept that has been pulled into a module - the 
fact that it is nested or not doesn't matter - it's just a module with an 
API, nothing more.

Here is a very basic primer showing how you might structure an imaginary 
SPA app:

Top Level

Page 1
Page 2 
Page 3
Page 4


Top Level
- Model hold the business/domain data tree for the entire app, the 
'currentPage', and the 'currentUser' (if you have to deal with auth).
- View uses the "currentPage" state to decide which page to display. 
- View passes slices of domain/business data to the Page.view function 
(Page models do not hold business/domain data)

Page Level
- Model hold page related state (this page section is open, this page 
section is closed, this form is submitting, etc).
- Page may provide an api, so that specific events that occur inside the 
page can be responded by outside code (The top level might take some action 
when the form on a Page has been submitted).

In all honesty, our app is not exactly arranged like this, but this 
imaginary example should be enough for people to ask questions about. How 
do I build this? How do I build that? Specific questions like this are so 
much easier to answer than "Does elm scale".


 


On Sunday, August 28, 2016 at 7:02:04 AM UTC-4, Wouter In t Velt wrote:
>
> Something I have been struggling with for quite some time (coming from 
> React and Flux) is how to scale. There are various posts on this forum 
> related to the topic, e.g. Design of large elm apps 
> , parent 
> child communication 
> ,
>  
> components 
> 
> .
>
> On structuring apps, I found the elm-sortable-table and the autocomplete 
> video - shared by Peter Damoc in this thread 
>  - 
> to be very helpful, as well as advice here 
> .
>
> My summary of the advice is more or less:
>
>- Forget about about "components": the term is very confusing, means 
>very different things in different contexts.
>- Start to build with 1 Model, 1 Msg, 1 update, 1 view
>- As soon as one these becomes too big, seperate that one out to a 
>view-helper, or update-helper etc
>
> This very much feels like a "top-down"  approach: the module you start 
> with remains on top. Put everything in there, and split out if needed.
> I keep reminding myself to stop trying to keep pieces of each of the 4 
> building blocks (Model, Msg, update, view) bundled as I separate out. That 
> it is fine to e.g. just put a piece of view code in a separate place - 
> *without 
> trying to bundle it with corresponding pieces of Model, Msg, and update.*
>
> Now I am not sure that my take on "how to do stuff"  is the right way, but 
> it does seem that the *multiple-counters example in the guide teach us 
> exactly the opposite pattern*. 
> *Do the multiple counter examples in the guide put us on the wrong foot?*
>
> We start out with one counter being the top module, and then we add a 
> wrapper *on top* to handle multiple instances of this counter.
> To make matters worse: the multiple counter examples introduces the kind 
> of opaque nesting and messaging structure that is being discouraged here:
> The parent does not know anything about each child counter, parent has its 
> own Msg structure etc.
> After scaling, the counter now has in effect become something that looks 
> and smells very much like a component.
>
> Just the other day I realized that much of my struggle with scaling came 
> from stuff I picked up on day 1 of learning Elm, with sinful thoughts such 
> as:
> "Hey, this counter thing in Elm is just like a reusable UI element. Just 
> like a react component, with state and all. 

[elm-discuss] Re: Collecting use cases for File, ArrayBuffer and TypedArrays/DataViews

2016-08-24 Thread Erik Lott
Our primary application allows photographers to upload hundreds/thousands 
of images for portfolio display. image delivery, etc. I guess you could say 
that our app is generally driven by image uploads. I would love to see this 
functionality provided by Elm, rather than having to use ports...

On Thursday, July 28, 2016 at 5:17:51 PM UTC-4, Daniel Bachler wrote:
>
> I'd love to see support for the File and ArrayBuffer Apis, and maybe 
> TypedArrays/DataViews as well. IMHO they are an important piece of the Web 
> Platform that is still missing in Elm.
>
> Evan suggested collecting concrete use cases to guide the design. I would 
> like this thread to be the starting point of this effort. I would like to 
> ask anyone who would also like this feature or who has substantial 
> experience using either Api to add use cases or comment here so that we can 
> try to define the user story for both apis. From there, we could decide 
> what we would like to see supported and what, if anything, we don't need 
> for now and suggest Elm Apis.
>
> I have two stories from a side project of mine. It is a slideshow editor 
> that allows the user to select photos and audio files from the local 
> system, uploads them to a web service, let's the user arrange and 
> manipulate photos and music and then share the result with others. For 
> this, I have two immediate use cases plus some more ideas:
>
> *Upload local files as binary blob to AWS S3*
>
> In my current, (hacky) version, I use the FileReader api (via simonH1000's 
> filereader library) to read the content of a file into an ArrayBuffer, 
> (represented as Json.Value in Elm) then use a modified version of elm-http 
> to upload the content of the ArrayBuffer to an S3 storage bucket.
>
> *Download mp3 files, decode them and play them back via the AudioApi*
>
> Currently I do this with my modified http library to download the mp3 file 
> into an arraybuffer, then pass the resulting arraybuffer through a port to 
> some native javascript that then uses the Audio Api to decode the mp3 file 
> into a playable audiobuffer.
>
> *Parsing or otherwise processing local text files. *
>
> For another project I would be interested in reading and parsing 
> Swagger/OpenAPI definition files and then providing a UI to compare rest 
> apis. Since the processing will be done on simple Strings, this would only 
> require FileReader support (specifically the readAsText method). This would 
> already work with the FileReader library as is (though that one is not 
> available on package.elm-lang.org because it contains native code and is 
> not whitelisted).
>
> *TypedArrays and DataViews*
>
> I haven't worked with these yet, but I can anticipate some cases that 
> would be interesting:
>
> *Parsing/manipulating of binary data via the ArrayBuffer api.*
>
> One case I personally would like to do with this, is to parse the Exif 
> header of the jpeg files the user loaded from the local file system. My 
> slideshow could then display metadata information without roundtripping to 
> the server.
>
> *Create geometry for WebGL in the form of Vertex Buffers*
>
> *Generating sound/music by writing raw audio samples*
>
> These could then be played back via the Web audio apis.
>
>
> Please add your own ideas to this thread. Once we have compiled a list of 
> use cases, we can look at the JS Apis available under the Web Platform for 
> Files, ArrayBuffers, Typed Arrays etc. and think how these could be exposed 
> to Elm. 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Task ports: A proposal to make it easier to integrate JS with Elm.

2016-08-23 Thread Erik Lott

>
> But isn't that covered by the error handling of tasks? The same way as 
> when you use the "built-in" tasks like Http? Http gets around the general 
> issue of "what happens if this never returns" using the Http.Error value 
> Timeout. Maybe something similar could be used for Task Ports.


It's hard to disagree with that rationale. A "Timeout" and 
"UnexpectedValue" error would be all that is needed to handle cases where 
functions return no promise, a non-resolving promise, or a promise with an 
incorrect return type. 
 

On Tuesday, August 23, 2016 at 6:21:38 PM UTC-4, Tim Stewart wrote:
>
> But isn't that covered by the error handling of tasks? The same way as 
> when you use the "built-in" tasks like Http? Http gets around the general 
> issue of "what happens if this never returns" using the Http.Error value 
> Timeout. Maybe something similar could be used for Task Ports.
>
> In the same case with standard Cmd / Sub, you would just never receive the 
> Sub. It gives you LESS opportunity to handle the JS error through a timeout 
> or similar mechanism.
>
> Not to mention the added complexity when using Cmd / Sub of tracking 
> separate, parallel calls to the same port. You have the overhead not only 
> of managing two different entry points to your update function (as with any 
> Cmd/Sub pair for an essentially single asynchronous operation), but of 
> encapsulating some kind of state identifier that lets you match the 
> incoming Subs with whatever Cmd they related to in the first place. The use 
> of Tasks on the Elm side and Promises on the JS side makes this unnecessary.
>
> I know, Elm design decisions are based on concrete use cases not on waffly 
> hand-waving. I'll try and find time to write one up.
>
>
> On Tuesday, August 23, 2016 at 11:56:06 PM UTC+10, Erik Lott wrote:
>>
>> Although I'd love to be able to use and compose port commands like tasks, 
>> I'm not a big fan of this solution. 
>>
>> regular ports only let you send data off or receive data back, not both.
>>
>>
>> This is a good design decision. Ports isolate Elm from the underlaying 
>> language (javascript) and avoids creating dependencies on the outside 
>> implementation: you fire commands out of ports, and don't need to be 
>> concerned about what happens to that data once it's exited the port. You 
>> receive subscription messages from js, and don't have to be concerned about 
>> how they were generated.
>>
>> As soon as you send a command out of a port and expect something in 
>> return, you've created a dependency, and a new source of runtime errors 
>> that the compiler can't catch.
>>
>>
>> On Saturday, August 13, 2016 at 11:31:07 AM UTC-4, James Wilson wrote:
>>>
>>> The problem
>>>
>>> ports as they stand are fundamentally incompatible with Tasks. Being 
>>> backed by Cmd's, they are harder to compose. A frustration of mine is that 
>>> often we are directed to "just use ports" when a proper interface to some 
>>> native API is not yet available, but this leads to our Msg types growing 
>>> and more significant changes being required when eventually the proper 
>>> interface is made available.
>>>
>>> Also, many JS interop things I find myself wanting to do are 
>>> fundamentally one-shot functions which I expect a result back into Elm from 
>>> immediately, or otherwise just want to compose with other Task based 
>>> things. Some examples that come to mind of one-shot tasks you may want to 
>>> compose rather than use the streaming interface that ports provide:
>>>
>>>- Getting items from local/sessionStorage
>>>- .. really, most things involving working with the Web API that 
>>>arent yet implemented in Elm.
>>>- Embedding JS widgets into Elm elements
>>>- Using a JS library for doing things like hashing passwords or 
>>>obtaining some data back from some custom service
>>>- Interacting with things like Electron for creating apps that can 
>>>run in the desktop and interact with the filesystem etc.
>>>
>>>
>>> The solution
>>>
>>> Task ports. The idea is that these are defined the same way that Ports 
>>> in elm currently are, but they return a Task type rather than a Cmd or Sub 
>>> type. On the JS Side, we attach a function to the Elm app that returns a 
>>> Promise, and on the Elm side we wait for the Promise returned to reject or 
>>> resolve, and marhsall the error or result from the promise into the error 
&

[elm-discuss] Re: Task ports: A proposal to make it easier to integrate JS with Elm.

2016-08-23 Thread Erik Lott
Although I'd love to be able to use and compose port commands like tasks, 
I'm not a big fan of this solution. 

regular ports only let you send data off or receive data back, not both.


This is a good design decision. Ports isolate Elm from the underlaying 
language (javascript) and avoids creating dependencies on the outside 
implementation: you fire commands out of ports, and don't need to be 
concerned about what happens to that data once it's exited the port. You 
receive subscription messages from js, and don't have to be concerned about 
how they were generated.

As soon as you send a command out of a port and expect something in return, 
you've created a dependency, and a new source of runtime errors that the 
compiler can't catch.


On Saturday, August 13, 2016 at 11:31:07 AM UTC-4, James Wilson wrote:
>
> The problem
>
> ports as they stand are fundamentally incompatible with Tasks. Being 
> backed by Cmd's, they are harder to compose. A frustration of mine is that 
> often we are directed to "just use ports" when a proper interface to some 
> native API is not yet available, but this leads to our Msg types growing 
> and more significant changes being required when eventually the proper 
> interface is made available.
>
> Also, many JS interop things I find myself wanting to do are fundamentally 
> one-shot functions which I expect a result back into Elm from immediately, 
> or otherwise just want to compose with other Task based things. Some 
> examples that come to mind of one-shot tasks you may want to compose rather 
> than use the streaming interface that ports provide:
>
>- Getting items from local/sessionStorage
>- .. really, most things involving working with the Web API that arent 
>yet implemented in Elm.
>- Embedding JS widgets into Elm elements
>- Using a JS library for doing things like hashing passwords or 
>obtaining some data back from some custom service
>- Interacting with things like Electron for creating apps that can run 
>in the desktop and interact with the filesystem etc.
>
>
> The solution
>
> Task ports. The idea is that these are defined the same way that Ports in 
> elm currently are, but they return a Task type rather than a Cmd or Sub 
> type. On the JS Side, we attach a function to the Elm app that returns a 
> Promise, and on the Elm side we wait for the Promise returned to reject or 
> resolve, and marhsall the error or result from the promise into the error 
> or result type required by the Task type of the port.
>
> Let's see how this might work:
>
>
> *Ports.elm:*
>
> port apiSession: Task String SessionId
>
>
>
> *Main.elm:*
>
> import Ports
> import Json.Decode as Decode
> import Task exposing (andThen)
>
>
> -- get an API session from JS land and make an http request using it
> -- given some path and a decoder to decipher the result:
> apiRequest : String -> Decoder a -> Task ApiError a
> apiRequest path decoder =
>   let
> headers sessId =
> [ ("Content-Type", "application/json")
> , ("MyApp-SessionId", sessId)
> ]
>
>
> req sessId = Http.send Http.defaultSettings
> { verb = "POST"
> , headers = headers sessId
> , url = path
> }
>
>
> decodeResponse res = Decode.decodeString decoder -- ...handle error 
> etc
>   in
> Ports.apiSession `andThen` req `andThen` decodeResponse
>
>
> *App.js:*
>
> Elm.Main.ports.apiSession = function(){
> return new Promise(function(resolve,reject){
>
>
> var sess = localStorage.getItem("sessionId");
> if(!sess) reject("NO_SESSION");
> else resolve(sess);
>
>
> });
> }
>
> var app = Elm.Main.fullscreen();
>
>
>
>
> Here, we use a tiny bit of JS to access localStorage and pull out a 
> session ID. This function is used whenever the apiRequest Task is performed 
> in Elm, and composes nicely into our apiRequest without the need for a 
> complicated effect manager or threading a sessionId through everywhere just 
> because we need to get it from a Cmd based port.
>
> One of the nice things about this is that there is minimal refactoring to 
> do for those things that do eventually receive coverage in the Elm Web API 
> - you're just swapping out Tasks for other Tasks. As the Web API will 
> always be changing, I think that having a nice way to make JS polyfills 
> like this will always have some value, let alone for interacting with 
> libraries written in JS that haven't or won't ever be ported to Elm.
>
> Elm would continue to make the same guarantees as with other ports; if the 
> task port can't marshall the response back into Elm an error would be 
> thrown along the same lines as is currently done via ports.
>
> Summary
>
> - regular ports only let you send data off or receive data back, not both.
> - Cmd's and Sub's are not composable
> - Task based ports allow you to create a new Task that is backed by JS
> - Task based ports allow for better composition and less friction when the 
> 

[elm-discuss] Re: We need a clearer story on architecture

2016-08-17 Thread Erik Lott
I feel like I just wrote you a vague response - something I try to avoid. 
If you have a specific question about how to build or structure something 
in Elm, don't hesitate to ask.

On Wednesday, August 17, 2016 at 12:19:21 PM UTC-4, Oliver Searle-Barnes 
wrote:
>
> I've been using Elm for about 4 weeks now and having generally been loving 
> it. An area that I'm really having trouble with though is architecture. The 
> basic TEA is a fantastic foundation but the guidelines are really very 
> limited with regards to requirements of a typical SPA. 
>
> * Components - the best advice I've heard is to extract view/model/update 
> separately, as we've seen with elm-mdl this only goes so far though. In the 
> end every large application is going to end up with it's own framework 
> similar to elm-mdl so this seems to be an issue that needs to be resolved 
> somehow. 
> * Separation between view model(component state) and application model 
> (records from the server) - previously I've always had these two separated 
> which has meant that I can have multiple views updating the same server 
> records. 
> * Services - when I've had cross-cutting concerns I would typically manage 
> them in a service tier, e.g. I'm using websockets and want to update the 
> view optimistically. Managing the optimistic vs confirmed state isn't 
> something that I'd expect to have abstracted away from the view.
>
> I'm not really looking to resolve these issues here but I do feel like the 
> community is going in circles. Every day we hear the same questions like 
> "how does parent-child communication work?" but the advice that is given is 
> different depending who you ask (and always feels unresolved). 
>
> A general concern I have is that the impression that's given is that 
> abstraction is treated as something which should be avoided. This seems 
> unworkable for large SPAs. It gives the impression that perhaps no one in 
> the Elm community is really building large applications. 
>
>
> These are my concerns and issues, what I'm really looking for though is an 
> approach to move things forward. Given that there are existing frameworks 
> with well understood architectures I wonder if we should work on guides of 
> the form Elm for React users or Elm for Ember users and try to translate 
> the concepts from those frameworks into practical solutions within Elm. I 
> think this would help clarify the advice and perhaps uncover areas where we 
> need to give some more thought.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: We need a clearer story on architecture

2016-08-17 Thread Erik Lott
Oliver, we're currently migrating a large production SPA to Elm - 15+ pages 
non-trivial app, drag and drop interfaces, complex data display, 
integrating with multiple backends, etc. Not a toy.

Components - the best advice I've heard is to extract view/model/update 
> separately, as we've seen with elm-mdl this only goes so far though. In the 
> end every large application is going to end up with it's own framework 
> similar to elm-mdl so this seems to be an issue that needs to be resolved 
> somehow. 


If you mean dividing a component into 3 separate files - ie. model.elm, 
update.elm, view.elm , then yeah, that's fine. A single file is too. If you 
have a massive Elm component that you feel is difficult to manage in a 
single file, and splitting it into three pieces will make it much easier to 
maintain and understand, go ahead and do that. Whether your component is 3 
files, or a single file shouldn't change your overall architecture - it's 
just a horizontal partitioning of functions.

I'm not sure what you mean by framework - do you mean elm-parts? If so, 
just forget about that for now and connect your components manually. It's 
not a big deal.

Separation between view model(component state) and application model 
> (records from the server) - previously I've always had these two separated 
> which has meant that I can have multiple views updating the same server 
> records. 


Yes, exactly right. Conceptually, you'll want to make sure that you have a 
single source of truth for your business state, and your components only 
manage their internal state - they do not store business state in their 
model. Evan has created a great example here: 
https://github.com/evancz/elm-sortable-table/blob/master/README.md#about-api-design
 . 
When you update your business state, any component displaying that state 
should automatically reflect that change. 

Notice that I've said "Conceptually". I get the impression that most folks 
in the Elm discuss board have small apps that can hold their entire 
business model in memory all at once, like a todo application - In that 
case, that business state could be stored all together in the root model 
and used as the single source of truth of business data. In our case, 
however, we have a huge amount of user data, and it would be unreasonable 
to load all of that data into the app at startup. Instead, as the SPA 
transitions from page to page, we load only the data that is required for 
that page - We have no central business data in our app, because our server 
itself serves acts as the single source of truth.

Services - when I've had cross-cutting concerns I would typically manage 
> them in a service tier, e.g. I'm using websockets and want to update the 
> view optimistically. Managing the optimistic vs confirmed state isn't 
> something that I'd expect to have abstracted away from the view.


I'm not sure if I follow you on this, but I think this is something that I 
would actually abstract away from the view. If you're using websockets to 
update your business model, go ahead and do that - the model will be 
automatically reflected in the view. Your view shouldn't know anything 
about websockets.

These are my concerns and issues, what I'm really looking for though is an 
> approach to move things forward. Given that there are existing frameworks 
> with well understood architectures I wonder if we should work on guides of 
> the form Elm for React users or Elm for Ember users and try to translate 
> the concepts from those frameworks into practical solutions within Elm. I 
> think this would help clarify the advice and perhaps uncover areas where we 
> need to give some more thought.


I would second the need for better "official" documentation in Elm for 
folks getting started. There is a learning curve to Elm, but once it 
"clicks", it'll be more obvious how to piece your application together.





On Wednesday, August 17, 2016 at 12:19:21 PM UTC-4, Oliver Searle-Barnes 
wrote:
>
> I've been using Elm for about 4 weeks now and having generally been loving 
> it. An area that I'm really having trouble with though is architecture. The 
> basic TEA is a fantastic foundation but the guidelines are really very 
> limited with regards to requirements of a typical SPA. 
>
> * Components - the best advice I've heard is to extract view/model/update 
> separately, as we've seen with elm-mdl this only goes so far though. In the 
> end every large application is going to end up with it's own framework 
> similar to elm-mdl so this seems to be an issue that needs to be resolved 
> somehow. 
> * Separation between view model(component state) and application model 
> (records from the server) - previously I've always had these two separated 
> which has meant that I can have multiple views updating the same server 
> records. 
> * Services - when I've had cross-cutting concerns I would typically manage 
> them in a service tier, e.g. I'm using websockets and want to 

Re: [elm-discuss] Re: Design of Large Elm apps

2016-08-09 Thread Erik Lott
Haha yeah I get your point, but when you talk about the large redink code 
base (no doubt it's huge), I'm curious of the granularity of your 
production Elm apps. Is your code base generally organized as one/a few 
large single page applications (routing handled client side - data via api) 
or is your code organized into many smaller applications, each served on a 
single server rendered html page (routing handled server side - maybe 
initial data is provided directly through Elm.fullscreen rather than 
hitting an api). What say you good sir?

It would be helpful to know, and would add some context to your comments. 



On Tuesday, August 9, 2016 at 10:28:33 PM UTC-4, Richard Feldman wrote:
>
> Either. :)
>
> On Tue, Aug 9, 2016, 7:20 PM Erik Lott <mreri...@gmail.com > 
> wrote:
>
>> Richard, just to clarify, when you say "pages", are you referring to 
>> server side rendered pages that each contain an Elm app, or a large Elm 
>> single page app that handles routing internally?
>>
>>
>>
>>
>>
>> On Tuesday, August 9, 2016 at 7:54:24 PM UTC-4, Richard Feldman wrote:
>>>
>>> But passing the callback down through the chain of nested components is 
>>>> ugly, fragile and may not even work if two components are not in the same 
>>>> parent-children chain. 
>>>>
>>>
>>> Not quite sure if that's what this is saying, but a good rule of thumb 
>>> is that Msg should never have a function in it, and neither should Model.
>>>
>>> Maybe I don't understand the Elm Architecture, but as far as I know 
>>>> every Elm module has it's own model, view and the update function.
>>>>
>>>
>>> For our (enormous) Elm code base at work, most pages (as in an 
>>> individual URL an end user can visit) have one model, one view, and one 
>>> update function. There is no "parent-child communication" on these pages.
>>>
>>> We had Elm in production for months before we encountered the first time 
>>> it was a good idea to have a "parent-child" relationship, and it was over 6 
>>> months (and well over 10,000 lines of Elm code) before we found the second 
>>> case where it was a good idea.
>>>
>>> Here is what I recommend:
>>>
>>>1. For a given page, start with one model, one view, and one update.
>>>2. If one of those (model, view, or update) gets too big and starts 
>>>feeling unwieldy, *subdivide only that thing.* For example, if view 
>>>feels too big, split it into some helper functions but *don't touch 
>>>model or update.* If update feels too big, same thing - split out 
>>>helper functions but don't touch the view or model. If your model feels 
>>> too 
>>>big, *reorganize only the model*. Split it from one record into some 
>>>nested records, but don't rearchitect update or view.
>>>3. Any time you find yourself thinking "I bet this will be nicer if 
>>>I split it into its own model/update/view" your next thought should be 
>>>"whoops! That's a classic beginner mistake. My code will actually be 
>>> worse 
>>>if I do that. Glad I didn't do that!" (It's an easy trap to fall into - 
>>> I 
>>>fell into it myself, and fell hard, as a beginner.)
>>>
>>> Basically, whenever I meet someone who is new to Elm and asking about 
>>> parent-child communication, what I really want to say is "a parent-child 
>>> relationship in an application is very rarely the right tool for the job, 
>>> and is almost certainly not what you want as a beginner. How can I help you 
>>> avoid falling into the same trap I fell into when I was just starting out?" 
>>> :)
>>>
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "Elm Discuss" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/elm-discuss/_cfOu88oCx4/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Design of Large Elm apps

2016-08-09 Thread Erik Lott
Richard, just to clarify, when you say "pages", are you referring to server 
side rendered pages that each contain an Elm app, or a large Elm single 
page app that handles routing internally?





On Tuesday, August 9, 2016 at 7:54:24 PM UTC-4, Richard Feldman wrote:
>
> But passing the callback down through the chain of nested components is 
>> ugly, fragile and may not even work if two components are not in the same 
>> parent-children chain. 
>>
>
> Not quite sure if that's what this is saying, but a good rule of thumb is 
> that Msg should never have a function in it, and neither should Model.
>
> Maybe I don't understand the Elm Architecture, but as far as I know every 
>> Elm module has it's own model, view and the update function.
>>
>
> For our (enormous) Elm code base at work, most pages (as in an individual 
> URL an end user can visit) have one model, one view, and one update 
> function. There is no "parent-child communication" on these pages.
>
> We had Elm in production for months before we encountered the first time 
> it was a good idea to have a "parent-child" relationship, and it was over 6 
> months (and well over 10,000 lines of Elm code) before we found the second 
> case where it was a good idea.
>
> Here is what I recommend:
>
>1. For a given page, start with one model, one view, and one update.
>2. If one of those (model, view, or update) gets too big and starts 
>feeling unwieldy, *subdivide only that thing.* For example, if view 
>feels too big, split it into some helper functions but *don't touch 
>model or update.* If update feels too big, same thing - split out 
>helper functions but don't touch the view or model. If your model feels 
> too 
>big, *reorganize only the model*. Split it from one record into some 
>nested records, but don't rearchitect update or view.
>3. Any time you find yourself thinking "I bet this will be nicer if I 
>split it into its own model/update/view" your next thought should be 
>"whoops! That's a classic beginner mistake. My code will actually be worse 
>if I do that. Glad I didn't do that!" (It's an easy trap to fall into - I 
>fell into it myself, and fell hard, as a beginner.)
>
> Basically, whenever I meet someone who is new to Elm and asking about 
> parent-child communication, what I really want to say is "a parent-child 
> relationship in an application is very rarely the right tool for the job, 
> and is almost certainly not what you want as a beginner. How can I help you 
> avoid falling into the same trap I fell into when I was just starting out?" 
> :)
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-07-21 Thread Erik Lott
It's a neat idea, but it makes me uncomfortable, because it introduces a 
possible source of errors into the application. What if a message is 
dispatched to the wrong port?

The code that I posted at the top of this thread is a simplistic example of 
how to dispatch messages across your app, but you probably don't want to be 
communicating with simple primitives (String, Int, etc). Just like you use 
union types for messages within TEA components, use union types for your 
app wide messages as well. 

For example, if you need to broadcast/subscribe to some app wide events, 
you could create an Events.elm module that isolates all of this logic:

port module Events exposing (Event(..), publish, subscribe)


type Event
= SomethingHappened
| SomethingElseHappened Int


type alias DTO = 
  (String, String)

-- Ports

port eventOutgoingPort : DTO -> Cmd msg

port eventIncomingPort : (DTO -> msg) -> Sub msg


-- PubSub

publish : Event -> Cmd msg
publish evt =
outgoingEventPort (serialize evt)


subscribe : (Event -> msg) -> Sub msg
subscribe f =
Sub.map f (incomingEventPort deserialize)

-- Serialization

serialize : Event -> DTO
serialize evt =
case evt of
SomethingHappened ->
  ("SomethingHappened", "")

SomethingElseHappened int ->
("SomethingElseHappened", ... serialize int to json)


deserialize : DTO -> Event
deserialize ( key, json ) =
case key of
"SomethingHappened" ->
SomethingHappened

"SomethingElseHappened" ->
SomethingElseHappened ... deserialize json to int


Dispatching an event looks like this:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
BlahMsg ->
( initialModel, Events.publish Events.SomethingHappened )

And subscribing to events looks something like this:

type Msg
= Event Events.Event



subscriptions : Model -> Sub Msg
subscriptions model =
Events.subscribe Event


I hope that makes sense.


On Thursday, July 21, 2016 at 2:30:30 PM UTC-4, OvermindDL1 wrote:
>
> I actually took your format and made it more generic:
> ```elm
> var app = Elm.Main.fullscreen();
>
> app.ports.*dispatchGlobal*.subscribe(function({portName, msg}) {
> app.ports[portName].send(msg);
> });
> ```
> Where the dispatchGlobal would be:
> ```elm
> port *dispatchGlobal* : {portName : String, msg : Json.Encode.Value} -> 
> Cmd msg
> ```
> And the receiving could be about whatever you want:
> ```elm
> port *receiveSomeMessage* : ({something : Int, more : String} -> msg) -> 
> Sub msg
> ```
> Dispatching via a helper function like:
> ```elm
> dispatchSomeMessage =
>   dispatchGlobal {portName="receiveSomeMessage", (object [("something", 
> int 42), ("more", string "blah")])}
> ```
>
> Although I am using this style for a certain javascript callback library 
> that Elm does not support yet and not needed it to toss messages 'far' away 
> yet, and hope to not need to...
>
>
> On Thursday, July 21, 2016 at 12:01:26 PM UTC-6, Erik Lott wrote:
>>
>> Hey Aislan,
>>
>> Max's point of avoiding unnecessary components is a good one, but it 
>> depends on what scale of app/architecture you're talking about.
>>
>> When you're building building smaller types of UI components, it's a good 
>> rule to get you started. For example, let's say you want to build something 
>> simple like an html form in elm. You may want some input fields, select 
>> boxes, error messages, and maybe a custom submit button (whatever that is). 
>> This can likely be built within a single TEA component, without the need to 
>> create any additional subcomponents. Creating subcomponents for individual 
>> inputs, or special buttons, etc will likely be an unnecessary abstraction 
>> that will only make your code harder to understand, and harder to maintain. 
>> On the small scale, just avoid unnecessary componentization and you'll be 
>> fine.
>>
>> When you're building something at a larger scale like a single page app, 
>> that contains various layouts, menus, &  pages - which contain several 
>> components per page - you'll need components to keep your code organized, 
>> maintainable, and easy to understand. 
>>
>> The inter-component communication method that I posted at the top of this 
>> thread is likely only useful in a large app, where there's a need for app 
>> wide communication. Using this method for small scale parent-child 
>> communication probably overkill.
>>
>>
>>
>>
>> On Thursday, July 21, 2016 at 12:41:09 PM UTC-4, Aislan de Sousa Maia 
>> wr

Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-07-21 Thread Erik Lott
Hey Aislan,

Max's point of avoiding unnecessary components is a good one, but it 
depends on what scale of app/architecture you're talking about.

When you're building building smaller types of UI components, it's a good 
rule to get you started. For example, let's say you want to build something 
simple like an html form in elm. You may want some input fields, select 
boxes, error messages, and maybe a custom submit button (whatever that is). 
This can likely be built within a single TEA component, without the need to 
create any additional subcomponents. Creating subcomponents for individual 
inputs, or special buttons, etc will likely be an unnecessary abstraction 
that will only make your code harder to understand, and harder to maintain. 
On the small scale, just avoid unnecessary componentization and you'll be 
fine.

When you're building something at a larger scale like a single page app, 
that contains various layouts, menus, &  pages - which contain several 
components per page - you'll need components to keep your code organized, 
maintainable, and easy to understand. 

The inter-component communication method that I posted at the top of this 
thread is likely only useful in a large app, where there's a need for app 
wide communication. Using this method for small scale parent-child 
communication probably overkill.




On Thursday, July 21, 2016 at 12:41:09 PM UTC-4, Aislan de Sousa Maia wrote:
>
> Hello guys! I'm a kind of noob with all of this. Can you explain a little 
> more the concern regarding componentization? Some examples could be great. 
>
> Thanks for all!
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Inter-Component Communication in 0.17

2016-07-15 Thread Erik Lott
Max, build a non-trival 15+ page SPA within a single elm component, and 
tell me how that goes :)


On Friday, July 15, 2016 at 8:08:23 PM UTC-4, Max Goldstein wrote:
>
> Allow me to suggest that this approach is *totally overkill*. It might not 
> be, but this is something Richard and I were discussing last night at the 
> meetup. If you come from React, everything is a component, so you reach for 
> them. But, for many uses cases, nesting TEA is unnecessary. Go ahead and 
> make Model and Msg huge types. The compiler will keep you from breaking 
> things. 

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Sending messages up the component tree in Elm 0.17

2016-07-13 Thread Erik Lott
Sandi, one way to manage component to component communication is to use 
ports and subscriptions:
https://groups.google.com/d/msg/elm-discuss/i99LBvYSkpY/yQyk6WB0AAAJ

Hope that helps.

On Thursday, July 7, 2016 at 1:50:41 PM UTC-4, Sandi Dušić wrote:
>
> In Elm 0.16 the Architecture tutorial had one more button list example 
> 
>  (I 
> dug that up from an old commit), aside from this one 
> .
>  
> Each counter would have it's own remove button which would remove that 
> exact one when clicked, unlike in the simpler example with a sole remove 
> button that removes the first counter. This was accomplished by passing two 
> addresses to the counter view, one for it's own actions and another which 
> it's father component (CounterList) handled, used for signaling removal. 
>
> I did the exact same thing in my application. I have a bunch of small 
> components in a big component, and the big component needs to know when one 
> of the small ones has been clicked. How do you do this in 0.17? Is it 
> impossible, since they removed the example which is supposed to implement 
> it?
>
> This is the only thing I can think of: Add the message that needs to be 
> sent upwards to the big component to the message union of the small 
> component (in the CounterList, this would mean Counter.Msg has Remove). 
> When the big component gets a small component action, it would first check 
> with an if whether it's the one it needs to handle (if msg == 
> Counter.Remove then ...). If so, it can handle it (remove the Counter), 
> otherwise it would just regularly pass it to Counter.update.
>
> To me that seems like it goes against the principles of Elm Architecture. 
> You can no longer treat components (and especially their actions) like 
> black boxes, but rather you have to tear them apart in a way. They cannot 
> fully define their interface. I don't know, it's just weird.
>
> If there's a way to define custom subscriptions they might be leveraged to 
> solve this, but I don't see a way to do that in the API. I apologize if 
> this is a silly question, 0.17 is still new to me.
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Bubbling Http Errors from Nested Components

2016-07-07 Thread Erik Lott
Mark:

That's lead me to think about but not yet write a command alternative that 
> could also handle tasks that didn't need to be routed back to the 
> originator and that could be used to send messages to the top-level (or 
> elsewhere).


I think you've nailed it. The suggested ELM architecture doesn't easily 
allow for application specific communication from the lower nested 
components to the upper components. There are times when in the scope of an 
overall architecture, you'd like to return some type of application wide 
recognized event/message back up the update stack, and have any interested 
ancestor component react to it... This is essentially how Commands 
function. Commands are a globally recognized type, that are returned up the 
stack, and although they may carry a local message type with them, the 
command itself is never returned or reused. The Command reaches the 
application root, and is processed by the core language.

Like you said: I think what we need (or at least what I need) is our own 
Application specific type to return up the stack instead of Cmd. An "Event" 
union type possibly? And CmdEvt tag could wrap the native elm Cmd, and be 
unwrapped at the root.

type Event 
  = CmdEvt Cmd
  | MsgEvt
  | Unauthorized
  | LoggedIn User
  | ConfirmPopup CancelMsg OkMsg



On Tuesday, July 5, 2016 at 1:30:51 PM UTC-4, Mark Hamburg wrote:
>
> The first option feels repugnant from an encapsulation standpoint. I've 
> built the second option and it works but it increases the amount of 
> boilerplate in hierarchical systems because we now have three results to 
> deal with in update functions. That's lead me to think about but not yet 
> write a command alternative that could also handle tasks that didn't need 
> to be routed back to the originator and that could be used to send messages 
> to the top-level (or elsewhere). That said, once one gets into replacing 
> Cmd, the API request model makes a lot of sense.
>
> Mark
>
> On Jul 5, 2016, at 5:46 AM, Erik Lott <mreri...@gmail.com > 
> wrote:
>
> My app has several layers of nested components. Various components 
> throughout the tree will need to interact with our API via http requests. 
> If any API request returns a 401 - Not Authorized error, or a Timeout 
> Error, the error needs to bubble up to the root component where is can be 
> handled appropriately.
>
> What is the most idiomatic way of dealing with this? 
>
> *1. Parent should pattern match against important child messages*: 
> Reference 
> <https://groups.google.com/d/msg/elm-discuss/QPqrJd4C78Y/_TLLg81SAQAJ>
> This could work, but would be unreasonable in this case. The root 
> component would need to match against every failing api http request made 
> by every child, grandchild, great-grandchild, etc, component in the tree. 
> If a single pattern is missed, the app would be in an error state, so this 
> is prone to mistakes.
>
> *2. Nested Components return additional info from the "update" function*: 
> Reference 
> <http://stackoverflow.com/questions/37328203/elm-0-17-how-to-subscribe-to-sibling-nested-component-changes>
> Each component returns an additional value from its update function like 
> this:
> update : Msg -> Model -> (Model, Cmd Msg, SomeInfo)
>
> The parent component could inspect the returned "SomeInfo" value from its 
> direct children, and act on that information if necessary.  In my case, any 
> nested component that makes http requests to our API would be responsible 
> for returning a APINotAuthorized and APITimeout value to its parent, and 
> its parent would do the same, until the error has bubbled up to the root 
> component.
>
>
> Option 2 is simple and robust, and can be used to pass messages of any 
> type, for any situation... but I'm wondering if I'm missing an obvious 3rd 
> solution?
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elm-discuss...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Bubbling Http Errors from Nested Components

2016-07-06 Thread Erik Lott
Yeah, the cookie is acting like a global var, which makes me cringe as much 
as you...


On Wednesday, July 6, 2016 at 2:50:40 PM UTC-4, Josh Adams wrote:
>
> What we need is a simple way to communicate these events from the API 
>> module to the root of the application. What if we use an external resource 
>> like a cookie or local storage to communicate these events? For example, 
>> when the module detects a successful login, it could also set a cookie with 
>> value  isLoggedIn = true. If the Api module detects a 401 response, the 
>> cookie is changed isLoggedIn = false
>>
>> Meanwhile, the application root also has access to this isLoggedIn cookie 
>> value, and it could precede every "update" with an authentication check - 
>> adding or removing any session data that is stored on the model.
>>
>
> I think this is a good indication of my handwavy concern.  I don't think 
> this is an event as much as it is data - "I'm logged in as this user".  And 
> passing data inside your elm application by way of cookies is horribly 
> reminiscent of using the dom as a database - i.e. that's not what it's for, 
> if you're using it that way then it indicates a design problem.  The 
> DOM-as-a-database problem haunted us for 15+ years, and still does for the 
> unenlightened.
>
> Why is it that you need to reach for cookies here?  Cookies are for remote 
> state.  This is local state. 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Authentication & Session Management

2016-07-06 Thread Erik Lott
Yup, I understand passing down config (context) data down through the 
update methods so they can be used in http requests.

What's not clear to me is how you are using this technique in terms of 
authentication. BTW: I'm generally a systems & server dev, so I'm likely 
bringing that baggage with me.

Here are some things that are not clear to me:

   1. Digging through elm app source code, I often see a "Maybe 
   currentUser" field stored directly on the root model, and I that's fine. 
   Let's say I also have a nested LoginComponent for my UI, and this component 
   does not have access to that root model (this is sort of obvious). When a 
   user uses this component to successfully authenticate themselves (the 
   LoginComponent makes the http request with the server), how am I then 
   communicating a successful login back up to the root model? Should the 
   LoginComponent directly return some data from it's update method - like 
   this 
   
<https://www.brianthicks.com/post/2016/06/23/candy-and-allowances-parent-child-communication-in-elm/>
   ?
   2. If a nested component receives an 401 response back from the API, how 
   should I then propagate that response back up to the root so that the 
   current user can be logged out (currentUser = Nothing)?
   
Am I thinking about this in the wrong way?



On Wednesday, July 6, 2016 at 3:12:54 PM UTC-4, Scott Corgan wrote:
>
> Here's an article that elaborates a bit more: 
> https://www.brianthicks.com/post/2016/07/05/duplicate-message-or-update-contexts-in-elm-components/
> .
>
> Then, in each parent's update function, you are calling the child's update 
> function. But, instead of just calling "ChildComponent.update msg model", 
> you'll call "ChildComponent.update context msg model"
>
> Does that help?
>
>
> On Wed, Jul 6, 2016 at 2:57 PM Erik Lott <mreri...@gmail.com > 
> wrote:
>
>> Can you explain how this works?
>>
>>
>>
>>
>> On Wednesday, July 6, 2016 at 2:37:57 PM UTC-4, Scott Corgan wrote:
>>>
>>> It seems like the easiest approach at this point is a combination of 
>>> binding a context type as the first argument to your update functions and 
>>> sending the Navigation.newUrl command from the updateUrl function (used by 
>>> Navigation).
>>>
>>> urlUpdate : Context -> Navigation.Location ->  ( Model, Cmd a )
>>>
>>> and the rest of the update functions:
>>>
>>> update : Context -> a -> Model -> ( Model, Cmd a )
>>>
>>> On Wednesday, July 6, 2016 at 2:05:25 PM UTC-4, Erik Lott wrote:
>>>>
>>>> *Is there an idiomatic/proven way to approach Authentication in an Elm 
>>>> single page app?* Sadly, there are very few resources online that 
>>>> touch on authentication, yet it's an unavoidable part of SPA development. 
>>>> It would be great if this discussion could serve as the best answer to 
>>>> this 
>>>> question.
>>>>
>>>> In our case, I am evaluating Elm for a Single Page Application. We have 
>>>> a simple json api, as follows:
>>>>
>>>> The API:
>>>>
>>>>
>>>>- POST /sessions  - post a username/password. If the credentials 
>>>>are authentic, it returns 200 OK along with a secure http-only cookie.
>>>>- GET /me - returns 200 OK with user record or 401 Unauthorized
>>>>
>>>>
>>>> Our Elm requirements:
>>>>
>>>>- When the client app loads, it makes a request to /me to see if 
>>>>the user is currently logged in. If 200 OK, store the current user in 
>>>> elm 
>>>>and display to the Dashboard page. If not, display the login page.
>>>>- On a successful login, make a request to /me to retrieve the 
>>>>current user record, store the current user in elm, and display the 
>>>>Dashboard page.
>>>>- If an API response ever returns 401 Unauthorized, remove the 
>>>>current user record on the elm model, and display the login page
>>>>
>>>>
>>>> I'm sure that any guidance from community would be appreciated by all!
>>>>
>>>>
>>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Authentication & Session Management

2016-07-06 Thread Erik Lott
Can you explain how this works?




On Wednesday, July 6, 2016 at 2:37:57 PM UTC-4, Scott Corgan wrote:
>
> It seems like the easiest approach at this point is a combination of 
> binding a context type as the first argument to your update functions and 
> sending the Navigation.newUrl command from the updateUrl function (used by 
> Navigation).
>
> urlUpdate : Context -> Navigation.Location ->  ( Model, Cmd a )
>
> and the rest of the update functions:
>
> update : Context -> a -> Model -> ( Model, Cmd a )
>
> On Wednesday, July 6, 2016 at 2:05:25 PM UTC-4, Erik Lott wrote:
>>
>> *Is there an idiomatic/proven way to approach Authentication in an Elm 
>> single page app?* Sadly, there are very few resources online that touch 
>> on authentication, yet it's an unavoidable part of SPA development. It 
>> would be great if this discussion could serve as the best answer to this 
>> question.
>>
>> In our case, I am evaluating Elm for a Single Page Application. We have a 
>> simple json api, as follows:
>>
>> The API:
>>
>>
>>- POST /sessions  - post a username/password. If the credentials are 
>>authentic, it returns 200 OK along with a secure http-only cookie.
>>- GET /me - returns 200 OK with user record or 401 Unauthorized
>>
>>
>> Our Elm requirements:
>>
>>- When the client app loads, it makes a request to /me to see if the 
>>user is currently logged in. If 200 OK, store the current user in elm and 
>>display to the Dashboard page. If not, display the login page.
>>- On a successful login, make a request to /me to retrieve the 
>>current user record, store the current user in elm, and display the 
>>Dashboard page.
>>- If an API response ever returns 401 Unauthorized, remove the 
>>current user record on the elm model, and display the login page
>>
>>
>> I'm sure that any guidance from community would be appreciated by all!
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Re: Bubbling Http Errors from Nested Components

2016-07-06 Thread Erik Lott
I had an idea during lunch that might work.

To recap, our Json API works like this:


   - POST /sessions  - post a username/password. If the credentials are 
   authentic, it returns 200 OK along with a secure http-only cookie.
   - GET /me - returns 200 OK with user record or 401 Unauthorized
   -  lots of other secure endpoints that require authentication


We also have an API module in elm that encapsulates all interaction with 
our server side api. This module can be imported into any nested component. 
There are 2 events that occur in this module that we wish we were notified 
about (globally).

   1. 200 OK response from POST "/sessions". This means the server accepted 
   our user/pass credentials and has set a cookie in the browser. We are now 
   logged in.
   2. A 401 Unauthorized response from any api endpoint - If we receive 
   this response, the server says we are not logged in

What we need is a simple way to communicate these events from the API 
module to the root of the application. What if we use an external resource 
like a cookie or local storage to communicate these events? For example, 
when the module detects a successful login, it could also set a cookie with 
value  isLoggedIn = true. If the Api module detects a 401 response, the 
cookie is changed isLoggedIn = false

Meanwhile, the application root also has access to this isLoggedIn cookie 
value, and it could precede every "update" with an authentication check - 
adding or removing any session data that is stored on the model.

I'm going to see if this might work.







On Wednesday, July 6, 2016 at 12:15:25 PM UTC-4, Maxwell Gurewitz wrote:
>
> Josh, I'm running into a similar problem.  I want to trigger a global 
> error handler whenever any of my components error, (a 401 from session 
> expiration for example), but I want to be able to spread out my api 
> throughout my components.
>
> On Tuesday, July 5, 2016 at 7:53:29 AM UTC-7, Josh Adams wrote:
>>
>> I would handle this entirely differently, personally.  I'm inclined to 
>> have an API TEA component as a child at the Root, and send up messages 
>> requesting API calls to it.  I would never spread my API requests out 
>> through components.
>>
>> That's just me though - I know other people handle this way differently. 
>>  Would love to hear any suggestions from more experienced folks re: this :)
>>
>> -Josh
>> http://www.dailydrip.com/topics/elm
>>
>> On Tuesday, July 5, 2016 at 7:46:16 AM UTC-5, Erik Lott wrote:
>>>
>>> My app has several layers of nested components. Various components 
>>> throughout the tree will need to interact with our API via http requests. 
>>> If any API request returns a 401 - Not Authorized error, or a Timeout 
>>> Error, the error needs to bubble up to the root component where is can be 
>>> handled appropriately.
>>>
>>> What is the most idiomatic way of dealing with this? 
>>>
>>> *1. Parent should pattern match against important child messages*: 
>>> Reference 
>>> <https://groups.google.com/d/msg/elm-discuss/QPqrJd4C78Y/_TLLg81SAQAJ>
>>> This could work, but would be unreasonable in this case. The root 
>>> component would need to match against every failing api http request made 
>>> by every child, grandchild, great-grandchild, etc, component in the tree. 
>>> If a single pattern is missed, the app would be in an error state, so this 
>>> is prone to mistakes.
>>>
>>> *2. Nested Components return additional info from the "update" function*: 
>>> Reference 
>>> <http://stackoverflow.com/questions/37328203/elm-0-17-how-to-subscribe-to-sibling-nested-component-changes>
>>> Each component returns an additional value from its update function like 
>>> this:
>>> update : Msg -> Model -> (Model, Cmd Msg, SomeInfo)
>>>
>>> The parent component could inspect the returned "SomeInfo" value from 
>>> its direct children, and act on that information if necessary.  In my case, 
>>> any nested component that makes http requests to our API would be 
>>> responsible for returning a APINotAuthorized and APITimeout value to its 
>>> parent, and its parent would do the same, until the error has bubbled up to 
>>> the root component.
>>>
>>>
>>> Option 2 is simple and robust, and can be used to pass messages of any 
>>> type, for any situation... but I'm wondering if I'm missing an obvious 3rd 
>>> solution?
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Authentication & Session Management

2016-07-06 Thread Erik Lott
*Is there an idiomatic/proven way to approach Authentication in an Elm 
single page app?* Sadly, there are very few resources online that touch on 
authentication, yet it's an unavoidable part of SPA development. It would 
be great if this discussion could serve as the best answer to this question.

In our case, I am evaluating Elm for a Single Page Application. We have a 
simple json api, as follows:

The API:


   - POST /sessions  - post a username/password. If the credentials are 
   authentic, it returns 200 OK along with a secure http-only cookie.
   - GET /me - returns 200 OK with user record or 401 Unauthorized


Our Elm requirements:

   - When the client app loads, it makes a request to /me to see if the 
   user is currently logged in. If 200 OK, store the current user in elm and 
   display to the Dashboard page. If not, display the login page.
   - On a successful login, make a request to /me to retrieve the current 
   user record, store the current user in elm, and display the Dashboard 
   page.
   - If an API response ever returns 401 Unauthorized, remove the current 
   user record on the elm model, and display the login page


I'm sure that any guidance from community would be appreciated by all!


-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Bubbling Http Errors from Nested Components

2016-07-06 Thread Erik Lott
Josh,

The code snippet you wrote is just the standard architecture. This is what 
I would expect.. 

But, if I'm understanding your previous messages correctly, it sounds like 
you're suggesting that nested components should "message" (such as with 
OutMsg in the brian hicks article you recommended 
)
 
to their direct parent when requesting data. If that's correct, I think 
you're going to run into some problems. 

I'm assuming your child component might message something like this:

module Child exposing(..)

-- model... 

type Msg
  = ResourceRequested
  | ResourceLoading
  | ResourceFailed
  
type OutMsg
  = *GiveMeResourceById String*
  
update : Msg -> Model -> ( Model, Cmd Msg, Maybe OutMsg )
update msg model =
case msg of
ResourceRequested ->
( model, Cmd.none, Just *GiveMeResourceById "2353253"* )

Great, *GiveMeResourceById* has been passed upwards to the parent. We know 
the Parent will need to pass a Parent.OutMsg upwards to the grandparent, 
but unfortunately, we can't simply wrap the Child.OutMsg in a Parent.OutMsg 
as we normally would since we'd lose all context of the child's request - 
The Grandparent would receive a generic Parent.OutMsg and wonder "what do I 
do with this?".


module Parent exposing (..)

import Child

type OutMsg
  = *ChildOutMsg Child.OutMsg*  -- wait! this won't work

update : Msg -> Model -> ( Model, Cmd Msg, Maybe OutMsg )


Instead, rather than wrapping the child's OutMsg, the parent would likely 
return a brand new local OutMsg that communicates the child's original 
intent, and value:

module Parent exposing (..)

import Child

type Msg
  = ChildMsg Child.Msg

type OutMsg
  = GiveChildResourceById String

update : Msg -> Model -> ( Model, Cmd Msg, Maybe OutMsg )
update msg model =
case msg of
ChildMsg submsg ->
  let
(childModel, childCmd, childOutMsg) = 
Child.update submsg model.childModel
  in
( { model | childModel = childModel }, Cmd.map ChildMsg 
loginCmd, convertChildOutMsg childOutMsg )

convertChildOutMsg : Maybe Child.OutMsg -> Maybe Parent.OutMsg
convertChildOutMsg msg = 
  case msg of 
Just Child.GiveMeResourceById id -> 
  Just GiveChildResourceById id
Nothing -> 
   Nothing


This process will be repeated between child and parent until we reach the 
root. Great... so the root has now processed the request and is ready to 
return data. How does it do that? The original suggestion of passing values 
down using the TEA no longer works, since the OutMsgs were not wrapped on 
the way up... there is nothing to unwrap on the way down. 


case msg of
...
  Apple msg ->
{ model | apple = Apple.update(msg) } -- handwavy, you want to catch 
`Cmd` as well
  Api msg ->
{ model | api = Api.update(msg) } -- ditto, deal with Cmd like in 
Keyboard.extra


The components msgs must be generated and converted from parent context to 
child context each downward step. If you expand this to multiple child 
components each making multiple api requests, you're going to quickly have 
OutMsg explosion - Each child's OutMsg involved in api request will be 
duplicated in its parent, and its parent.. all the way up to the root.

Here is a hicks article that also briefly touches on this point..
https://www.brianthicks.com/post/2016/07/05/duplicate-message-or-update-contexts-in-elm-components/

Anyways, this is getting somewhat away from the issue that I'm having with 
Authentication. I think I'll open a new thread with a more direct question.

Thanks again for the suggestions Josh.


On Tuesday, July 5, 2016 at 8:46:13 PM UTC-4, Josh Adams wrote:
>
> If it then needs to proxy requests through its direct parent - the 
>> AdminComponent - the AdminComponent will contain message like:
>>
>> type Msg
>>= LoadAppleComponentApples
>>| AppleComponentApplesLoading
>>| AppleComponentApplesFailure Error
>>| AppleComponentApplesSuccess Data
>>... etc etc for each Component type
>>
>> Is this still on par with what you're suggesting?
>>
>
> Aha, no.  See the README for Keyboard.Extra - 
> http://package.elm-lang.org/packages/ohanhi/keyboard-extra/1.0.1
>
> A typical TEA would see something like a single tag for a given component 
> in the parent, and routing messages through to it.  So in general I would 
> expect to see something like:
>
> case msg of
> ...
>   Apple msg ->
> { model | apple = Apple.update(msg) } -- handwavy, you want to catch 
> `Cmd` as well
>   Api msg ->
> { model | api = Api.update(msg) } -- ditto, deal with Cmd like in 
> Keyboard.extra
>
> Then I could see the API supporting `LoadApples` or some such, and getting 
> that message up to the Root by saying `AskForApples`.  The root would proxy 
> to the API, and it would use the messages it knows about re: telling 
> AppleComponent about new data - presumably it got its data 

Re: [elm-discuss] Re: Bubbling Http Errors from Nested Components

2016-07-05 Thread Erik Lott
Josh, let's say I have components nested 3 levels deep: MainComponent, 
which contains AdminComponent, which contains 3 components 
[ApplesComponent, OrangesComponent, and BananasComponent]

Each of the 3 child-most components need to load their respective resource 
(apples, oranges, and bananas), and visualize the current loading state 
(not requested, loading, failed, success)

The AppleComponent might have the following msg's:

type Msg
   = LoadApples
   | ApplesLoading
   | ApplesFailure Error
   | ApplesSuccess Data


If it then needs to proxy requests through its direct parent - the 
AdminComponent - the AdminComponent will contain message like:

type Msg
   = LoadAppleComponentApples
   | AppleComponentApplesLoading
   | AppleComponentApplesFailure Error
   | AppleComponentApplesSuccess Data
   ... etc etc for each Component type

Is this still on par with what you're suggesting?


On Tuesday, July 5, 2016 at 6:13:28 PM UTC-4, Josh Adams wrote:
>
> I want to understand what you're saying because it seems I'm missing 
>> something. Let's say we're 3 nested components deep. The deepest child 
>> wants to load a resource. Rather than creating a http Cmd directly, the 
>> child should return a message to its parent asking for the resource. That 
>> parent would then also repeat this process and ask it's parent for the 
>> resource. Eventually the message arrives at the root component, and the 
>> root component can generate the Cmd necessary to fetch the resource - 
>> whether that is from an http request, or a mock service. Is this what 
>> you're suggesting?
>>
>
> That is, essentially, what I'm suggesting, though others here might 
> proffer up different ways to get at the same thing.  In general, though, I 
> like thinking of children as just spewing out Msg and having the results of 
> those flow back into them from the top.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Bubbling Http Errors from Nested Components

2016-07-05 Thread Erik Lott
Josh,

I took a moment and read those articles. They're both a great, but they're 
only discussing communication between direct parent and child components. 
This type of interaction is fairly easy to model. 

I want to understand what you're saying because it seems I'm missing 
something. Let's say we're 3 nested components deep. The deepest child 
wants to load a resource. Rather than creating a http Cmd directly, the 
child should return a message to its parent asking for the resource. That 
parent would then also repeat this process and ask it's parent for the 
resource. Eventually the message arrives at the root component, and the 
root component can generate the Cmd necessary to fetch the resource - 
whether that is from an http request, or a mock service. Is this what 
you're suggesting?




On Tuesday, July 5, 2016 at 5:01:19 PM UTC-4, Josh Adams wrote:
>
> Can you give me an example of this in Elm? I'm curious of how you are 
>> "signifying" to the parent component. 
>>
>
> I can't easily, but in general brian hicks' recent articles on 
> parent<->child communications should give you an idea of how you might do 
> it.
>  
>
>> I agree, and this is what the current Api module does - it encapsulates 
>> all communicating with the api, structuring and serializing/deserializing 
>> json requests, etc. For example, to get some data from the api, you might 
>> make a request using the API module like this:
>>
>> Api.getHeroByName "bruce wayne" 
>>
>> The issue is not necessarily communicating with the api itself, but 
>> managing a potential 401 or 408 error (timeout). The Api module is 
>> available globally to all nested components, but those particular errors 
>> need to be managed at the root of the app... and this is the crux of the 
>> problem. 
>>
>
> So for me, I think you haven't found the end of your edge cases going down 
> this path.  Among other things, I can imagine you might want to swap out 
> the API for a mock.  If you just have your components tell the parent "I 
> wish this thing happened!" then that's not a problem - change some code in 
> the parent, swap out the mock, it suddenly handles those requests.  If 
> instead they all call to the Api module, then you're going to have a bad 
> time.
>
> I also think it's reasonable that you might want your app at the top level 
> to be able to signify to the user "I'm talking to a remote service" and if 
> that's not at the top then you'll still have to have the children 
> ultimately tell the parent about that, in which case they might as well 
> have just asked someone else up top to do the work in the first place.
>
> So my thoughts would be that your child might return (Model, Cmd Msg, 
> DoThisThing GetHeroByName "bruce wayne") and then it would just handle the 
> updated data it got later on.  It *probably* shouldn't even care, on its 
> own, whether or not this succeeded.
>
> There's clearly a lot more that would need 'fixing' in that (i.e. the 
> children should probably be able to tell the API what message they want 
> sent out after a success, a la your typical Http requests), but in general 
> this feels good to me.  YMMV.
>
> Joshie 
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Bubbling Http Errors from Nested Components

2016-07-05 Thread Erik Lott
Mark, that reminds me of a similar solution I saw here:
https://gist.github.com/pdamoc/a47090e69b75433efa60fe4f70e6a06a

Rather than returning a Cmd from the update function, a custom Req type is 
being returned instead. The Req naturally returns to the root component, 
gets mapped to the local Msg type, and then transformed into a Cmd.

I'm not exactly sure what that buys us, but it is... interesting.




On Tuesday, July 5, 2016 at 1:30:51 PM UTC-4, Mark Hamburg wrote:
>
> The first option feels repugnant from an encapsulation standpoint. I've 
> built the second option and it works but it increases the amount of 
> boilerplate in hierarchical systems because we now have three results to 
> deal with in update functions. That's lead me to think about but not yet 
> write a command alternative that could also handle tasks that didn't need 
> to be routed back to the originator and that could be used to send messages 
> to the top-level (or elsewhere). That said, once one gets into replacing 
> Cmd, the API request model makes a lot of sense.
>
> Mark
>
> On Jul 5, 2016, at 5:46 AM, Erik Lott <mreri...@gmail.com > 
> wrote:
>
> My app has several layers of nested components. Various components 
> throughout the tree will need to interact with our API via http requests. 
> If any API request returns a 401 - Not Authorized error, or a Timeout 
> Error, the error needs to bubble up to the root component where is can be 
> handled appropriately.
>
> What is the most idiomatic way of dealing with this? 
>
> *1. Parent should pattern match against important child messages*: 
> Reference 
> <https://groups.google.com/d/msg/elm-discuss/QPqrJd4C78Y/_TLLg81SAQAJ>
> This could work, but would be unreasonable in this case. The root 
> component would need to match against every failing api http request made 
> by every child, grandchild, great-grandchild, etc, component in the tree. 
> If a single pattern is missed, the app would be in an error state, so this 
> is prone to mistakes.
>
> *2. Nested Components return additional info from the "update" function*: 
> Reference 
> <http://stackoverflow.com/questions/37328203/elm-0-17-how-to-subscribe-to-sibling-nested-component-changes>
> Each component returns an additional value from its update function like 
> this:
> update : Msg -> Model -> (Model, Cmd Msg, SomeInfo)
>
> The parent component could inspect the returned "SomeInfo" value from its 
> direct children, and act on that information if necessary.  In my case, any 
> nested component that makes http requests to our API would be responsible 
> for returning a APINotAuthorized and APITimeout value to its parent, and 
> its parent would do the same, until the error has bubbled up to the root 
> component.
>
>
> Option 2 is simple and robust, and can be used to pass messages of any 
> type, for any situation... but I'm wondering if I'm missing an obvious 3rd 
> solution?
>
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to elm-discuss...@googlegroups.com .
> For more options, visit https://groups.google.com/d/optout.
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Bubbling Http Errors from Nested Components

2016-07-05 Thread Erik Lott

Thanks for getting back Josh. But I'm still wondering a few things:

Anywhere I was currently wishing to call the API from the child, I would 
> instead signify to the root that I would like to take an equivalent action 
> and be notified of the outcome. 


Can you give me an example of this in Elm? I'm curious of how you are 
"signifying" to the parent component. 

I don't think a component should really give a crap what the backend 
> happens to do.  It should care about the data it is responsible for.  It 
> should tell someone else to do stuff with it.  The item with the single 
> responsibility of shuffling data to/from the backend can take care of it 
> and tell this component how that worked out.  Seems good to me 
> architecturally, but then I haven't actually *built* the thing I'm 
> describing yet either :)


I agree, and this is what the current Api module does - it encapsulates all 
communicating with the api, structuring and serializing/deserializing json 
requests, etc. For example, to get some data from the api, you might make a 
request using the API module like this:

Api.getHeroByName "bruce wayne" 

The issue is not necessarily communicating with the api itself, but 
managing a potential 401 or 408 error (timeout). The Api module is 
available globally to all nested components, but those particular errors 
need to be managed at the root of the app... and this is the crux of the 
problem. 




On Tuesday, July 5, 2016 at 4:09:08 PM UTC-4, Josh Adams wrote:
>
>
>>- How would you choose to send up messages to the root?
>>
>> Anywhere I was currently wishing to call the API from the child, I would 
> instead signify to the root that I would like to take an equivalent action 
> and be notified of the outcome. 
>
>>
>>- What is the benefit of wrapping the API calls in a component?
>>
>> I don't think a component should really give a crap what the backend 
> happens to do.  It should care about the data it is responsible for.  It 
> should tell someone else to do stuff with it.  The item with the single 
> responsibility of shuffling data to/from the backend can take care of it 
> and tell this component how that worked out.  Seems good to me 
> architecturally, but then I haven't actually *built* the thing I'm 
> describing yet either :)
>  
>
>> I hope I'm not giving the impression that the API calls are randomly 
>> spread throughout nested components willy-nilly. All api requests and 
>> models are tightly encapsulates in an API module. If a component wishes to 
>> make an api request, it must import the module.
>>
>
> My general assumption (which seems to hold true pretty well!) is that by 
> the time someone's posting on elm-discuss, they're already pretty good at 
> making good decisions, so I did not get that impression at all!  I just 
> think it's sad that a component has to think about the API and/or interact 
> with it.  Instead, it should just say "gosh it would be swell if someone 
> handled fetching or storing this data for me" and "oh look!  New data to 
> care about!"  That's my feeling at least.
>
> I like this idea of creating a "Service TEA component" - the thought 
>> hadn't crossed my mind. The component could have a model which manages the 
>> "CurrentUser" state of the application in a central location. Is this what 
>> you were alluding to? 
>>
>
> Yeah.  I've seen a lot of people refer to passing things like that all 
> through their application, and in general my feeling has been that it was 
> probably not a good thing that they needed to.  Still not as bad as some 
> early Rails 'solutions' to the "current_user" problem (I'm looking at you, 
> class attributesgeezus)
> -- 
> Josh Adams
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[elm-discuss] Bubbling Http Errors from Nested Components

2016-07-05 Thread Erik Lott
My app has several layers of nested components. Various components 
throughout the tree will need to interact with our API via http requests. 
If any API request returns a 401 - Not Authorized error, or a Timeout 
Error, the error needs to bubble up to the root component where is can be 
handled appropriately.

What is the most idiomatic way of dealing with this? 

*1. Parent should pattern match against important child messages*: Reference 

This could work, but would be unreasonable in this case. The root component 
would need to match against every failing api http request made by every 
child, grandchild, great-grandchild, etc, component in the tree. If a 
single pattern is missed, the app would be in an error state, so this is 
prone to mistakes.

*2. Nested Components return additional info from the "update" function*: 
Reference 

Each component returns an additional value from its update function like 
this:
update : Msg -> Model -> (Model, Cmd Msg, SomeInfo)

The parent component could inspect the returned "SomeInfo" value from its 
direct children, and act on that information if necessary.  In my case, any 
nested component that makes http requests to our API would be responsible 
for returning a APINotAuthorized and APITimeout value to its parent, and 
its parent would do the same, until the error has bubbled up to the root 
component.


Option 2 is simple and robust, and can be used to pass messages of any 
type, for any situation... but I'm wondering if I'm missing an obvious 3rd 
solution?

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.