slouchpie

slouchpie

I have finished reading Craft GraphQL APIs in Elixir with Absinthe (Pragprog) and I am trying to expand upon the item_controller.ex to allow for “menu item” editing.

I have made these functions in the controller:

  @graphql """
  query ($id: ID!) {
  menu_item(id: $id) @put {
  name
  description
  }
  }
  """
  def edit(conn, %{data: %{menu_item: item}}) do
    render(conn, "edit.html", item: item)
  end

  @graphql """
  mutation UpdateMenuItem($id: ID!, $input: MenuItemInput!) {
    updatedMenuItem: updateMenuItem(id: $id, input: $input) {
      errors { key message }
      menuItem {
        name
        description
        price
      }
    }
  }
  """
  def update(conn, %{data: %{menu_item: _}}) do
    conn
    |> redirect(to: "/admin/items")
  end
  def update(conn, %{errors: errors}) do
    conn
    |> put_flash(:info, Enum.reduce(errors, "", fn e, a -> a <> e.message end))
    |> redirect(to: "/admin/items")
  end

Here is my edit.html.eex:

<%= render "form.html",
Map.put(assigns, :action,
Routes.item_path(@conn, :update, @item)) %>

Here is my form.html.eex:

<%= form_for @conn, @action, [method: :put, as: :input], fn f -> %>
    <div class="form-group">
        <label for="description">Description</label>
        <input type="string" id="description" as="description" name="description" value="<%= @item.description %>"/>
        <label for="price">price</label>
        <input type="string" id="price" name="price" value="<%= @item.price %>"/>
        <label for="name">name</label>
        <input type="string" id="name" name="name" value="<%= @item.name %>"/>
        <label for="category">category</label>
        <input type="string" id="category" name="categoryId" value="<%= @item.category_id %>"/>
    </div>
    <%= submit "Update", class: "btn btn-primary" %>
<% end %>

But I get an error when I submit the form. This is the error:

In argument "input": Expected type "MenuItemInput!", found null.
Variable "input": Expected non-null, found null.

It makes sense to me. I could, for example change the name attribute of any of the input elements in form.html.eex to be "input" and then I would get a different error:

Argument "input" has invalid value $input.

Again, it makes sense to me. The $input argument is not a MenuItemInput variable.

So I am looking to approach this in either of 2 possible ways:

  1. In the form.html.eex, I create a “form within a form” so that it has an “input” field which, in turn, has several fields.

  2. In the item_controller I pass variables into the @graphql module attribute. I simply don’t know how to do this. I experimented with a lot of strange syntax because I cannot even find examples of SDL that have the variables inline.

Any advice/criticism/ideas are very welcome. I’m sure somebody else has done this since it seems like a natural thing to try after finishing the book.

Showing Posts 1 to 4

slouchpie

slouchpie OP

I answered my own question! I just had to change my @graphql query to this:

  mutation UpdateMenuItem($id: ID!, $description: String!, $name: String!, $price: Decimal!, $categoryId: ID!) {
    update_menu_item(id: $id, input: {description: $description, name: $name, price: $price, categoryId: $categoryId}) {
      errors { key message }
      menu_item {
        name
        description
        price
      }
    }
  }

So it seems you cannot really use custom input types like MenuItemInput when using this @graphql module attribute in Phoenix controllers. Also I had to use snake-case for the field names.

P.S. I changed my controller update function signature to this:

def update(conn, %{data: %{update_menu_item: %{errors: nil, menu_item: menu_item}}}) do
slouchpie

slouchpie OP

A word of warning to anybody else doing this - mutations that come from Absinthe.Phoenix don’t trigger subscriptions! I cannot figure out why this is the case but I spent most of today trying to make this mutation trigger a subscription. It’s kind of annoying tbh.

slouchpie

slouchpie OP

Still talking to myself 1 month later…
I tried writing a test to recreate the problem:
https://github.com/peaceful-james/absinthe_phoenix/blob/6a4ff3c7aa132acdc85a4933eda805a5ebefce2b/test/absinthe/phoenix/controller_test.exs#L163

I hope this might help any of the core Absinthe team looking into this.

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews