diff --git a/lib/live_select.ex b/lib/live_select.ex index 4385fcc..f809838 100644 --- a/lib/live_select.ex +++ b/lib/live_select.ex @@ -543,6 +543,14 @@ defmodule LiveSelect do iex> decode(["{\"name\":\"New York City\",\"pos\":[-74.00597,40.71427]}","{\"name\":\"Stockholm\",\"pos\":[18.06871,59.32938]}"]) [%{"name" => "New York City","pos" => [-74.00597,40.71427]}, %{"name" => "Stockholm","pos" => [18.06871,59.32938]}] + + Non-JSON strings (e.g. raw text from a search input) are returned as-is: + + iex> decode("Glon") + "Glon" + + iex> decode(["Berlin", "Rome"]) + ["Berlin", "Rome"] """ def decode(selection) do json = Phoenix.json_library() @@ -550,8 +558,14 @@ defmodule LiveSelect do case selection do nil -> [] "" -> nil - selection when is_list(selection) -> Enum.map(selection, &json.decode!/1) - selection -> json.decode!(selection) + selection when is_list(selection) -> Enum.map(selection, &safe_decode(json, &1)) + selection -> safe_decode(json, selection) end end + + defp safe_decode(json, value) do + json.decode!(value) + rescue + _ -> value + end end diff --git a/test/live_select/decode_test.exs b/test/live_select/decode_test.exs new file mode 100644 index 0000000..1902ced --- /dev/null +++ b/test/live_select/decode_test.exs @@ -0,0 +1,42 @@ +defmodule LiveSelect.DecodeTest do + @moduledoc false + + use ExUnit.Case, async: true + + describe "decode/1" do + test "decodes nil to empty list" do + assert LiveSelect.decode(nil) == [] + end + + test "decodes empty string to nil" do + assert LiveSelect.decode("") == nil + end + + test "decodes a JSON-encoded map" do + assert LiveSelect.decode(~s({"name":"Berlin","pos":[13.41,52.52]})) == + %{"name" => "Berlin", "pos" => [13.41, 52.52]} + end + + test "decodes a list of JSON-encoded maps" do + assert LiveSelect.decode([ + ~s({"name":"Berlin"}), + ~s({"name":"Rome"}) + ]) == [ + %{"name" => "Berlin"}, + %{"name" => "Rome"} + ] + end + + test "returns plain string as-is when it's not valid JSON" do + assert LiveSelect.decode("Glon") == "Glon" + end + + test "returns string with special characters as-is when not valid JSON" do + assert LiveSelect.decode("São Paulo") == "São Paulo" + end + + test "returns list elements as-is when they are not valid JSON" do + assert LiveSelect.decode(["Berlin", "Rome"]) == ["Berlin", "Rome"] + end + end +end