"(FunctionClauseError) no function clause matching" error

Hey all, I’m new to elixir and getting the following error:

** (FunctionClauseError) no function clause matching in TSS.DriverStatuses.list_assignable_drivers_by_truck_load/1

So in my module, I define a get_remaining_time function that takes a truck_load:

  defp get_remaining_time(truck_load) do
    time_since_available = DriverStatuses.list_assignable_drivers_by_truck_load(truck_load)
    Formatters.decorate_time_since_available(time_since_available)
  end

This function uses the list_assignable_drivers_by_truck_load in the DriverStatuses module, which looks like this:

  def list_assignable_drivers_by_truck_load(%TruckLoad{
        well: %{id: well_id},
        pull_point: pull_point
      }) do
    base_assignable_drivers_query()
    |> apply_default_select(pull_point.point)
    |> filter({:well_id, well_id})
    |> sort({:distance_in_meters, :asc}, %{"pull_point_id" => pull_point.id})
    |> preload(driver: [:trailer_type, driver_contract: [:carrier]])
    |> Repo.all()
  end

and then formats it using the decorate_time_since_available function in the Formatters module, which looks like this:

  def decorate_time_since_available(%{driver_status: %{last_available_at: last_available_at}})
      when not is_nil(last_available_at),
      do:
        humanize_time(DateTime.diff(DateTime.utc_now(), last_available_at), :seconds, :minutes) <>
          " (hh:mm)"

  def decorate_time_since_available(_), do: "N/A"

Finally, I am calling the function like so:

<CardInfo label="Time Since Available" title={{ get_remaining_time(@truck_load) }} small />

I think I’m not pattern matching correctly, but nothing I’ve tried is working. How can I fix this?
Thanks so much!!

So your @truck_load is not a %TruckLoad(...} then. the error message after the ** (FunctionClausError)... line should give you more clue

1 Like

or it is, but the contents do not pattern match

So, I fixed that issue I believe by passing in a struct:

  defp get_remaining_time(truck_load) do
    current_truck_load = %TruckLoad{
      pull_point: truck_load.pull_point,
      well: %Well{id: truck_load.well_id}
    }

    driver = TSS.DriverStatuses.list_assignable_drivers_by_truck_load(current_truck_load)
    time_elapsed = Formatters.decorate_time_since_available(driver)

    "#{time_elapsed} (hh:mm)"
  end

But now I am getting this error:

(KeyError) key :pull_point not found in: ~huge map of truck_load's contents~

The truck_load map has a pull_point key, but it’s value is pull_point: #Ecto.Association.NotLoaded<association :pull_point is not loaded>

I believe I need to preload pull_point, but I shouldn’t do that on the front end, right? I’m not sure how else to access that data though…

Thanks so much for the help, I really really appreciate it!!!

These two statements are not compatible - the error is specifically stating that truck_load does NOT have a :pull_point key at the beginning of get_remaining_time.

Some things to investigate:

  • where is the argument to get_remaining_time coming from? The code in your initial post suggested it was intended to be a %TruckLoad{} struct, but wasn’t.
  • as shown in these posts, list_assignable_drivers_by_truck_load will return a list of structs (from Repo.all) - but decorate_time_since_available expects a single driver. Should that be Repo.one?