Ember-concurrency ajax-throttling example not working in my dev environment

Ok here’s what I found:

  • the biggest problem seems to be that on: 'init' doesn’t seem to work. This prevents the actual tasks (inner function) from ever being performed
  • tagName is extraneous and can be removed
  • this.set doesn’t work, iirc this.set and this.get APIs aren’t available on Glimmer components. Ember.set could still be used but it’s better to convert logs to autotracking and use other methods of updating it

Below is the code I ended up with that seems to work ok. I chose to add another task that initializes the other tasks (in lieu of a working on: 'init' task modifier. There’s probably a better or more elegant way of doing this, I just threw this in quickly to get it working.

import Component from '@glimmer/component';
import { enqueueTask, task, timeout } from 'ember-concurrency';
import { tracked } from '@glimmer/tracking';

function loopingAjaxTask(id, color) {
  return function* () {
    while (true) {
      this.log(color, `Task ${id}: making AJAX request`);
      yield this.ajaxTask.perform();
      this.log(color, `Task ${id}: Done, sleeping.`);
      yield timeout(2000);
    }
  };
}

export default class AjaxThrottlingExampleComponent extends Component {
  @tracked logs = [];

  constructor() {
    super(...arguments);
    this.startTasks.perform();
  }

  startTasks = task(async () => {
    // this is just to slightly delay the start of the tasks so it doesn't
    // double-modify this.logs in the initial render pass
    await timeout(50);
    this.task0.perform();
    this.task1.perform();
    this.task2.perform();
    this.task3.perform();
    this.task4.perform();
    this.task5.perform();
    this.task6.perform();
    this.task7.perform();
  });

  ajaxTask = enqueueTask({ maxConcurrency: 3 }, async () => {
    // simulate slow AJAX
    await timeout(2000 + 2000 * Math.random());
    return {};
  });

  @task({ on: 'init' }) task0 = loopingAjaxTask(0, '#0000FF');
  @task({ on: 'init' }) task1 = loopingAjaxTask(1, '#8A2BE2');
  @task({ on: 'init' }) task2 = loopingAjaxTask(2, '#A52A2A');
  @task({ on: 'init' }) task3 = loopingAjaxTask(3, '#DC143C');
  @task({ on: 'init' }) task4 = loopingAjaxTask(4, '#20B2AA');
  @task({ on: 'init' }) task5 = loopingAjaxTask(5, '#FF1493');
  @task({ on: 'init' }) task6 = loopingAjaxTask(6, '#228B22');
  @task({ on: 'init' }) task7 = loopingAjaxTask(7, '#DAA520');

  log(color, message) {
    this.logs = [...this.logs.slice(-6), { color, message }];
  }
}

EDIT: oh i see in the API docs that on applies only to @ember/component that on only applies to ember/component which totally makes sense, just means this example in the docs was even more in need of some love.

EDIT 2: and i guess the imports are hidden in the docs examples so while the code shows that they’re still using @ember/component (which would probably still work great with the code that’s in there) it doesn’t work for glimmer component. So TECHNICALLY the guides are still accurate, but they still rely on @ember/component and don’t seem to indicate that.

1 Like