Hi, I’m having trouble rendering a component correctly in Elixir.
So this is the component, which takes in a @truck_load:
<CardHeader
:if={{ not is_nil(@truck_load.sand_type) }}
background_color={{ @truck_load.sand_type_background_color }}
text_color={{ @truck_load.sand_type_text_color }}
title={{ @truck_load.sand_type }}
info={{ @truck_load.measured_weight }}
/>
The info part is currently set to truck_load.measured_weight, but I need it to be truck_load.weight if the truck_load’s current_column is “dispatched”.
I know this sounds very simple, but I’ve been struggling to get it to render correctly.
Right now, I’ve set info to be this in the CardHeader component:
info={{ render_weight(@truck_load) }}
and I’ve created these helpers, which should render either the truck_load.measured_weight or truck_load.target_weight, and format them the way I want:
defp render_weight(truck_load) do
if truck_load.current_column == "dispatched" do
format_measured_weight(truck_load.measured_weight)
else
format_measured_weight(truck_load.target_weight)
end
end
defp format_measured_weight(truck_load) do
"#{@truck_load.measured_weight} lb (#{
Weight.convert_pounds_to_tons_and_round(@truck_load.measured_weight)
} tons)"
end
defp format_target_weight(truck_load) do
"#{@truck_load.target_weight} lb (#{
Weight.convert_pounds_to_tons_and_round(@truck_load.target_weight)
} tons)"
end
But, nothing is showing up. How can I fix this?
Your private helper functions expect the entire struct (truck_load
), yet in render_weight
you are passing a struct’s field (truck_load.measured_weight
& truck_load.target_weight
). Also, inside their bodies you are using a module attribute @truck_load
. These are the inconsistencies I’ve observed.
2 Likes
Thanks so much!! This was super helpful. I fixed those inconsistencies:
defp render_weight(truck_load) do
if truck_load.current_column == "dispatched" do
format_target_weight(truck_load.target_weight)
else
format_measured_weight(truck_load.measured_weight)
end
end
defp format_target_weight(weight) do
"#{weight} testing to see if works (#{
Weight.convert_pounds_to_tons_and_round(weight)
} tons)"
end
defp format_measured_weight(weight) do
"#{weight} lb (#{
Weight.convert_pounds_to_tons_and_round(weight)
} tons)"
end
Now the format_measured_weight helper is working and rendering the weight correctly, but the format_target_weight is not. I don’t see the “testing to see if works” text I added to the format_target_weight helper, so I know that helper isn’t being hit and there must be an issue with the conditional part of my render_weight function. Is my syntax and everything correct?
Syntax-wise, everything looks alright to my eye. Is truck_load.current_column
actually dispatched
for what you are testing?
1 Like
ah so it turns out dispatched is an atom and not a string, so I just had to change my function to this:
defp render_weight(truck_load) do
if truck_load.current_column == :dispatched do
format_target_weight(truck_load.weight)
else
format_measured_weight(truck_load.measured_weight)
end
end
Thank you so much!! You saved my day haha
Also, quick question: I’m doing an elixir course that said it’s best to avoid using if/else statements when possible. Is this true? Is my current code written in an overly verbose or naive way?
It’s a matter of personal preference. If you prefer this way, then by all means, keep it like this (you’ll be the one reading the code in the future, anyway, thus keep it the way you like it most).
The above could be written like this:
defp render_weight(%{current_column: :dispatched} = truck_load),
do: format_target_weight(truck_load.weight)
defp render_weight(truck_load), do: format_measured_weight(truck_load.measured_weight)
or with a case
defp render_weight(truck_load) do
case truck_load.current_column do
:dispatched -> format_target_weight(truck_load.weight)
_ -> format_measured_weight(truck_load.measured_weight)
end
end
.etc
Credo is worth being mentioned in this context.
2 Likes
awesome, this really helps me understand elixir syntax better so I really appreciate it. will definitely be using credo also!