hi everyone so far so good with graphql and Absinthe. Its getting bit tricky with some data structs
here is the example of schema
object :uploads do
field :links, list_of(:links_types)
end
the links_types looks like
object :links_types do
field :url, :string
field :format, :string
end
so the data structure that is fetched from postgresql looks this
%{id:1, links: %{data: [ %{"url" => "xyz.com", "format" => "format1" }, %{ "url": "abc.com", format => "format2"]}}
i managed to remove data
key from links map , so now links:
is list of maps as we described in graphql schema still i get null result
sample query
id,
links{
url
}
}
result is
id:1,
links: [ {url: null}, {url: null}]
}
I think i am making some mistake here or there is something better way to define schema. thanks in advance
1 Like
Hey there!
Can you elaborate a bit on your data? Normally if you use a jsonb column the keys are strings not atoms. I’m also confused by the single quotes, are you intentionally storing char lists instead of strings?
You’ll likely just need a small inline resolution function on your links field, but in order to suggest one I need to understand the shape of your data better.
1 Like
@benwilson512 thanks for quick reply. I think the problem is my data structure was map with arrow
x = %{"a" => "xyz"}
I thing in the absinthe library we access map as x.a
which gave null
i think. idn i maybe wrong.
i was thinking to convert arrow map into atoms is there better way to solve this. like some config to access with the arrow maps as well? x["a"]
1 Like
finally solved with own helper
```
Enum.map(list, fn(x)->
for {key, val} <- x, into: %{}, do: {String.to_existing_atom(key), val}
end)
```
thanks. still wondering is there better solution 
1 Like
First off, some elixir terminology. All elixir maps are “arrow maps”. %{foo: 1}
is exactly the same as %{:foo => 1}
. If the key is an atom you can write it in the %{foo: 1}
form, but it’s just a visual change.
%{:foo => 1}
is a map with the atom key :foo
.
%{"foo" => 1}
is a map with the string key "foo"
.
What you’re trying to figure out is how to get values out of a map with string keys. The answer does not need to be converting them to atoms.
You haven’t really supplied enough of your code for me to tell you exactly where to put stuff. For example you just said you created a helper, but you didn’t say where you put that code or what values you gave it (what is list
?) so it doesn’t help us. Help us to help you, give us the full context.
The basic way to use string keys is as follows:
query do
field :thing, :thing_with_string_keys do
{:ok, %{"name" => "ben", "age" => 25}}
end
end
object :thing_with_string_keys do
field :name, :string, resolve: key("name")
field :age, :integer, resolve: key("name")
end
def key(key_name) do
fn thing, _, _ ->
{:ok, Map.get(thing, key_name}
end
end
4 Likes
As a final note, please don’t try to split the conversation. It makes it harder to help you.
1 Like
thanks got it and sorry
cheers finally able to work this out. Thanks again
1 Like
Since you are looking for a general idea, here’s how I tackled a similar problem. I like Ben’s solution with the helper.
My data structure is different, and Ben’s solution is better, but it may help to see nonetheless.
I have a jsonb column with permissions, e.g.
{"add":[], "roles": ["employee", "manager"], "exclude":[]}
…
object :permissions do
field :add, list_of(:string) do
resolve(fn(%{"add" => add},_,_) ->
{:ok, add}
end)
end
field :exclude, list_of(:string) do
resolve(fn(%{"exclude" => exclude },_,_) ->
{:ok, exclude}
end)
end
field :roles, list_of(:string) do
resolve(fn(%{"roles" => roles},_,_) ->
{:ok, roles}
end)
end
end
1 Like