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