5

I am trying to get users that were created before/after certain date and I get this error.

"message": "Argument \"filter\" has invalid value $filter.\nIn field \"insertedAfter\": Expected type \"NaiveDateTime\", found \"2018-05-13\".",

The error makes sense since "2018-05-13" is not NativeDateTime... However, I thought NativeDateTime should parse the string "2018-05-13". I am trying to apply what I learned from a book but having hard time. I also created a custom date scalar but I basically encountered the same error.

How can I accomplish being able to search user created after certain date with phoenix and absinthe?

query($filter: UserFilter){
  allUsers(filter: $filter){
    id
    firstName
    lastName
  }
}

values
{
  "filter": {
    "insertedAfter": "2018-05-13"
  }
}

Ecto schema, account > user.ex

schema "users" do
  field :avatar_img, :string
  field :email, :string, null: false
  field :fb_token, :string
  field :first_name, :string
  field :google_token, :string
  field :last_name, :string
  field :password, :string, null: false
  field :admin_user_id, :string

  timestamps()
 end

types.ex

 use Absinthe.Schema.Notation
 use Absinthe.Ecto, repo: ElixirBlog.Repo
 import_types Absinthe.Type.Custom

 object :user do
  field :id, non_null(:id)
  field :first_name, non_null(:string)
  field :last_name, non_null(:string)
  field :email, non_null(:string)
  field :password, non_null(:string)
  field :avatar_img, :string
  field :admin_user_id, :string
  field :fb_token, :string
  field :google_token, :string
  field :inserted_at, :naive_datetime
  field :updated_at, :naive_datetime
end

Absinthe schema schema.ex

use Absinthe.Schema
import_types Elixir.Schema.Types

input_object :user_filter do
  field :id, :integer
  field :first_name, :string
  field :last_name, :string
  field :email, :string
  field :inserted_before, :naive_datetime
  field :inserted_after, :naive_datetime
end

query do
  field :all_users, list_of(:user) do
   arg :filter, :user_filter
   arg :order, type: :sort_order, default_value: :asc
   resolve &ElixirBlogWeb.UsersResolver.all_users/3
  end
end

users_resolver.ex

alias Elixir.Account

def all_users(_root, args, _info) do
 users = Account.list_users(args)
 {:ok, users}
end

account.ex

def list_users(args) do
  args
  |> Enum.reduce(User, fn
    {:order, order}, query ->
    query |> order_by({^order, :first_name})
    {:filter, filter}, query ->
      query |> filter_with(filter)
    end)
  |> Repo.all
end

defp filter_with(query, filter) do
  Enum.reduce(filter, query, fn
    {:id, id}, query ->
      from q in query, where: q.id == ^id
    {:first_name, first_name}, query ->
      from q in query, where: ilike(q.first_name, ^"%#{first_name}%")
    {:last_name, last_name}, query ->
      from q in query, where: ilike(q.last_name, ^"%#{last_name}%")
    {:email, email}, query ->
      from q in query, where: ilike(q.email, ^"%#{email}%")
    {:inserted_before, date}, query ->
      from q in query, where: q.inserted_at <= ^date
    {:inserted_after, date},  query ->
      from q in query, where: q.inserted_at >= ^date
 end)
end

mix.exs

  {:phoenix, "~> 1.3.2"},
  {:phoenix_ecto, "~> 3.2"},
  {:absinthe, "~> 1.4"},
  {:absinthe_plug, "~> 1.4"},
  {:absinthe_ecto, "~> 0.1.3"},
Felipe Skinner
  • 16,246
  • 2
  • 25
  • 30

1 Answers1

3

I can't find things about :naive_datetime in Absinthe's document.

But we can find it [in Absinthe's code](https://github.com/absinthe-graphql/absinthe/blob/master/lib/absinthe/type/custom.ex#L29

The DateTime appears in a JSON response as an ISO8601 formatted string.

So we can use datetime "2018-05-13 00:00:07".

chris
  • 2,761
  • 17
  • 24
  • Thank you for your answer. So we need to change the input date in the frontend because users are not going to type ~N[2018-05-13 00:00:00]. I was wondering if there's any other way? – Yuki Umetsu May 15 '18 at 11:56
  • @梅津優樹 Nope. You can figure out to transfer the type. – chris May 15 '18 at 12:00
  • Okay. I changed the variable, `"insertedAfter": "~N[2018-05-13 00:00:00]"` It still gives me `"message": "Argument \"filter\" has invalid value $filter.\nIn field \"insertedAfter\": Expected type \"NaiveDateTime\", found \"~N[2018-05-13 00:00:00]\".",` – Yuki Umetsu May 15 '18 at 12:06
  • @梅津優樹 `~N[2018-05-13 00:00:00] ` is a sigil instead of string. Plz read the url I gave. : P – chris May 15 '18 at 12:09
  • `~N[2018-05-13 00:00:00]` instead of `"~N[2018-05-13 00:00:00]"`. – chris May 15 '18 at 12:10
  • When I put `"insertedAfter": ~N[2018-05-13 00:00:00]`, GraphiQL gives me error: Variables are invalid JSON: Unexpected token ~ in JSON at position 37. It is expecting JSON format. – Yuki Umetsu May 15 '18 at 12:23
  • Try "2018-05-13 00:00:07" instead of ~N[2018-05-13 00:00:00]. @梅津優樹 – chris May 15 '18 at 12:42