Solved:Possible errata in programming phoenix 1.4 version p1.0 pdf

At page 47, I run into a confusing part:

Excerpt from the page

With our user in place, let’s define our Accounts context. We will add a couple
of functions which will allow user account fetching. Let’s create a new file in
lib/rumbl/accounts.ex and key this in:
controllers_views_templates/listings/rumbl/lib/rumbl/accounts.ex

Line 1 defmodule Rumbl.Accounts do
- @moduledoc """
- The Accounts context.
- """
5
- alias Rumbl.Accounts.User
-
- def list_users do
- [
10 %User{id: "1", name: "José", username: "josevalim"},
- %User{id: "2", name: "Bruce", username: "redrapids"},
- %User{id: "3", name: "Chris", username: "chrismccord"}
- ]
- end
15
- def get_user(id) do
- Enum.find(list_users(), fn map -> map.id == id end)
- end
-
20 def get_user_by(params) do
- Enum.find(list_users(), fn map ->
- Enum.all?(params, fn {key, val} -> Map.get(map, key) == val end)
- end)
- end
25 end

Isn’t this suppose to be?
lib/rumbl/accounts.ex and key this in:

defmodule Rumbl.Accounts do
  @moduledoc """
  The accounts context
  """

  alias Rumbl.Accounts.User
end

So what do I do with this part?

controllers_views_templates/listings/rumbl/lib/rumbl/accounts.ex

def list_users do
    %User{id: "1", name: "Jose", username: "josevalim"},
    %User{id: "2", name: "Bruce", username: "redrapids"},
    %User{id: "3", name: "Chris", username: "chrismccord"}
  end

  def get_user(id) do
    Enum.find(list_users(), fn map -> map.id == id end)
  end

 def get_user_by(params) do
    Enum.find(list_users(), fn map ->
      Enum.all?(params, fn {key, val} -> Map.get(map, key) == val end)
    end)
  end

Thank in advance if you can shed some light over this

After looking closely at the User structs discovered that they have commas and that gave an error in my vscode on Lubuntu. So I change the code to this:

in lib/rumbl/accounts.ex

defmodule Rumbl.Accounts do
  @moduledoc """
  The accounts context
  """

  alias Rumbl.Accounts.User

  def list_users do
    %User{id: "1", name: "Jose", username: "josevalim"}
    %User{id: "2", name: "Bruce", username: "redrapids"}
    %User{id: "3", name: "Chris", username: "chrismccord"}
  end

  def get_user(id) do
    Enum.find(list_users(), fn map -> map.id == id end)
  end

  def get_user_by(params) do
    Enum.find(list_users(), fn map ->
      Enum.all?(params, fn {key, val} -> Map.get(map, key) == val end)
    end)
  end
end

and ignored this controllers_views_templates/listings/rumbl/lib/rumbl/accounts.ex

Am i going the right way?

Thanks

At the second page(48) everything becomes clear when I see:

Let’s take this context for a spin and then in iex:

Code

iex> alias Rumble.Accounts
iex> alias Rumble.Accounts.User
iex> Accounts.list_users

Explanation:
The final command confirms my intuition that the function(def) list_users is part of the context Accounts module more precisely the Rumbl.Accounts module.

Still have a problem with this

def list_users do
    %User{id: "1", name: "Jose", username: "josevalim"}
    %User{id: "2", name: "Bruce", username: "redrapids"}
    %User{id: "3", name: "Chris", username: "chrismccord"}
  end

If i use it like the code above it is compiling fine with iex mix phx.server but i get only the last User struct
%User{id: "3", name: "Chris", username: "chrismccord"}

On the other hand if i use commas like so:

def list_users do
    %User{id: "1", name: "Jose", username: "josevalim"},
    %User{id: "2", name: "Bruce", username: "redrapids"},
    %User{id: "3", name: "Chris", username: "chrismccord"}
  end

I get this error

** (SyntaxError) lib/rumbl/accounts.ex:11: unexpectedly reached end of line. The current expression is invalid or incomplete

So what does this multiple struct construct expects?

Thanks

Found out that it expect a list of maps.

So the following solves all the problems:

def list_users do
    [%User{id: "1", name: "Jose", username: "josevalim"},
    %User{id: "2", name: "Bruce", username: "redrapids"},
    %User{id: "3", name: "Chris", username: "chrismccord"}]
  end

Solution

One thing that is helpful with Pragmatic books is that you can click on the code listing (Ebook of course) and it will take you to the plaintext version without the formatting. You can use that for copy/pasting rather than the PDF itself.

2 Likes

Thank you,
I didn’t realize that controllers_views_templates/listings/rumbl/lib/rumbl/accounts.ex this was a link to the code.
I was using a printed book.

A print copy would be an issue regarding the link! One thing you may want to do, if you haven’t already, is grab the source code from https://pragprog.com/titles/phoenix14/source_code. This will generally be the authoritative source from the book.

Some of the helps like line numbering and code highlighting can interfere with copy pasting. You’d always leave these out of copied snippets, but you can also copy straight from the source to avoid them completely.

It sounds like you’re all set now :metal:

1 Like

Thank you for the source code link.

Even with the print book the links can be helpful.

(Faux-REST) build your own URL:

The missing piece is that code listing urls for this book all have a path root of

https://media.pragprog.com/titles/phoenix14/code/

The title of the code listing on page 47 is

controllers_views_templates/listings/rumbl/lib/rumbl/accounts.ex

Combine both to get:

https://media.pragprog.com/titles/phoenix14/code/controllers_views_templates/listings/rumbl/lib/rumbl/accounts.ex

Note the phoenix14 in the book’s storefront URL:

https://pragprog.com/book/phoenix14/programming-phoenix-1-4

With Real-time Phoenix (Pragprog) the root is:

https://media.pragprog.com/titles/sbsockets/code/

and a listing title is

hello_sockets/lib/hello_sockets_web/channels/ping_channel.ex

so

https://media.pragprog.com/titles/sbsockets/code/hello_sockets/lib/hello_sockets_web/channels/ping_channel.ex

Note the sbsockets in the book’s storefront URL:

https://pragprog.com/book/sbsockets/real-time-phoenix

So the code listing URL path template is

https://media.pragprog.com/titles/{book_id}/code/{listing_title}
2 Likes

Cool tip.
Thank you for sharing.