Question

I am following the Miguel Camba tutorial on Elixir lang.

Everything is ok until I try to utilize the following snippet:

get "/play/:story_name" do
    conn = conn.resp_content_type("text/event-stream")
    conn = conn.send_chunked(200)

    iterator = File.iterator!("#{conn.params[:story_name]}.txt")

    Enum.each iterator, fn(line) ->
      { :ok, conn } = conn.chunk "data: #{line}\n"
      await conn, 1000, on_wake_up(&1, &2), on_time_out(&1)
    end
    conn
  end

  defp on_wake_up(arg1, arg2) do
    # Nothing
  end

  defp on_time_out(arg1) do
    # Nothing
  end

I have tried the following:

await conn, 1000, on_wake_up&(&1, &2), on_time_out&(&1)
await conn, 1000, on_wake_up(&(&1, &2)), on_time_out(&(&1))
await conn, 1000, on_wake_up(), on_time_out()
   end
    conn
  end

  defp on_wake_up() do
    # Nothing
  end

  defp on_time_out() do
    # Nothing
  end

I would like to run introspection to see what is the type of object passed in to (arg1, arg2) and (arg1), respectively, and still trying to figure out how to accomplish that..

In the meantime, I cannot tell whether the shortcut ampersand method is useful because I was unable to get it to work in the iex REPL. My question is how do you do troubleshoot in such case via introspection, the docs, or utilizing the shortcut ampersand method. Thanks in advance.

Was it helpful?

Solution

The syntax is outdated. You need to either write: &on_wake_up(&1, &2) or &on_wake_up/2. Those are anonymous functions:

iex> is_function &is_atom/1
true

OTHER TIPS

Here's an update of the Miguel Camba tutorial, must also add the cinderella.txt and red-riding.txt files to root directory:

application_router.ex

defmodule ApplicationRouter do
  use Dynamo.Router

  prepare do
    conn.fetch([:cookies, :params])
  end

  get "/" do
    conn = conn.assign(:title, "Welcome to Concurrent Story Teller!")
    render conn, "index.html"
  end

  get "/:file_name" do
    normalized_title = String.capitalize(String.replace(conn.params[:file_name], "-", " "))
    conn = conn.assign :title, normalized_title
    conn = conn.assign :file_name, conn.params[:file_name]
    render conn, "story.html"
  end

  get "/play/:story_name" do
    conn = conn.resp_content_type("text/event-stream")
    conn = conn.send_chunked(200)

    iterator = File.stream!("#{conn.params[:story_name]}.txt")

    Enum.each iterator, fn(line) ->
      { :ok, conn } = conn.chunk "data: #{line}\n"
      await conn, 1000, &on_wake_up(&1, &2), &on_time_out(&1)
    end
    conn
  end

  defp on_wake_up(arg1, arg2) do
    # Nothing
  end

  defp on_time_out(arg1) do
    # Nothing
  end

end


index.html.eex

<!DOCTYPE HTML>
<html>
<head>
  <title><%= @title %></title>
  <link href="/static/favicon.ico" rel="icon">
  <link href="/static/storyteller.css" media="all" rel="stylesheet" type="text/css">
  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
  <script ="/static/storyteller.js"></script>
</head>
<body>
    <div id="main-container">
        <h1><%=@title%></h1>
        <section class="stories-list">
            <h2>Please, choose a story</h2>
            <article class="story">
                <h3>Red Riding</h3>
                <a href="/red-riding">Read it to me!</a>
            </article>
            <article class="story">
                <h3>Cinderella</h3>
                <a href="/cinderella">Read it to me!</a>
            </article>
        </section>
    </div>
</body>
</html>


story.html.eex

<!DOCTYPE HTML>
<html>
<head>
    <title><%= @title %></title>
    <link href="/static/favicon.ico" rel="icon">
    <link href="/static/storyteller.css" media="all" rel="stylesheet" type="text/css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <script src="/static/storyteller.js"></script>
</head>
<body>
    <div id="main-container">
        <h1><%= @title %></h1>
        <section id="chat">

        </section>
        <a class="play" href="/play/<%= @file_name %>">Play!</a>
    </div>
</body>
</html>


storyteller.css

html, body {
  background-color: #4B7399;
  font-family: Helvetica, Verdana, Arial, sans-serif;
  font-size: 14px;
}

#main-container {
  width: 75%;
  margin: 0 auto;
  background-color: #FFF;
  padding: 20px 40px;
  border: solid 1px black;
  margin-top: 20px;
}
.stories-list .story{
  display: inline-block;
  width: 30%;
  margin: 10px 0.5%;
  padding: 0.5em;
  border: 1px solid lightgray;
  text-align: center;
}

@media only screen and (max-width: 600px) {
  .stories-list .story{ width: 90%; }
}
.story a{
  display: inline-block;
  background-color: #4B7399;
  text-decoration: none;
  color: white;
  padding: 5px;
  border-radius: 3px;
}
.story a:hover{
  background-color: #4E7FAC
}


storyteller.js

$(function(){
  $('.play').on('click', function(ev){
    ev.preventDefault();
    var source = new EventSource(this.href);
    source.addEventListener('message', function(e) {
      var $line = $('<p class="story-line">' + e.data + '</p>');
      $line.appendTo('#chat').hide().fadeIn(200, function(){
        $("html, body").animate({ scrollTop: $(document).height() }, "slow");
      })
    }, false);
  });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top