I did precisely the same style in https://github.com/OvermindDL1/elm-jsphoenix too, to minimize the duplication of work (which also increased by elm removing the ability to extend record types into a new type, and lacking the ability to move Dict's across, so those two things still add some, but it still saved a ton of work but (ab)using ports for the end-user).
On Thursday, November 3, 2016 at 10:43:01 AM UTC-6, Kasey Speakman wrote: > > I first started using Elm's recommended codec-ing scheme. I found that if > I needed to round-trip an entity to an API, I needed *4 representations* > of the same entity. One on the client and one on server is given. But then > 1 encoder representation and 1 decoder representation... both of which > spell out the same information in the type alias. So in order to change the > entity, I have 4 places that need maintenance. *No thanks.* > > Abusing ports, I arrived at a similar solution to what I explained > previously in this thread for decoding. But since encoding is also monkey > work, I wanted to abuse ports to launder that too. However, the process to > do that was herky-jerky. A port/sub round trip for encoding, then an Elm > HTTP call, then a port/sub round trip for decoding. Instead, I abandoned > the Elm HTTP library altogether. I added in a fetch polyfill (whatwg-fetch > <https://github.com/github/fetch>) and run the HTTP call in JS. > > Here is a gist. > <https://gist.github.com/kspeakman/3653ae489c62c4d60c9ba9a9c19fd30b> > > *Notes* > > The JS fetch code could be generalized/improved even more, but this is all > I need for calling my own APIs. Once tweaked and running for its intended > use, it will rarely need to be touched. > > Outgoing ports start with 'api' so that the startup code knows to wire > them up. If Elm would let me, I would define only one outgoing port as `*port > apiRequest : Request a -> Cmd msg*`, but that doesn't compile. > > Overhead per API method is around 5 lines of code. One outgoing port, 2 > incoming ports (1 success, 1 fail), and 2 for adding incoming ports to > subscriptions list. > > Most importantly, if my messages change, I only have 2 places to update > them: client model and server model. No encoder/decoder maintenance. > > Using strings to represent incoming ports is not ideal, but shouldn't need > that much maintenance and are private. > > Just starting to explore this, so maybe there is some blocking situation I > haven't discovered yet. > > On Tuesday, October 4, 2016 at 10:37:41 AM UTC-5, Vojtěch Král wrote: >> >> Awesome! I'll try it out... >> Thanks! >> Vojtech >> >> Dne úterý 4. října 2016 16:36:37 UTC+2 Kasey Speakman napsal(a): >>> >>> I haven't done this yet as we're developing the UI first as things take >>> shape and faking the API calls with Process.sleep + Task.perform. So below >>> is just a sketch. >>> >>> Conceptually, you could use `Http.getString` (or construct a request and >>> use `Http.send`) in Elm to get the JSON, then send that through a port to >>> JavaScript. You'd need at least one outgoing port, and an incoming port for >>> every result type. >>> >>> port deserializeJson : String -> String -> Cmd msg >>> >>> >>> port studentsLoaded : (List Student -> msg) -> Sub msg >>> >>> port coursesLoaded : (List Course -> msg) -> Sub msg >>> >>> >>> subscriptions : Model -> Sub Msg subscriptions model = Sub.batch [ >>> studentLoaded StudentsLoaded , courseLoaded CoursesLoaded ] >>> >>> >>> On the outgoing port, you could pass both the JSON and the incoming port >>> name as a string. Then in the JS, you could wire it once like this: >>> >>> app.ports.deserializeJson.subscribe(function(port, json) { >>> // TODO can throw, so catch error and send to an error port >>> var object = JSON.parse(json); >>> app.ports[port].send(object); >>> }); >>> >>> >>> Once you get the HTTP response string from a particular request, you >>> send it through the outgoing port with the correct return path. >>> >>> deserializeJson "studentLoaded" json >>> >>> It looks like after initial setup, each deserialization would take ~3 >>> lines of wiring code. So it might not be worth it for small objects. But >>> again this is just a sketch that I haven't tried to run. >>> >>> On Tuesday, October 4, 2016 at 6:40:08 AM UTC-5, Vojtěch Král wrote: >>>> >>>> I have the same problem. Would someone be so kind as to give an example >>>> of how to launder the JSON via ports like this? Do you just rut the data >>>> through a port, or do you do ajax in JS? >>>> 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
