tracked-tools / ember-could-get-used-to-this

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Update when argument changes

sandstrom opened this issue · comments

This isn't necessarily an issue with the code, could be a misunderstanding on my part as well.

I have a resource that doesn't seem to update then the argument route changes.

I've currently got it working using {{did-update …}} render modifiers, but that's a workaround.

Trying to understand if I've misunderstood how Resources are supposed to work?

But if the did-update modifier can pick up that the route has changed, I was thinking that the update hook would fire as well.

// helpers/geographic-map-resource.js

import { Resource } from 'ember-could-get-used-to-this';

export default class GeographicMapResource extends Resource {
  _instance = null;

  get value() {
    return this._instance;
  }

  setup() {
    let element = this.args.positional[0];
    let route = this.args.positional[1];

    // instantiate only if the map isn't already setup
    if (!this._instance) {
      this._renderMap(element);
    }

    // render map route
    this._updateRoute(route);
  }

  update() {
    let element = this.args.positional[0];
    let route = this.args.positional[1];

    // instantiate only if the map isn't already setup
    if (!this._instance) {
      this._renderMap(element);
    }

    // render map route
    this._updateRoute(route);
  }

  _renderMap(element) {
    this._instance = this._createMapFromThirdPartyLib(element);

    // …
  }
  
  _updateRoute(route) {
    // …
  }
}
// components/geographic-map.js
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { use } from 'ember-could-get-used-to-this';
import GeographicMapResource from 'client/helpers/geographic-map-resource';

export default class GeographicMapComponent extends Component {
  mapContainer = null;

  @use map = new GeographicMapResource(() => [this.mapContainer, this.args.route]);

  @action
  loadMap(element) {
    this.mapContainer = element;
    this.map; // instantiate
  }

  @action
  updateMap(_element) {
    // Resources are supposed to auto-update if any of their args changes, but that doesn't seem to be the case,
    // so we're using did-update to call this method, to trigger an update if route/markers change.
    if (this.args.route) {
      this.map; // trigger update
    }
  }
}
<!-- components/geographic-map.hbs -->
<div class='geographic-map-component'>
  <div {{did-insert this.loadMap}} {{did-update this.updateMap @route}}></div>
</div>

The code looks correct. However, I think for your use case, you probably want a custom modifier instead of a resource. It seems this resource is pretty much to deal with initializing a lib that requires an Element, which is what modifiers are designed for.

Talked with the library author and my mistake here is that the resource isn't actually, which is why it won't get recalculated automatically.

The forthcoming effects is what should be used here (instead of a resource).