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

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews