0

I have this code part, loading 3 AJAX requests and generate charts:

class IncidentStats {
  constructor($statsForm) {
    this.$statsForm = $statsForm;
    this.charts = [];

    this.$statsForm.on('submit', event => {
      event.preventDefault();
      this.renderCharts();
    });
  }

  prepareFormData(key) {
    const formData = this.$statsForm.serializeArray();

    formData.push({
      name: 'key',
      value: key,
    });

    return formData;
  }

  renderCharts() {
    Promise.all([
      this.renderGeneralStats(),
      this.renderServiceRepartitionStats(),
      this.renderServerRepartitionStats(),
    ]).then(() => console.log('TEST'));
  }

  // The two other methods does nearly the same thing.
  renderServiceRepartitionStats() {
    return new Promise(resolve => {
      $.post(this.$statsForm.attr('action'), this.prepareFormData('serviceRepartition'), data => {
        this.charts['incident-service-repartition-stats'] = this.createTop10Chart(
          $('#incident-service-repartition-stats'),
          'Alertes Nagios',
          data
        );
        resolve();
      }, 'json');
    });
  }
}

I use promise in order to do some stuff at the very end of the 3 charts loading, but want to keep the loading sync.

The console.log('TEST') on the then callback works at the first loading.

On second form submit, the charts are indeed reloaded but the then callback is never called.

I'm sure I'm missing something, but what? :-)

Thanks

Soullivaneuh
  • 3,553
  • 3
  • 37
  • 71
  • you miss [mcve]. – apple apple Sep 26 '18 at 14:31
  • 1
    add a catch block to Promise.all and check if it is getting triggered. – Shubham Gupta Sep 26 '18 at 14:31
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! See https://stackoverflow.com/a/31327725/1048572. – Bergi Sep 26 '18 at 14:41
  • @appleapple how would you like me to give a complete and verifiable example? without modify all the code (internal HTTP calls). – Soullivaneuh Sep 26 '18 at 14:43
  • @Soullivaneuh how would you like me to give an answer if I cannot run it at all? I don't even know whether your ajax works. – apple apple Sep 26 '18 at 14:45
  • @Bergi I'm not sure `$.post` would return a native `Promise`. So it's probably fine here. – apple apple Sep 26 '18 at 14:47
  • @appleapple Not a native one, but that's still no reason to use the antipattern (with the mistake of not handling errors anywhere). See the second link I posted. – Bergi Sep 26 '18 at 14:52
  • @Bergi can you `await` on non native `Promise` (and get the result value)? (I always use native one so I don't need to check.) – apple apple Sep 26 '18 at 14:57
  • @appleapple Yes you can. But if you want to be sure, just use `Promise.resolve(…)` on the non-native one. – Bergi Sep 26 '18 at 15:12
  • @Bergi happy to know that. But I think I'm not convinced yet to use non-native `Promise`. Would look for more resource. thanks anyway. – apple apple Sep 26 '18 at 15:52
  • @appleapple Well if you want to use `$.ajax` you *have* to use a non-native promise implementation... – Bergi Sep 26 '18 at 16:29
  • Using jQuery promise did solve the issue. – Soullivaneuh Sep 27 '18 at 08:49

1 Answers1

0

So I finally found the solution. Just do not create a new Promise when you are using jQuery ajax call. Just returns the call works because it's also a promise:

renderServiceRepartitionStats() {
  return $.post(this.$statsForm.attr('action'), this.prepareFormData('serviceRepartition'), data => {
    this.charts['incident-service-repartition-stats'] = this.createTop10Chart(
      $('#incident-service-repartition-stats'),
      'Alertes Nagios',
      data
    );
  }, 'json');
}

I understand using new Promise is overkill here, but I don't know why this was causing my issue... Maybe someone can add some details here.

Soullivaneuh
  • 3,553
  • 3
  • 37
  • 71