How to get access values from boltsips response data in .eex file

Want to access name and email filed in .eex file
How to iterate thorough Bolt.Sips.Response --> results --> properties --> email,name

%Bolt.Sips.Response{ bookmark: "", fields: ["n"], notifications: [], plan: nil, profile: nil, records: [ [ %Bolt.Sips.Types.Node{ id: 0, labels: ["E"], properties: %{ "email" => "abc@email.com", "name" => "Abc Xyz", } } ] ], results: [ %{ "n" => %Bolt.Sips.Types.Node{ id: 0, labels: ["E"], properties: %{ "email" => "abc@email.com", "name" => "Abc Xyz", } } } ], stats: [], type: "r" }

Hello and welcome,

Probably the nicest way is to use

https://hexdocs.pm/elixir/Kernel.html#get_in/2

You need to remember results is a list. and your response mixes atoms and strings keys.

1 Like

you can use @kokolegorille’s example, and you can also use the recommendation from the Bolt.Sips Response docs and examples, pasting some samples below, for brevity:

iex» %Bolt.Sips.Response{results: results} = Bolt.Sips.query!(Bolt.Sips.conn(), "RETURN [10,11,21] AS arr")
iex» results
[%{"arr" => [10, 11, 21]}]

And of course, since Response implements the Enumerable protocol, you can easily use it for manipulating your results. Example:

Bolt.Sips.conn()
|> Bolt.Sips.query!("RETURN [10,11,21] AS arr") 
|> Enum.reduce(0, &(Enum.sum(&1["arr"]) + &2))

# => 42

HTH

__
One of the main reasons the Response has a mix content, atoms and strings, is because we cannot control the response from the server, converting everything to atoms would obviously not be safe.

2 Likes

First of all Thank you for immediate reply.

I have to display “properties” in .eex file, but so far I have not been able to access it even in iex shell.
It seems to be very complex structure of maps and lists.

i have tried using Enum functions but could not get desired output
ex: results[“n”][:properties]

for get_in, the error is “n” is not an atom, I have tried String.to_atom(“n”) but the results are not desirable.

need some help about it.

conn = Bolt.Sips.conn()

%Bolt.Sips.Response{results: results}=Bolt.Sips.query!(conn,“match (n) return n limit 1”)

results
[
%{
“n” => %Bolt.Sips.Types.Node{
id: 0,
labels: [“E”],
properties: %{
“email” => “abc@email.com”,
“name” => “ABC XYZ”,

  }}}

]

get_in(results,[“n”,:properties])
** (ArgumentError) the Access calls for keywords expect the key to be an atom, got: “n”
(elixir 1.10.4) lib/access.ex:311: Access.get/3
(elixir 1.10.4) lib/kernel.ex:2308: Kernel.get_in/2

results is a list… If I had to collect data from it, I would first start with Enum.map. Not tested, but I would do something similar if I had to collect n, email and name.

Enum.map(results, & %{n: &1["n"], email: &1.properties["email"], name: &1.properties["name"]})

thank you so much for the guidance. I checked it on iex shell but giving this error

Enum.map(results, & %{n: &1[“n”], email: &1.properties[“email”], name: &1.properties[“name”]})

** (KeyError) key :properties not found in: %{“n” => %Bolt.Sips.Types.Node{id: 0, labels: [“E”], properties: %{“email” => “abc@email.com”, “name” => “ABC XYZ”}}}
(stdlib 3.8) erl_eval.erl:680: :erl_eval.do_apply/6
(stdlib 3.8) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib 3.8) erl_eval.erl:411: :erl_eval.expr/5
(stdlib 3.8) erl_eval.erl:786: :erl_eval.eval_map_fields/5
(stdlib 3.8) erl_eval.erl:263: :erl_eval.expr/5
(elixir 1.10.4) lib/enum.ex:1396: Enum.“-map/2-lists^map/1-0-”/2

I didn’t get the structure right. it should be…

Enum.map(results, fn m -> 
  %{n: m["n"], email: m["n"].properties["email"], name: m["n"].properties["name"]} 
end)
1 Like

Thank you so much!!

thank you @kokolegorille

1 Like

These are some rules when trying to access data, with mixed keys…

  • If it is a list, use Enum.map to collect elements.
  • If it is a map with string keys, You can get the value with map[“key”]
  • If it is atom keys, You have the sugar… map.key, but if the key is not present, it fails
  • In this case, You can use map[:key], it will not fail
  • Use get_in if You have structs
  • If it is a tuple, use elem/2

and just follow the path of your data :slight_smile:

1 Like