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.

Reply via email to