Relation records don't trigger reactive state on first render #52
Description
Code examples below simplified from real app experiencing the issue.
I have an input component where the RR attribute isn't rendered directly to allow valid data to be entered before assigning. Record attribute is loaded and assigned to state before mount. Or after, doesn't seem to matter or affect this issue. But in the load
block value
is nil, when that method is supposed to guarantee the data is ready.
class Input < Hyperloop::Component
state value: ""
before_mount do
record.load(attribute).then do |value|
mutate.value value # this is nil and shouldn't be
end
end
render do
INPUT(
value: state.value
).on(:change) do |e|
mutate.value e.target.value
end.on(:blur) do
record.send :"#{attribute}=", state.value
end
end
def record; params.record; end
def attribute; params.attribute; end
end
In the below method preference
you can see the 2 ways of loading a Preference instance. The first way going through a relation triggers the bug. The second way loading Preference directly works fine above. It's just when going through the association that there's any issue.
class App < Hyperloop::Component
render do
Input(record: preference, attribute: :job_description)
end
def preference
Candidate.current.preference # leads to the nil bug
# Preference.find_by(candidate_id: Candidate.current.id) # works
end
end
Weirdly, even when value
is nil in the load
block (in the association case), entering this in the browser console correctly outputs the actual value without triggering a second server fetch.
Opal.Candidate.$current().$preference().$job_description()
So, even in the buggy case the value is still fetched correctly and assigned to the RR record as seen above. It can also be seen in the server fetching JSON returned, neatly nested under candidate as it should be. But inside the load
block it's nil, and it never shows up on screen in React.
If using Opal Hot Reloader, saving the file causes the file to be reloaded and the already loaded data is then correctly shown.
What we know:
- Non-relation fetch works fine
- Relation fetch data is correctly assigned to the RR as it's accessible in console
- Relation fetch data is not available in
load
- Relation fetch data is not available to React
- Relation fetch data is somewhere in the system as OHR kicks it into action
- A
puts
inside theload
block shows it does fire at the correct time only after the data is loaded