raich
raich

Reputation: 127

Erlang list of tuples jsx:encode error

I want to create a List of tuples in json format with jsx:encode, which is returning error:

    io:format("Mylist After reverse ==========: ~n~p~n",[Mylist]),

    FinalReading = lists:map(
                fun(X) ->
                    jsx:encode([X])
                end, Mylist),

Mylist is printed as follows:

    [{{<<"name">>,<<"Batman">>},{<<"steps">>,1033},{<<"distance">>,830}},
     {{<<"name">>,<<"Superman">>},{<<"steps">>,641},{<<"distance">>,520}}]

I'm getting this error:

    09:49:24.048 [error] ** Boss Service Handler myproj_priv_mylib_websocket terminating in handle_incoming/4
    for the reason error:badarg
    ServiceUrl: "/websocket/mylib"
    WebSocketId: <0.336.0>
    SessionId  : <<"a4f60118091309990af7c89c9a1acb49ee3bb08d">>
    Message    : <<"[email protected]:z3CMLU9jDTYdiAacNiJrMIkdp4lTf6sb">>
    State    : []
    ** Stacktrace: [{jsx_parser,value,4,[{file,"src/jsx_parser.erl"},{line,125}]},{lists,map,2,[{file,"lists.erl"},{line,1237}]},{myproj_priv_mylib_websocket,handle_incoming,5,[{file,"..."},{line,130}]},{boss_service_worker,handle_cast,2,[{file,"src/boss/boss_service_worker.erl"},{line,173}]},{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,599}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]

It would be great if someone points out the correct code. Thanking all in advance.

Upvotes: 2

Views: 1199

Answers (2)

Riccardo Manfrin
Riccardo Manfrin

Reputation: 741

I'm very much a newbie to Erlang, so not sure if I've the right to judge, but my feeling is that it would be good to hide the need to convert the tuple to list in jsx:encode.

If

[{a,<<"a">>}, {b,<<"b">>}].

becomes

{
  "a" : "a",
  "b" : "b"
}

I believe the same should work as well for this syntax

{{a,<<"a">>}, {b,<<"b">>}}.

This last syntax brings more information (it reflects an ordering which I can count on, within the code, for pattern matching).

I usually try to convert my JSON into a tuple for which I know the ordering, so that I can play with pattern matching instead of using keyfind and friends. But because the above syntax does not work, I have to wrap jsx:encode(tuple_to_list()) to automatically manage "PropTuples".

Am I completely misunderstanding it? Is there a more decent way to represent/treat/manipulate JSON in Erlang?

Upvotes: 2

Dogbert
Dogbert

Reputation: 222398

You'll have to convert the top level tuples to lists using erlang:tuple_to_list/1 and lists:map/2 so that jsx can correctly encode them to a JSON Array.

1> List = [{{<<"name">>,<<"Batman">>},{<<"steps">>,1033},{<<"distance">>,830}},
1>         {{<<"name">>,<<"Superman">>},{<<"steps">>,641},{<<"distance">>,520}}].
[{{<<"name">>,<<"Batman">>},
  {<<"steps">>,1033},
  {<<"distance">>,830}},
 {{<<"name">>,<<"Superman">>},
  {<<"steps">>,641},
  {<<"distance">>,520}}]
2> List2 = lists:map(fun erlang:tuple_to_list/1, List).
[[{<<"name">>,<<"Batman">>},
  {<<"steps">>,1033},
  {<<"distance">>,830}],
 [{<<"name">>,<<"Superman">>},
  {<<"steps">>,641},
  {<<"distance">>,520}]]
3> io:format("~s~n", [jsx:encode(List2)]).
[{"name":"Batman","steps":1033,"distance":830},{"name":"Superman","steps":641,"distance":520}]

Upvotes: 4

Related Questions