Writing your first Elixir package (Part 2)
The real stuff
In Part 1, we set up our project. Now we need to add functionality to it. Head back to IEX, now we’ll use the Tesla
package to send an HTTP request to api.chucknorris.io/jokes/random, (make sure to include “https://” in the URL or Tesla
will surely give you an error)
iex(1)> response = Tesla.get("https://api.chucknorris.io/jokes/random")%Tesla.Env{__client__: nil, __module__: Tesla,
body: "{\"category\":null,\"icon_url\":\"https:\\/\\/assets.chucknorris.host\\/img\\/avatar\\/chuck-norris.png\",\"id\":\"q7PEcA4VRv-su2636vmYMA\",\"url\":\"http:\\/\\/api.chucknorris.io\\/jokes\\/q7PEcA4VRv-su2636vmYMA\",\"value\":\"Chuck Norris will hit you so hard that your blood will bleed\"}",
headers: %{"access-control-allow-credentials" => "true",
"access-control-allow-headers" => "Content-Type, Accept, X-Requested-With",
"access-control-allow-methods" => "GET, HEAD",
"access-control-allow-origin" => "*", "cache-control" => "no-cache",
"cf-ray" => "3ca2c28df8ba706e-SIN", "connection" => "keep-alive",
"content-length" => "263", "content-type" => "application/json",
"date" => "Fri, 08 Dec 2017 21:18:56 GMT", "server" => "cloudflare-nginx",
"set-cookie" => "__cfduid=da4f70308a24c13c2251f0efea5e721881512767935; expires=Sat, 08-Dec-18 21:18:55 GMT; path=/; domain=.chucknorris.io; HttpOnly",
"via" => "1.1 vegur"}, method: :get, opts: [], query: [], status: 200,
url: "https://api.chucknorris.io/jokes/random"}
This weird syntax that it just returned is a Hash Map, that Elixir likes to call a Map
. The API has returned a lot of information that we don’t need, like…AT ALL! The body
part of the map seems like useful stuff, so we’ll take that:
iex(2)> response = response.body
"{\"category\":null,\"icon_url\":\"https:\\/\\/assets.chucknorris.host\\/img\\/avatar\\/chuck-norris.png\",\"id\":\"q7PEcA4VRv-su2636vmYMA\",\"url\":\"http:\\/\\/api.chucknorris.io\\/jokes\\/q7PEcA4VRv-su2636vmYMA\",\"value\":\"Chuck Norris will hit you so hard that your blood will bleed\"}"
Seems like we do have some useful output. This is essentially a JSON string, it can be converted into a JSON object by parsing it. Remember that Poison
package? This is where it makes its entrance.
Lets decode the JSON string to return a JSON object and use pattern matching to assign it to a variable:
iex(3)> {:ok, result} = Poison.decode response
Now if you check for result["value]
:
iex(4)> result["value"]
"Chuck Norris will hit you so hard that your blood will bleed"
Awesome! You finally have your Chuck Norris fact in a string form. Now, all that we have done above, lets put that into our random
function
# norris.exdef random do
response =
"https://api.chucknorris.io/jokes/random"
|> Tesla.get() response = response.body
{:ok, result} = Poison.decode response result["value"]
end
The |>
is the pipe operator that basically takes the output of the previous function and executes the next function with that as its first argument. so basically:
x
|> function1()
|> function2()# is equivalent to
function2(function1(x))
Important note on publishing your packages
Although publishing a package to the hex repository is very easy, don’t publish it until you really solve a problem that you think a lot of people have. The cool thing about Elixir is that you don’t need to have it published on Hex, you can simply provide the Github link to your package repo and the package manager will gracefully oblige. So if you have a silly package like mine, try to refrain from publishing it.
That being said, here’s the awesome guide to prepping your package for publishing and then publishing on Hex.
If you would like to take a look at the other features I’ve provided in the package, head over here. Also check out the Github repo of this package if you think you can improve this package and contribute to it.
Happy Coding!