If I would need to sort and filter some data, this previously looked like this:
sort = ['created:desc'];
@sort('inviteLinks', 'sort')
sortedLinks;
@filter('sortedLink', link => link.used != null)
displayedLinks;
(invitedLinks is the array containing all elements, sortedLinks are sorted and displayedLinks removes all items that should not be displayed)
I’d be reading in various places (like discord) that it often is recommended to no longer use these functions provided by ember (not going into details here, as I am no expert on that matter)
However, I was struggling with finding a replacement - and recently I have been recommended to use macro-decorators for such a purpose. Unfortunately I could not get them to work probably for this use case.
Yesterday, I just thought I might be not need those at all, if the required parts are properly @tracked
. And this turned out to be true. This is all I needed:
@tracked inviteLinks;
get activeLinks() {
return this.inviteLinks.filter((link) => link.used == null)
.sortBy('created')
.reverse();
}
Awesome. Not third party libs required, and this is a lot nicer to read.
Just sharing this in case anybody is struggling with similar things - and just kind of missing the obvious.
(though this might not currently update correctly if any of the dependent variables change during runtime - like the used or created field is updated - still need to check that - I think tracked only tracks the array and not it’s content)
1 Like
This is indeed great, and thanks for writing it up!
You’re right that if you need to track the array’s content, you’ll need to tweak how inviteLinks
gets set:
- you can use a “purely functional update” style, where you do
this.inviteLinks = this.inviteLInks.concat(someNewLink)
and similar
- you can use @pzuraq’s tracked-built-ins as long as you don’t need DIAF IE11 support
- you can use classic Ember Arrays, creating them with
A([])
and then using the key-value-observable functions like .pushObject
I would avoid the lattermost option unless you have to use it for a combination of performance and DIAF IE11 support; either of the first two options works very well.
1 Like
thanks for your reply. I am having a few troubles understanding your first suggestion, though. This would not account for cases where an attribute of an existing inviteLink is changed, right? Like, when I change an existing inviteLinks used
attribute, which would mean it should get filtered.
I barely remember that I came across one addon that would allow to track arrays and maps. likely it’s been one of these two GitHub - tracked-tools/tracked-built-ins: Tracked versions of JavaScript's built-in classes GitHub - tracked-tools/tracked-maps-and-sets: Autotracked Map, WeakMap, Set, and WeakSet (I haven’t yet had the time to look into it). Pretty much I would need a way to tell ember that if one of these two fields change, invalidate the array (or the things that depend on it - not sure what the right term is here)
Currently I am using an Ember Array to back the array (mostly because I thought this is what ember data currently returns - just checked and it looks like it still does)
I am using pushObject and removeObject though, because the inviteLinks are not modelled as a oneToMany of the parent entity, so ember data doesn’t notice any additions to the array (so I am managing it myself)
You’re correct that if the objects within the array are not tracked in some way, you won’t get updates in this filtering. The way around that is straightforward: track the properties on the class used to create those objects. If the source is Ember Data objects, those are already autotracked. If the source is otherwise outside of your control, you can (a) use TrackedObject
to deeply track the objects as you create the array or (b) continue to use Ember’s set
function to set the values.
Thanks a lot for the details. Everything updates indeed as needed without further modifications.
This will likely make things so much easier with the more complex components.
1 Like