Parsing nested JSON

Hi @Maxximiliann! Since you said your were starting out, I decided to show you a couple of things about Elixir! Hopefully this helps you in your journey. :slight_smile:

I created a repo here: https://github.com/pdgonzalez872/maxximiliann that has an acceptance_test file. There, I show a couple of things about your problem, how to use some tools to your advantage (tests, pry) and ultimately help you with your question. For completeness, I added the content of the file below. Please read the code and hopefully this helps you in your journey.

PD

defmodule AcceptanceTest do
  use ExUnit.Case

  test "should work" do
    # Since you mentioned you are starting out, here are a couple of things you
    # may not know. If you do, disregard them.
    # You can use `require IEx; IEx.pry` to start a debugging session within a test.
    # You can then run the tests like so: `iex -S mix test`
    # more about Pry here: https://medium.com/@diamondgfx/debugging-phoenix-with-iex-pry-5417256e1d11

    # Uncomment line 20 below to allow pry to run in this test and when the
    # debugger asks you if you want to "Allow" Pry, press "Y" to jump in the
    # session. It is an IEx session, but through tests. Helpful to debug things
    # that you need to go back to later. If you need more than 60 seconds in
    # your debugging session (very common), pass the `trace` flag to the mix
    # command like so: `iex -S mix test --trace` to make the test have a
    # timeout of `infinity`.

    # require IEx; IEx.pry

    # I'm going to use the code you posted to keep things the same. Apples to
    # apples. :)

    res = HTTPoison.get!("https://api.wavesplatform.com/v0/pairs")
    body = Poison.decode!(res.body, keys: :atoms)

    # `body` is a `map` with the following keys:
    # We prove this by having the assertion below pass. If the keys were not
    # the same, this test would fail.
    assert Map.keys(body) == [:__type, :data]

    # we can see that `body.data` is a `list`:
    assert is_list(body.data) == true

    # you can also write the same thing above like this:
    assert is_list(body.data)

    # This is what the first element in your collection looks like:
    first_element = Enum.at(body.data, 0)

    # Using IO.inspect() is a great way to look at the shape your data has:
    msg = "This will print out to the terminal when you run the test, this is what first_element looks like"
    IO.inspect(first_element, label: msg)

    # These are the keys you have in `first_element`
    assert Map.keys(first_element) == [:__type, :amountAsset, :data, :priceAsset]

    # You mentioned you wanted `volumeWaves` for each element. You can see that
    # you don't have that key in that first map.
    # This is what you have inside `data`:
    assert Map.keys(first_element.data) == [:firstPrice, :high, :lastPrice, :low, :quoteVolume, :txsCount, :volume,
     :volumeWaves, :weightedAveragePrice]

    # There is a little hiccup with your data, you are getting floats back from
    # your api call, which is fine, but I suggest using a library when
    # dealing with float values. A great one is this one:
    # https://github.com/ericmj/decimal
    # Here is proof you have a float:
    assert is_float(first_element.data.firstPrice)

    # To answer your original question: When dealing with collections
    # (enumerables), look at the functions in `Enum`:
    # https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/enum.ex
    # Here is `map/2`. The number by the function name is the number of
    # arguments it takes (called arity). `Map` iterates through the enumerable
    # you pass and keeps the result of a function you pass in as a second
    # argument:
    all_volume_waves_prices = Enum.map(body.data, fn element -> element.data.volumeWaves end)
    IO.inspect(all_volume_waves_prices)

    # To answer your question, we can also filter enumerables: `Enum.filter/2`
    # will return the element that returns `true` in the function you pass in
    # as a second argument:
    volume_waves_greater_than_500 = Enum.filter(body.data, fn element -> element.data.volumeWaves > 500.0 end)
    IO.inspect(volume_waves_greater_than_500)

    # Hope this helps. Thanks for asking the question and I hope you keep using Elixir.
  end
end

On a side note, here is a guide to markdown: Basic Syntax | Markdown Guide. It’s nice to be able to format things in these forums, helps you get your point across faster.