My question is two-fold:
Where is the best place to put some kind of polling logic - in the route file right?
How do I pass this constantly updating value from the Route to some child component? Labeling some variable as "@tracked
" and then passing the tracked variable via the model
hook?
Let's say I have something like this:
routes/index.js
export default class IndexRoute extends Route {
@tracked
recent: {
A: 0,
...
},
constructor() {
super(...arguments);
this.getRecent();
}
getRecent() {
// poll data / fetch latest
const {A, ...partialObject} = this.recent;
this.recent = { ...partialObject, A: <some new value fetched>};;
later(this, this.getRecent, 2000);
}
model() {
return this.recent;
}
}
application.hbs
<p>constantly updating "this.recent": {{ this.model.A }} </p>
I thought if I use the model hook like this, it would be tracked and therefore auto-update but that was not the case. I have this sample Ember Twiddle that emulates what I'm trying to do. I tried to force a re-compute by reassigning the entire variable but it didn't work.
This question is a deeper dive from my initial question here.
You are returning a reference to object stored in this.recent
in your model hook. But the getRecent
method does not change that object but overrides this.recent
. After the first execution of getRecent
method the model of the route and this.recent
aren't the same object anymore. The model of the route, which you can access through this.modelFor(this.routeName)
is the initial value and this.recent
is the new value.
You want to mutate the object returned from model hook instead.
The object given in your example has a fixed schema. This allows you to mark the property A
as tracked:
recent: {
@tracked A: 0,
...
}
As currently you return the value of this.recent
in your model hook. But instead of overwriting it in getRecent
method, you are only changing the value of it's property A
:
getRecent() {
this.recent.A = <some new value fetched>;
later(this, this.getRecent, 2000);
}
If you don't know the schema of the object returned in model hook or if you are dealing with an array, it's a little bit more complicated. You wouldn't have a property to decorate with @tracked
. I would recommend to use the tracked-built-ins
package in that case.
For arrays you can also fallback to legacy MutableArray
from @ember/array/mutable
package. But you must make sure in that case that you use it's custom methods to manipulate the array (e.g. pushObject
instead of push
).