Create custom case function in phoenix "create"

I’m having a little problem. There is a function, which is the result of a json.

I want to get my Phoenix to show the error on the screen and redirect to a specific place.

If status_code for 201, appears on screen
“Successfully Inserted”

Can you help me?

Below you show what I did …

response =
%HTTPoison.Response{
body: “{“errors”:[{“code”:“CUS-008”,“path”:“customer.ownId”,“description”:”-----------ERROR ---------"}]}",
headers: [
{“Server”, “nginx”},
{“Date”, “Wed, 21 Aug 2019 23:16:00 GMT”},
{“Content-Type”, “application/json”},
{“Content-Length”, “166”},
{“Connection”, “keep-alive”},
{“X-Content-Type-Options”, “nosniff”},
{“Vary”, “Accept-Encoding, Origin”}
],
request: %HTTPoison.Request{
body: “{“taxDocument”:{“type”:“CPF”,“number”:“00000000000”},“shippingAddress”:{“zipCode”:“75000000”,“streetNumber”:“1”,“street”:“Rua 6”,“state”:“Minas”,“district”:“Vila Sales”,“country”:“BRA”,“city”:“Minas Gerais”},“phone”:{“number”:“999999999”,“countryCode”:“55”,“areaCode”:“11”},“ownId”:“24”,“fullname”:“Name test full”,“email”:“test15@test.com.br”,“birthDate”:“1980-12-09”}”,
headers: [
{“Authorization”,
“Basic ghghghtyty5==”},
{“Content-Type”, “application/json”}
],
method: :post,
options: [
hackney: [
basic_auth: {“12345”,
“12345”}
]
],
params: %{},
url: “https://teste.teste.com.br/v2/customers/
},
request_url: “https://teste.teste.com.br/v2/customers/”,
status_code: 400
}

Controller =

    case Floki.find(response.body, "code") do
      [{"code", _, [code]}] ->
        code
      body ->
        raise  """
          status: #{response.status_code}
        """
    end

Floki ist for parsing HTML, your response body does more look like JSON, perhaps you should use a JSOn parser instead?

True, I ended up totally confused.

I’m using Poison.decode to bring the result and print it on screen.

response.body = “{“errors”:[{“code”:“PAY-036”,“path”:“taxDocument.validCpf”,“description”:“O CPF informado deve ter 11 números”}]}”

Poison.decode!(response.body)                          
%{
  "errors" => [
    %{
      "code" => "PAY-036",
      "description" => "O CPF informado deve ter 11 números",
      "path" => "taxDocument.validCpf"
    }
  ]
}

I am trying to get the value of “code”, but I can’t.
I’ve tried several ways, but to no avail.

Poison.decode!(response.body)["code"] = nil
Poison.decode!(response.body)["errors"]["code"] =

** (ArgumentError) the Access calls for keywords expect the key to be an atom, got: “code”

Could you help me with any examples?

Errors is a list, not a map…

Depending on what You want, You might try

errors = Poison.decode!(response.body)["errors"]
Enum.map(errors, &Map.get(&1, "code"))
["PAY-036"]

You might prefer this syntax (not tested…). Anyway I would wrap decode! in a case statement.

response.body
|> Poison.decode!()
|> Map.get("errors") 
|> Enum.map(&Map.get(&1, "code"))

BTW Jason is a newer JSON library.

If You know what You should receive, then pattern matching can be nice too.

%{"errors" => [%{"code" => code}|_tail]} = Poison.decode!(response.body)
2 Likes

It helped me a lot.
Running perfectly now.

Thank you very much.

iex(12)> response
%{
  "errors" => [
    %{
      "code" => "PAY-036",
      "description" => "O CPF informado deve ter 11 números",
      "path" => "taxDocument.validCpf"
    }
  ]
}
iex(13)> defmodule Xyz do
...(13)>   def code(%{"errors" => [%{"code" => code}]} = _response), do: code
...(13)> end
iex(14)> Xyz.code(response)
"PAY-036"
iex(15)>