Multiple_select selected field access non existing key

I’m trying to refactor my multiple_select code.

Here’s the refactor code:

template:

  37         <%= multiple_select f, :company_id, company_select_options(@companies),                            38               [prompt: "Choose one or more company.",                                                      39                class: "custom-select w-100 form-control is-invalid",
  40                selected: Enum.map(@perfume.companies, &(&1.id)),
  41                id: "company_select"] %>

The problem is that when the user input no company, then this @perfume.companies goes crazy.

The error message: key :companies not found in: %{...

How do I fix it?

One solution I had was to made a companies key in @perfume map and set it to nil, in the controller. But it’s ugly.

My current code have a view function that check for if the key exist. Is this the best possible solution?

Current code view:

  47   def company_selected(params) do
  48     cond do
  49       # this is for changeset
  50       Map.has_key?(params, :companies) -> 
  51         company_selected_aux(params.companies)
  52       true ->
  53         nil
  54     end

Thanks!

Is @perfume a map or a struct? If its a map, just use @perfume[:companies] || []

If it is a struct, you should make it that [] is the default value for :companies.

But as you say the key is missing sometimes, I think a map can safely be assumed.

1 Like

Thank you.

I used your solution and it have pointed toward my inconsistency in passing map for create action and struct for update action.

I’m going to need to refactor my controller to pass just map now by converting all struct to map (Map.from_struct/1).

No, in this case its properly better to pass structs everywhere and use the default value of [].

2 Likes