jeudi 16 juin 2016

Unable to override handleResponse in Active Model Adapter

I'm trying to teach Ember to re-try a request if it gets a 202 accepted response header. This is my code (in ember/app/adapters/application.js).

import ActiveModelAdapter from 'active-model-adapter';

function AcceptedRetry() {
}

export default ActiveModelAdapter.extend({
  namespace: 'api',
  session: Ember.inject.service(),

  handleResponse(status) {
    console.log("never called");
    console.log(status);
    if (status === 202) {
      throw new AcceptedRetry();
    } else {
      return this._super.call(this, ...arguments);
    }
  },


  ajax(url, type, options) {
    let tries = 1;
    while (1) {
      let promise;
      try {
        if (tries < 3) {
          console.log("TRY " + tries.toString());
          tries++;
          promise = this._super.call(this, ...arguments);
        }
      } catch (e) {
        if (e instanceof AcceptedRetry) {
          console.log("caught exception");
          continue;
        } else {
          throw e;
        }
      }
      console.log("returning promise");
      return promise;
    }
  },

  headers: Ember.computed('session.csrfToken', function() {
    return {
      "X-CSRF-TOKEN": this.get('session.csrfToken')
    };
  })
});

The console.logs produce the following output:

TRY 1 returning promise

The overriden ajax method works fine, but when I call the superclass's ajax method, it seems to be hardcoded to call its own method rather than my overridden one.

I think I've located the offending lines of code in the Active Model Adapter's ajax method:

It has:

const adapter = this;

And then calls handleResponse with:

      let response = adapter.handleResponse(
        jqXHR.status,
        parseResponseHeaders(jqXHR.getAllResponseHeaders()),
        payload,                                                                                                                                                                    
        requestData
      );

So it seems adapter is bound to 'this', which means it's going to call its own class rather than my overridden method, but I thought that using:

this._super.call(this, ...arguments)

Should set 'this' to my own object. Any help would be greatly appreciated!




Aucun commentaire:

Enregistrer un commentaire