Modifiers - updating element based on service state

So I’ve been playing around with modifiers (specifically with ember-modifier) a bit recently and I had a case where I wanted a modifier placed on an element to add CSS class(es) to its element based on the value of some state in a service. A slightly simplified reproduction:

service (just stores a tracked prop):

export default class StatusService extends Service {
  @tracked thingStatus = 'success';

modifier (class based of course):

export default class StatusModifier extends Modifier {
  @service status;

  updateClass() {

  didReceiveArguments() {

This works really well, much better than a couple of the weirder things I tried first. My question is … why? I guess I don’t understand exactly why didReceiveArguments is called if a prop on an injected service is changed. It this expected and reliable? Or is there a better way to do something like this?

The ember-modifer README included this passage:

As with functional modifiers, the lifecycle hooks of class modifiers are tracked . When they run, they any values [sic] they access will be added to the modifier, and the modifier will update if any of those values change.

I think you may need to dig into the internals if you want to find out what allows this to happen.

As a tangent, it’d be good to create a POJO or Map to map this.status to a class name. To my understanding, string concatenations like some-${this.status.thingStatus}-class are difficult to analyze.

1 Like

Thanks @ijlee2, that’s kind of what I was thinking but unfortunately I haven’t had a ton of opportunity to play with autotracking yet :grin:. So I guess my issue was more the semantics, didReceiveArguments made me think it was only going to be triggered on arg updates but it’s really more like willUpdate or something because it’s not an arg that’s updating but a consumed tracked prop. Anyway that’s great and exactly what I wanted, just wanted to understand exactly why.

As to the string concat, that was just a contrived example and not something I’d actually write (hopefully :sweat_smile:) but I’m curious when you say “difficult to analyze” do you mean static analysis of “what css classes am i using?” e.g. purgecss or something else?

Yep, PurgeCSS was an example that I had in mind.

1 Like

This is a really great piece of feedback, with which I strongly agree. Would you be so kind as to open an issue on the ember-modifier repo with it? The history here is that the original API names were designed to reflect all the classic component hooks, even though that’s not really the most accurate mental model. This is exactly the thing we need to get nailed down as we iterate toward a version of ember-modifiers that can ship with Ember (see discussion starting here on the modifiers RFC).

1 Like

Sure thing, thanks @chriskrycho!

EDIT: issue here

1 Like