By Developers, For Developers

Historical errata for Craft GraphQL APIs in Elixir with Absinthe

PDF PgPaper PgTypeDescriptionFixed onComments
85TYPO

in the Meal query, usage of inHand field, but result show field onRye.

At the end of page 85

2017-10-05
129TYPO

Ecto changset instead of Ecto changeset

Top of page, callback approach paragraph

2017-10-05
66SUGGEST

“For completeness we provide a fallthrough match. It returns nil, which denotes that the value doesn’t belong to a member type of the union.”

That match doesn’t appear in the code nor in the accompanying code. It is confusing. Is this added by default by the macro or the authors didn’t update the code?

2017-11-10
98TYPO

Just before setting up subscriptions title

Let’s get started be covering some important background about subscriptions

replace be -> by

2017-10-05
108TYPO

enter the following in the right side panel

maybe it meant

enter the following in the left side panel

2017-10-05
24ERROR

The current version of Phoenix 1.3 mix tasks start with ‘phx’ instead of the ‘phoenix’, as is used in the instructions for starting the application.

2017-10-05
9TYPO

The last line of the page:
“when working with databases via Ecto2
, and absinthe_phoenix and adds support”

The “and” between “absinthe_phoenix” and “adds” looks like it’s not suppose to be there.

2017-10-05
117TYPO

In page 177
What about the other case that shows up in the trigger topic function: , -> []

The other case in the code in the page 176 is _ -> []

2017-11-10
130TYPO

Absinthe.run(“{ search(term: \\”Rueben\\“) { name } }”, PlateSlateWeb.Schema)

Should be

Absinthe.run(“{ search(matching: \\”Rueben\\“) { name } }”, PlateSlateWeb.Schema)

2017-10-05
115TYPO

The main difference is that we’re now doing something more dyanmic

dyanmic -> dynamic

2017-10-05
133SUGGEST

First make sure you’re up to date with the code and seeds for this
chapter.

The chapter’s code has 6 different code folders. One might expect that the chapters seeds are complete from 1-start.

Suggestion:

1. Put the complete new migration in 07-chp.middleware/1-start or
2. State explicitly that for this section the reader must start from 07-chp.middleware/5-default or
3. Give instructions to change manually the migrations file. This last one would be more convenient for those who follow the project from the beginning.

S

2017-11-22
139SUGGEST

There’s a very useful package called :comeonin_ecto_password that we’re going to
use

It would be nice to say few words how to install that package.

2017-11-10
142TYPO

which is useful for whent the api client

which is useful for when the api client

2017-10-05
28SUGGEST

It’d be great to show the menu_items_test source… though I’m pretty sure it’s what I expect, I’m reading in a coffee shop and can’t go look to make sure.

2017-10-05
33TYPO

4th graf says “term” where the code said “name”.

2017-10-05
108ERROR

The paragraph about subscription mentions the topic macro which does not exist anymore.

2017-11-10
131SUGGEST

First sentence, last paragraph:

“The middleware/3 call back is run on every field for an object…”

I believe “callback” should replace “call back.”

Nice work on the book guys!

2017-10-05
131ERROR

Last sentence, second paragraph:

“If no loading happens, the middleware/3 callback is run.”

I believe that it should say the callback is not run.

Thanks!

2017-10-05
33TYPO

“By declaring our inputs up front Absinthe has a bounded set of input to work with and can thus give us atom an atom keyed map to work with as arguments, unlike Phoenix controller action params.”

“atom an atom” should be “an atom”

2017-10-05
151TYPO

“This makes sense of course, because aren’t doing anything in our tests to setup a context that might permit the creation of menu items.”

“because aren’t doing anything” should be “because we aren’t doing anything”

2017-10-05
73TYPO

The top of p73 mentions “removing the now-excessive fragment usage”, but the snippet that follows (04-chp.flexibility/3-interfaces/test/plate_slate_web/schema/query/search_test.exs) still contains the two “… on” fragment references. I think you meant to remove those; sure enough, when remove those lines from the test query, the test still passes.

2017-11-10
91TYPO

Not sure whether you’re intending to show all new code, but the text at the bottom of p91 mentions the :menu_item_result object type, but the snippet doesn’t show it. If I look at the downloaded code, it’s there (in 05-chp.mutations/5-errorobjects/lib/plate_slate_web/schema/menu_types.ex)

(I noticed this because I got curious about how, in p93’s middle snippet, “errors { key message }” would be interpreted as a list of error_items, vs a single error - make sense now that I’ve seen the :menu_item_result declaration.)

2017-11-10
138TYPO

Since you’re distinguishing employees and customers, maybe the example token in the API response example should be “EMPLOYEE-TOKEN-HERE” instead of “CUSTOMER-TOKEN-HERE”?

2017-11-10
41TYPO

“give us atom an atom ” should be “give us an atom”

2017-10-05
70TYPO

This: If you’re even curious about the GraphQL type that’s being returned,
Should be: If you’re ever curious about the GraphQL type that’s being returned,

s/even/ever

2017-10-05
79SUGGEST

In the mutations chapter, you say something along the lines of “Thankfully Ecto already pulls in the decimal package”.
While that’s true, I don’t think it is good to promote using a transitive dependency directly. I think it may be worth adding it to your own mix.exs

2017-11-21
1ERROR

This is more an Ecto issue than anything else. You are always using utc_datetime as type in your schema when you deal with dates which is good but you need to explicitly tell Ecto to use this type as well for the timestamps macros.

In your schema by using: @timestamps_opts [type: :utc_datetime]
In your repo config by using: migration_timestamps: [type: :utc_datetime]

2017-11-21
143SUGGEST

PlateSlateWeb.Authentication is mentioned in the text and used in the accounts resolver (08-chp.auth/2-login/lib/plate_slate_web/resolvers/accounts.ex) and corresponding test. However, it is not shown or fully described and the reader is not instructed to create it.

2017-11-21
24TYPO

Current text reads “Because the User type has fields and represents a complex value, GraphQL refers to as an object type, whereas Int and String are simple values ”

I think it should read “GraphQL refers to it as an object type”

2017-11-09
66TYPO

“Now that we have both a valid and invalid test working correctly, let’s talk about how users might use this query in the real world”

I think this would best read
“Now that we have both valid and invalid tests working correctly, let’s talk about how users might use this query in the real world”

2017-11-09
5TYPO

There are typos in the example JSON response:

- Missing comma after the “name” field.
- Missing trailing double quote in the string value of “email” field.

2017-11-09
117TYPO

“As we you learned in the previous chapter, its important to keep your business logic inside your context modules”

I can’t make sense of this, seems it should be “As you learned in the previous chapter…”

2017-11-10
66TYPO

menu items for a list of categories were requested, for example, this would like execute a database query per category (an example of the infamous “N+1”

Should be

menu items for a list of categories were requested, for example, this would execute a database query per category (an example of the infamous “N+1”

2017-11-10
165TYPO

The code sample uses {:finish, path} as the option argument (in two places), but both the paragraphs below it refer to :end.

2017-11-09
114TYPO

Bottom of page. Last paragraph. “Notably, we want use this ” <- should be “to use this”

2017-11-10
157ERROR

resolve fn _, %{context: %{current_user: current_user}}} do

should be

resolve fn _, %{context: %{current_user: current_user}} ->

(it has an extra closing brace ( should be }} not }}} ) and it should be -> instead of “do”)

2017-11-09
19ERROR

On this page, you say: “ add an :id field and a :name field to our :menu_item object.“

But it appears you’re also adding a description field too.

2017-11-09
27SUGGEST

You show how to add documentation with @desc but do not include further screenshots from Graphiql. I think you should include these screenshots to really drive home the point about adding a description.

2017-11-21
35ERROR

At the end of this page you say that the test works… before you even run it. “It works!” Should be after the test has run

2017-11-09
60TYPO

first paragraph under Importing Types, “singe” should be “single”

2017-11-21
62SUGGEST

Bottom of this page. Where you have the object menu_queries, I am not sure where you’re suggesting this could go.

2017-11-21
157ERROR

It appears that there’s code missing to get the viewer union working. Comparing code with 09-chp.performance the viewer query is also missing.

2017-11-21
65SUGGEST

Bottom of this page, items_for_category takes 3 arguments when previous examples have taken only two. I think the reason for the difference should be explained here and maybe some of the resolver code shown too.

2017-11-21
66ERROR

“For completeness we provide a fall- through match. It returns nil, which denotes that the value doesn’t belong to a member type of the union.”

No you don’t! This code is missing.

2017-11-21
79ERROR

There is an extra end at the end of the code block at the top of this page

2017-11-21
117TYPO

The document shows
trigger :ready_order, topic: fn
%{read: order} -> [to_string(order.id)]
_ -> []
end

When it should read
%{ready: order} -> [to_string(order.id)]

2017-11-21
130SUGGEST

iex(1)> Absinthe.run(“{ search(matching: \\”Rueben\\“) { name } }”, PlateSlateWeb.Schema)

Exceeds page margins. Is this intentional?

2017-11-21
134TYPO

menuItem(filter: “Thai Salad”) {

should be

menuItems(filter: “Thai Salad”) {

2017-11-21
134ERROR

menuItem(filter: “Thai Salad”) {

should be
menuItems(filter: {name: “Thai Salad”}) {

2017-11-21
6TYPO

In the third bullet you’ve got an extraneous “and”. You presumably wanted “When information about friends is returned, where will it be in the result?”.

2017-11-26
157ERROR

resolve_type fn
%{role: “customer”} -> :customer
%{role: “employee”} -> :employee
end

Should be
resolve_type fn
%{role: “customer”}, _ -> :customer
%{role: “employee”}, _ -> :employee
, -> nil
end

according to the accompanying code from the link in the snippet and the resolve_type doc in hexdocs

2017-12-03
175TYPO

“we just set a flag to flase within the our context” => “flase” should be “false”

2017-12-03
108TYPO

Code: “config fn_args, _info - > {:ok,topic:”*“} end”
Text: “setup macro” (2x), “The setup function” => I think it should be “config macro”, “config function”

2017-12-03
182TYPO

The last sentence on the page: “While it’s useful to be able to run specific code for plug and sockets, what would be useful is a” => a part of this sentence is missing

2017-12-03
9TYPO

I think function add_filter should be private. Ex:

`defp add_filter(filters, :date, date) do`

and

`defp add_filter(filters, key, value) do`

otherwise they would be like controller actions, wouldn’t be?

2017-12-03
160ERROR

The viewer query at the end of chapter 8 isn’t producing correct results (tested with latest source from chapter 8). I can’t compare it with source from beyond chapter 8 since the whole viewer setup is absent.

Running:
{
viewer{
… on Customer{
orders{
customerNumber
items{name quantity}
}
}
}
menuItems{
name
}
}

Response:
{
“data”: {
“viewer”: {}, <- even though there should be orders.
“menuItems”: [items here]
}
}

2018-01-22
145ERROR

token = PlateSlateWeb.Authentication.sign(%{
type: “employee”, id: user.id

and the test in page 146

assert {:ok, %{type: “employee”,id: user.id,}} == PlateSlateWeb.Authentication.verify(token)

but then in page 150

defp get_user(%{id: id, role: role}) do

which doesn’t match.

Should be either “type” or “role”

2018-01-22
155SUGGEST

The text regarding the code listing in the bottom of the page 155 and beginning of the page 156 doesn’t mention that this is new code. Actually the code listing is available since “2-login” check point in the accompanying code but it is never mentioned in the book before.

2018-01-22
157SUGGEST

:any which permits any user to view the page whether they’re a customer or

We don’t view any pages with GraphQL. Instead maybe it would be better to be

:any which permits any user to perform the operation whether they’re a customer or

This is also the terminology the GraphQL documentation uses [1][2]

[1] graphql.org/learn/queries/
[2] facebook.github.io/graphql/draft/#sec-Language.Operations

2017-12-03
175TYPO

In this case, we just set a flag to flase within the our context.

In this case, we just set a flag to false within our context.

2017-12-03
181SUGGEST

It would be nice to add installation instructions or at least a link where dataloader package can be found. A link is provided for facebook’s dataloader but just a mention about absinthe-graphql organization in Github for the elixir package.

2018-01-22
166ERROR

On pg. 166 I am finding the following code is not matched

```
defp apply([], :get_string, field, %{identifier: :allergy_info}) do
[{Absinthe.Middleware.MapGet, to_string(field.identifier)}]
end
```

Changing this to will match

```
defp apply(_, :get_string, field, %{identifier: :allergy_info}) do
[{Absinthe.Middleware.MapGet, to_string(field.identifier)}]
end
```

2018-01-22
173TYPO

“Absinthe is going to to call ”

2018-01-22
106SUGGEST

In chapter 3, at the end of “Marking Arguments as Non Null” it is suggested to put the field category as non_null, but in the next chapter “Creating Your Own Scalar Types”, the source code does not have that change and when you get to the first test , an error is generated by not specifying a category.

I know that we must work with the code of each chapter, but some hint/warning that it will no longer be used or it’s just a tip, or adding the category in the tests would be nice.

2018-01-22
196TYPO

“The mode: INTERNAL bit isn’t a strange new syntax; this is just an
argument with an enum value that tells Absinthe.Phoenix that we want to have it
adjust the results of executing the query to suite internal Elixir usage”

suite should be “suit”.

2018-01-22
102TYPO

in the listing at the begging of the page the line

|> cast_embed(:items)

is not marked as new.

2018-01-22
67SUGGEST

def search(, %{matching: term},) do
{:ok, Menu.search(term)}
end

The function PlateSlate.Menu.search/1 is not defined anywhere in the book. Not previously or later. This is difficult for the reader who follows through the project as he has to suspect and search in the accompanying code to find the definition of that function and the search_ecto/2 function.

2018-01-22
117ERROR

What about the other case that shows up in the trigger topic function: , -> []

The other case of trigger function in page 116 is

trigger [:ready_order, :complete_order], topic: fn
%{order: order} ->
[to_string(order.id)]
_ ->
[]

2018-01-22
117ERROR

The ready_order resolver will return %{order: %Order{id: “2”, …}},

Technically the resolver returns {:ok, %{order: %Order{id: 2, …}}}

I guess the first element of the tuple is omitted for the sake of the discussion.

The id is depicted as binary but it is actually an integer. Later in the text is described how it should be transformed with to_string as it is an integer

2018-01-22
132TYPO

when the default behaviour doesn’t suite the data you’re working

I think it should be suit
Also should it be behaviour or behavior (American spelling)?

2018-01-22
108TYPO

Line 3:
“You’ll first need to a subscription field in your schema”

could it be that there is a missing word - maybe “to add a subscription …”

2018-01-22
193SUGGEST

Grammar of this sentence seems off:
“In both cases we’re just grabbing the parent item, adding it dataloader, and then getting it back out in the on_load.”

Maybe “grabbing its dataloader”

2018-03-01
225ERROR

I believe this sentence is misleading since the basic javascript file is served by Express not Phoenix.

“We’ll start with a basic, single file JavaScript application that’s served directly by Phoenix, ”

2018-03-01
188TYPO

SQL is written with a lower-case l instead of L

“When we run that function we can see that a single SQl query runs to grab all the items we’d queued up so far.”

2018-03-01
163ERROR

resolve &Resolvers.Menu.list_items/3

Until now the resolver was

resolve &Resolvers.Menu.menu_items/3

2018-03-01
63ERROR

By mistake I wrote the previous erratum as in page 163. It is actually in page 63.

resolve &Resolvers.Menu.list_items/3

Until now the resolver was

resolve &Resolvers.Menu.menu_items/3
—voger

2018-03-01
67TYPO

Since the resolved value for the :search_value type will be Ecto schema structs

maybe it should be :search_result

2018-03-01
84SUGGEST

{
menuItem: createMenuItem(input: $menuItem) {
name
}
}

Why not put the whole mutation there ?

mutation ($menuItem: MenuItemInput!) {
menuItem: createMenuItem(input: $menuItem) {
name
}
}

2018-03-01
99SUGGEST

This is not about the book but for the accompanying code.

The function PlateSlateWeb.UserSocket.connect/2 is since chapter 2

def connect(_params, socket) do
{:ok, socket}
end

and it works. In this chapter’s (6) code it is

def connect(_params, socket) do
{:ok, assign(socket, :absinthe, %{schema: PlateSlateWeb.Schema})}
end

but this change is not mentioned in the book.

2018-03-01
118TYPO

For example suppose :read_order

For example suppose :ready_order

2018-03-01
135ERROR

In the bottom of the page the reader is instructed to copy/paste the listing but it is missing the aliases and creation of the sides category. Plus the sides variable is undefined. Need to add the lines in the beginning of the listing

alias PlateSlate.{Menu, Repo}
sides = %Menu.Category{name: “Sides”} |> Repo.insert!

2018-03-01
135ERROR

I can’t edit my previous erratum. The proper lines for the listing in page 135 should probably be

alias PlateSlate.{Menu, Repo}
sides = Repo.get_by(PlateSlate.Menu.Category, name: “Sides”)

_thai_salad =
%Menu.Item{
name: “Thai Salad”, price: 3.50, category: sides,
allergy_info: [ ,{“allergen” => “Shell Fish”, “severity” => “Shared Equipment”}, ] } |> Repo.insert!

2018-03-01
144ERROR

mix ecto.gen.migration AddCustomerToOrders

but the file name in the listing that follows is
08-chp.auth/1-start/priv/repo/migrations/20170828180804_add_relations_to_orders.exs

The module name remains AddCustomerToOrders though

2018-03-01
144ERROR

The second listing on the page is for the migration. The same as the first listing on the page
08-chp.auth/1-start/priv/repo/migrations/20170828180804_add_relations_to_orders.exs

It should be the listing for
08-chp.auth/1-start/lib/plate_slate/ordering/order.ex

2018-03-01
145SUGGEST

foo.com and bar.com are both registered domains. Wouldn’t be better to use
example.{com,net,org}?

2018-03-01
160ERROR

def place_order(_, ,{context: context}) do

This line is also changed but it is not marked as changed.

2018-03-01
171TYPO

for a bunch of menu item
for a bunch of menu items

2018-03-01
179TYPO

so let’s give it a look as a way to get out feet wet.
so let’s give it a look as a way to get our feet wet.

2018-03-01
187SUGGEST

Then in our Menu item context we’re going to define a Dataloader source:

Then in our Menu context we’re going to define a Dataloader source:

2018-03-01
190TYPO

Return once more to the :category field and let’s put dataloader to work:

Return once more to the :category field resolver and let’s put dataloader to work:

2018-03-01
190ERROR

In the second listing need to insert

import Absinthe.Resolution.Helpers, only: [on_load: 2]

2018-03-01
190TYPO

which we’re importing from Absinthe

which we’re importing from Absinthe.Resolution.Helpers

2018-03-01
213SUGGEST

In the second listing, the new code for the link maybe should be marked.

10-chp.serverui/4-login/lib/plate_slate_web/templates/layout/app.html.eex

2018-03-01
216TYPO

On the :orders field the resolver: option is an anonymous function,

On the :orders field the resolve: option is a captured(?) function,

2018-03-01
59?SUGGEST

In chapter three, in this listing: /code/03-chp.userinput/2-matchinginline/lib/plate_slate_web/schema.ex

It is critical that the reader include the “import Ecto.Query”, but this is not called out in the text. For the reader following along and attempting to build from scratch this might cause a bit of confusion as to why the code is not compiling.

2018-03-01
226SUGGEST

Maybe it would be better to state explicitly that the “plate-slate-basic-ui” should not be contained in the PlateSlate project folder.

2018-03-01
42TYPO

In the code snippet, 03-chp.userinput/4-ordering/lib/plate_slate/menu/menu.ex, the argument to ‘^order’ should not be ‘:name’. Probably it is ‘order’. I have not tested the code though…

2019-05-28The book code is correct. The interpolated value would result in `order: {:asc, :name} or {:desc, :name} which is what we want.
142ERROR

The second example on this page is meant to be refering to `lib/plate_slate/ordering/order.ex` where the :customer_id is added to the cast list, however the example that is there is a repeat of the first example on the page (the snippet of the migration changes for adding the customer_id field to the :orders table). In the source code for this chapter, the change is indeed there; it’s just the example in the book is wrong.

2019-05-28
245ERROR

The example command of `get-graphql-schema …localhost:4000/graphql > ./schema.graphql` at the very bottom of this page uses an incorrect URL. The URL should be localhost:4000/api/graphql (the /api/ prefix was forgotten, it seems).

2019-05-28
247ERROR

Cannot compile the graphql schema with relay-compiler as described on this page. Even the book source code fails with same error I’m getting:

Writing js
ERROR:
rule is not a function
error Command failed with exit code 100.

177TYPO

“which will import from the Absinthe.Resolution.Helpers module” >> “which we’ll import …”

2019-05-21
179SUGGEST

“The first makes sure we can hook into individual fields when they need to use Dataloader”

This sentence references Dataloader before it’s been introduced.

2019-05-21
238SUGGEST

"We’ll cover two of them: Apollo Client and Relay.

At the current time, there are two major client-side JavaScript frameworks that developers use to build user interfaces on top of GraphQL: Relay and the Apollo GraphQL platform."

This seems redundant? The prior sentence should probably be removed.

2019-05-28This will be fixed in the next edition, thanks!
125ERROR

Text suggests that Absinthe.run will be used to test a mutation, but the code pushes the mutation over the socket.

Text: The next thing we do is run a mutation to place an order. You could actually push this document over the socket as well; sockets support all the different operation types. For the purposes of this test case, though, doing an explicit Absinthe.run call is handy because it helps make it clear that the trigger process that’s happening isn’t tied to the socket process specifically.

Code: 06-chp.subscriptions/4-publish/test/plate_slate_web/schema/subscription/new_order_test.exs

ref = push_doc socket, @mutation, variables: %{“input” => order_input}

2019-05-28Good catch, this will be fixed in a future addition, thanks!
3218ERROR

At the first command in the book (feel really annoyed): Absinthe.Schema.lookup_type(PlateSlateWeb.Schema, “MenuItem”)

Compilation error in file lib/plate_slate_web/schema.ex

(Absinthe.Schema.Error) Invalid schema:
Elixir.PlateSlateWeb.Schema:0: The root query type must be implemented and be a of type Object

Elixir 1.7.1 (compiled with Erlang/OTP 21)

2019-05-21
3016ERROR

Compilation error in file lib/plate_slate_web/schema.ex

(Absinthe.Schema.Error) Invalid schema:
Elixir.PlateSlateWeb.Schema:0: The root query type must be implemented and be a of type Object

If you are using elixir 1.7 update the deps to {:absinthe, “~> 1.4.13”}.

2019-05-21
56ERROR

Running the first test fails because of some characters that are changed:
left: %{“name” => “Bánh mì”}
right: %{“name” => “Bánh mì”}

1) test menuItems field returns menu items (PlateSlateWeb.Schema.Query.MenuItemsTest)
test/plate_slate_web/schema/query/menu_items_test.exs:15
Assertion with failed code: assert json_response(conn, 200) ,{“name” => “Croque Monsieur”}, ,{“name” => “Bánh mì”}, ,{“name” => “French Fries”}, ,{“name” => “Pasta Salad”}, ,{“name” => “Soft Drink”}, ,{“name” => “Masala Chai”}, ,{“name” => “Chocolate Milkshake”}]}}
left: ,{“name” => “Croque Monsieur”}, ,{“name” => “Bánh mì”}, ,{“name” => “French Fries”}, ,{“name” => “Pasta Salad”}, ,{“name” => “Soft Drink”}, ,{“name” => “Masala Chai”}, ,{“name” => “Chocolate Milkshake”}]}}
right: ,{“name” => “Croque Monsieur”}, ,{“name” => “Bánh mì”}, ,{“name” => “French Fries”}, ,{“name” => “Pasta Salad”}, ,{“name” => “Soft Drink”}, ,{“name” => “Masala Chai”}, ,{“name” => “Chocolate Milkshake”}]}}
stacktrace:
test/plate_slate_web/schema/query/menu_items_test.exs:19: (test)

Finished in 0.06 seconds
1 test, 1 failure‘

2019-05-28This looks like an encoding issue with your editor. Make sure you're running in UTF8 mode. All Elixir code expects UTF8.
113ERROR

Contrary to the explanations (“For the purposes of this test case, though, doing an explicit Absinthe.run call is handy because it helps make it clear that the trigger process that’s happening isn’t tied to the socket process specifically”), the code uses the socket :
ref = push_doc socket, @mutation, ​variables:​ %{​“​​input”​ => order_input}

2019-05-28
185ERROR

The book says that running loader |> Dataloader.get(Menu, Menu.Item, 2) would return nil but instead I get this:

iex(9)> loader |> Dataloader.get(Menu, Menu.Item, 2)

(Dataloader.GetError) “Unable to find batch {:queryable, #PID<0.2133.0>, PlateSlate.Menu.Item, :one, :id, %{}}”
(dataloader) lib/dataloader.ex:193: Dataloader.do_get/2

2019-05-28This happens if using a later version of Dataloader than the one specified in the book mix.lock.
197TYPO

Within the code example, the graphql query as well as the body of the index function should use camelCase (at least … wasn’t that the convention)?

2019-05-28When using Absinthe.Phoenix.Controller you generally want to use `snake_case so that the values come back in a form more normally usable within Elixir. Absinthe allows you to use query transformers to support different casing conventions.
204ERROR

The Phoenix.Controller.redirect function does not halt the connection which causes the following error

Request: GET /admin/items

(exit) an exception was raised:
(Plug.Conn.AlreadySentError) the response was already sent
(phoenix) lib/phoenix/controller.ex:525: Phoenix.Controller.put_new_layout/2
(…)

adding `|> halt()` to the pipeline does prevent that exception from happening

2019-05-28This seems like an error in your code, Phoenix.Controller source code definitely shows that redirect halts the connection.
191TYPO

The description about the dataloader/2 has some typo.

1)
“`Dataloader.load(loader, {key, args}, parent)” should be “`Dataloader.load(source, {key, args}, parent)”

2)
“Dataloader.get(loader, {key, args}, parent)” should be
“Dataloader.get(loader, source, {key, args}, parent)”

2019-05-21Fixed, thanks!
142TYPO

I think this page has an accidental repetition of the code block from “08-chp.auth/1-start/priv/repo/migrations/20170828180804_add_customer_to_orders.exs”, where the second appearance should actually be something different indicating how to add the association field of customer_id to the order schema.

The text says:

> The column we’ve added to the orders table needs a corresponding line in the
> order schema module, and the addition of the :customer_id to the changeset
> function’s cast list:

But then the code block is a repeat of the one above which shows creating the migration.

I’m guessing the intended line should be something like

belongs_to :customer, PlateSlate.Accounts.User

2019-05-28
16ERROR

This is more for the benefit of people reading this page than an error in the printing.

To compile the project with the versions in the source:

Set your .tool-versions to:
erlang 20.0 (or a bugfix release)
elixir 1.5.3-otp-20
and run asdf install.

Then, run:
mix deps.unlock postgrex
so that you can get a necessary bugfix release.

2019-05-21
25ERROR

Missing the actual query that the reader should type here. Thus, I recommend the following:

replace:

Start by typing your query into the text area to the top left.

with:

Start by typing the following query into the text area to the top left:

{
menuItems {
name
}
}

Then move the corresponding diagram after the above query in order to give the reader the result of executing it.

36ERROR

query """ { menuItems(matching: 123) { name } } """ test "menuItems field returns errors when using a bad value" do response = get(build_conn(), "/api", query: query)

assert %{
“errors” => [
%{“message” => message}
]
} = json_response(response, 400)

assert message == “Argument \\”matching\\" has invalid value 123."
end

$ mix test test/plate_slate_web/schema/query/menu_items_test.exs
..

1) test menuItems field returns errors when using a bad value (PlateSlateWeb.Schema.Query.MenuItemsTest)
test/plate_slate_web/schema/query/menu_items_test.exs:76
(RuntimeError) expected response with status 400, got: 200, with body:
{errors \\“matching\\” has invalid value 123.“,”locations“:[{”line“:2,”column":0}]}]}
code: } = json_response(response, 400)
stacktrace:
(phoenix) lib/phoenix/test/conn_test.ex:373: Phoenix.ConnTest.response/2
(phoenix) lib/phoenix/test/conn_test.ex:419: Phoenix.ConnTest.json_response/2
test/plate_slate_web/schema/query/menu_items_test.exs:83: (test)

Finished in 0.2 seconds
3 tests, 1 failure

2019-05-28This happened because you upgraded absinthe_plug which has slightly different behaviour with respect to status codes. Using the version specified in the book lock file will ensure that the book code works.
69ERROR

The query
{
menuItems(addedBefore: 123) {
name
}
}

should be

{
menuItems(filter: {addedBefore: 123}) {
name
}
}

89TYPO

The last paragraph mentions format_error/1. This function is not used here, as the paragraph suggests. It is used on page 93.

16SUGGEST

Make this stuff work with the latest Phoenix (1.4.x) and Elixir (1.9.x)… I’ll help if you want.

Categories: