Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sparse field param for function based attribute breaks #337

Open
elvanja opened this issue Jan 29, 2021 · 3 comments
Open

Sparse field param for function based attribute breaks #337

elvanja opened this issue Jan 29, 2021 · 3 comments
Labels
1.0.0 1.0.0

Comments

@elvanja
Copy link

elvanja commented Jan 29, 2021

I have a serializer defined like this:

  attributes([
    :name,
    :custom_property
  ])

Where :name exists in the original struct, but :custom_property is calculated in same named function.

If I try to use sparse fields that include the custom property via e.g. fields[record]=custom-property, it breaks when trying to convert from dashed to underscored key value while building the attributes (error details below).

A fix for this is to just apply formatting while doing the conversion. E.g. in JaSerializer.Builder.Utils.safe_atom_list/1:

  def safe_atom_list(field_str) do
    field_str
    |> String.split(",")
    |> Enum.map(&JaSerializer.ParamParser.Utils.format_key/1) # <---- this is the fix
    |> Enum.map(&String.to_existing_atom/1)
  end

After that, it all seems to be working fine. I can turn this into a PR, but I am not sure if this is the right place to fix the issue.

And, here is the stack trace:

* (exit) an exception was raised:
    ** (ArgumentError) argument error
        :erlang.binary_to_existing_atom("custom-property", :utf8)
        (elixir 1.10.3) lib/string.ex:2303: String.to_existing_atom/1
        (elixir 1.10.3) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
        (elixir 1.10.3) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
        (ja_serializer 0.16.0) lib/ja_serializer/builder/attribute.ex:37: JaSerializer.Builder.Attribute.do_filter/2
        (ja_serializer 0.16.0) lib/ja_serializer/builder/attribute.ex:11: JaSerializer.Builder.Attribute.build/1
        (ja_serializer 0.16.0) lib/ja_serializer/builder/resource_object.ex:23: JaSerializer.Builder.ResourceObject.build/1
        (elixir 1.10.3) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
        (ja_serializer 0.16.0) lib/ja_serializer/builder/top_level.ex:34: JaSerializer.Builder.TopLevel.build/1
        (ja_serializer 0.16.0) lib/ja_serializer.ex:62: JaSerializer.format/4
        (phoenix 1.4.17) lib/phoenix/view.ex:410: Phoenix.View.render_to_iodata/3
@elvanja
Copy link
Author

elvanja commented Jan 29, 2021

P.S. If it helps, I also have a workaround. In controller, I apply this transformation to the sparse fields params:

  defp underscore(nil), do: nil

  defp underscore(string) when is_binary(string), do: String.replace(string, "-", "_")

  defp underscore(%{} = map) do
    map
    |> Enum.map(fn {key, value} ->
      {key, underscore(value)}
    end)
    |> Enum.into(%{})
  end

Used like this:

    render(conn, "index.json",
      data: some_data,
      opts: [
        fields: underscore(params["fields"])
      ]
    )

@beerlington
Copy link
Contributor

@elvanja sorry I haven't had a chance to look at this yet. It seems like this should affect any sparse field name that needs to get converted from dashes to underscore. If the regular (non-custom) property name has an underscore, does that break too?

@elvanja
Copy link
Author

elvanja commented Feb 1, 2021

Hi! Sure, no problemo, it is not an emergency 😄
And yes, the non-custom properties also break, on main record or on relations.

@beerlington beerlington added the 1.0.0 1.0.0 label Feb 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.0.0 1.0.0
Projects
None yet
Development

No branches or pull requests

2 participants