I’m inserting a Glimmer component in topic-above-footer-buttons. This Glimmer component attempts to show some metadata about the topic. I am serializing these to topic.my_metadata
When the metadata is updated from a background job(!), the topic refreshes via MessageBus.publish("/topic/#{topic.id}", { reload_topic: true, refresh_stream: true })
Now this correctly updates in the template:
{{this.args.topic.my_metadata.status}}
However, when I access it via a getter
get statusMessage() {
return this.args.topic.my_metadata.status;
}
then
{{ this.statusMessage }}
does not update.
(And the same goes for all getters that I have that depend on this.args.topic.my_metadata in any way. Which is the actual problem).
What am I doing wrong?
I’ve already tried a lot, including defining custom events, copying topic.my_metadata to a @tracked metadata and then using this.metadata, etcetera.
Well, it’s not a matter of “better” or not, there is a lot of logic in Javascript evaluating the metadata and for instance deciding of a button should be shown, like
get showButton() {
// do some heavy stuff on this.args.topic.my_metadata.foo and this.args.topic.my_metadata.bar
}
so I need the getters and I need them to reevaluate somehow.
Additionally, the Glimmer documentation says args and its values are automatically tracked.
If the template is able to autotrack them, why can’t the getter?
Even this works, passing the metadata as an argument
This is an unfortunate part of us being midway-through converting from Ember’s ‘classic’ reactivity system (get/set/computed) to the ‘octane’ @tracked / native-getters.
So as discussed above, the problem with your example is that you’re accessing a non-@tracked property from a native getter.
Accessing the full path directly from a template will work, although as you say, it limits the logic available.
Alternatively, using .get() will allow Ember’s new autotracking system to work against classic (i.e. non-@tracked) properties.
So in this case, it would be
get statusMessage() {
return this.args.topic.get("my_metadata.status");
}
@computed is part of Ember’s classic reactivity system. It’s not officially deprecated, but we try to avoid adding it to new code.
If your getter is complicated enough to warrant caching, then you can use @cached:
import { cached } from "@glimmer/tracking";
...
@cached
get statusMessage() {
// this might be a lot more complicated
return this.args.topic.my_metadata.status;
}