How does one send JSON payload with Mojito

I’m attempting to test the ability to post to an external site (in this case, Procore ) using Mojito. As much as I would like to use a variable to represent the expected payload (in this case, a task_item object), I have been using IEx to test the ability to do so before I commit to any actual code. After getting a series of 400-Bad Request responses (which means that I was, at least, hitting the endpoint), I checked out the “Submitting a JSON payload as post request body” section at Hexdocs for Mojito, only to run into the following:

** (FunctionClauseError) no function clause matching in Keyword.get/3    
    The following arguments were given to Keyword.get/3:
        # 1
        "{\"task_item\":{\"title\":\"This is a title\"}}"
        # 2
        # 3
    Attempted function clauses (showing 1 out of 1):
        def get(keywords, key, default) when is_list(keywords) and is_atom(key)
    (elixir) lib/keyword.ex:195: Keyword.get/3
    (mojito) lib/mojito.ex:281: Mojito.request/1

My attempt can be seen here:

...(17)> "",
...(17)> [
...(17)>           {"content-type", "application/x-www-form-urlencoded"},
...(17)>           {"authorization", "Bearer #{procore_config[:access_token]}"}
...(17)>         ],
...(17)> URI.encode_query(%{"project_id" => "[redacted]"}),
...(17)> Jason.encode!(%{"task_item" => %{"title" => "This is a title"}}))

My questions are:

  1. What am I doing wrong here?
  2. How do I not do whatever it is that I’m doing wrong?
  3. Should we achieve the first two, what do I need to do in order to employ a variable in the body space? Ultimately, I will be reading from a CSV and posting multiple of these.

Thank you in advance.

According to docs payload should be the 3rd parameter, not 4th.
I believe this code will work as you expect:

encoded_query = URI.encode_query(%{"project_id" => "[redacted]"})
  "" <> encoded_query,
    {"content-type", "application/x-www-form-urlencoded"},
    {"authorization", "Bearer #{procore_config[:access_token]}"}
  Jason.encode!(%{"task_item" => %{"title" => "This is a title"}})
1 Like

Having run your solution, this is part of what I got in return:

   body: "{\"errors\":\"param is missing or the value is empty: task_item\"}",
   complete: true,

On the bright side, I am, again, reaching the endpoint, which is nice.

Perhaps, you need another header. Try to replace application/x-www-form-urlencoded by application/json

1 Like