title: How do you create an ajax service in ember-cli 3.17?
body: <p>I am recently trying to upgrade my ember from <code>ember-cli: 2.6.2</code> to <code>ember-cli: 3.17</code> and I am having a hard time trying to parallel my implementation of ajax service to the newer ember-cli version. I wasn't the one who created the app from the scratch that is why I do not know why the <code>import { raw } from 'ic-ajax';</code> is needed. Any help are very much appreciated.</p>
  
  <p>Error that I am getting: <code>Uncaught (in promise) TypeError: Cannot read property 'status' of undefined</code></p>
  
  <p>This is my old ajax service <code>app/services/ajax.js</code></p>
  
  <pre><code>import Ember from 'ember';
  import { raw } from 'ic-ajax';
  import dasherizeObjectKeys from '../../utils/dasherize-object-keys';
  
  const { inject, get, isEmpty } = Ember;
  
  export default Ember.Service.extend({
    currentSession: inject.service(),
  
    request(url, method = 'GET', data = undefined, dataType = 'json') {
      data = JSON.stringify(dasherizeObjectKeys(data));
      return new Ember.RSVP.Promise((resolve, reject) =&gt; {
        const contentType = 'application/json';
        const token = this.get('currentSession.token');
        const headers= {
          'Authorization': `Token ${token}`,
          'X-Client-Platform': 'Web'
        };
  
        raw({ url, headers, data, type: method, dataType, contentType })
          .then((response) =&gt; this.handleSuccess(response, resolve))
          .catch((response) =&gt; this.handleError(response, reject));
      });
    },
  
    handleSuccess(response, resolve) {
      return resolve({
        status: response.jqXHR.status,
        response: response.response
      });
    },
  
    handleError(response, reject) {
      if (response.jqXHR.status === 401 &amp;&amp; this.get('currentSession.isAuthenticated')) {
        this.get('currentSession').invalidate();
      }
  
      let error = get(response, 'jqXHR.responseJSON');
      if (isEmpty(error)) {
        const responseText = get(response, 'jqXHR.responseText');
        // FIXME: server should always return json, empty string is not json,
        // after backend is fixed, `JSON.parse` and try/catch for errors are not needed
        try {
          error = JSON.parse(responseText);
        } catch (e) {
          error = {
            errors: { detail: responseText }
          };
        }
      }
  
      error.status = response.jqXHR.status;
      reject(error);
    }
  });
  </code></pre>
  
  <p>And this is my new ajax service <code>app/services/request.js</code></p>
  
  <pre><code>import Service from '@ember/service';
  import { Promise } from 'rsvp';
  import fetch from 'fetch';
  import dasherizeObjectKeys from '../../utils/dasherize-object-keys';
  
  export default class RequestService extends Service {
    request(url, method = 'GET', data = undefined, dataType = 'json') {
      data = JSON.stringify(dasherizeObjectKeys(data));
      return new Promise((resolve, reject) =&gt; {
        const contentType = 'application/json';
        const token = this.get('currentSession.token');
        const headers= {
          'Authorization': `Token ${token}`,
          'X-Client-Platform': 'Web'
        };
  
        fetch({ url, headers, data, type: method, dataType, contentType })
          .then((raw) =&gt; this.handleSuccess(raw, resolve))
          .catch((raw) =&gt; this.handleError(raw, reject));
      })
    }
  
    handleSuccess(response, resolve) {
      return resolve({
        status: response.jqXHR.status,
        response: response.response
      });
    }
  
    handleError(response, reject) {
      if (response.jqXHR.status === 401 &amp;&amp; this.get('currentSession.isAuthenticated')) {
        this.get('currentSession').invalidate();
      }
  
      let error = get(response, 'jqXHR.responseJSON');
      if (isEmpty(error)) {
        const responseText = get(response, 'jqXHR.responseText');
        // FIXME: server should always return json, empty string is not json,
        // after backend is fixed, `JSON.parse` and try/catch for errors are not needed
        try {
          error = JSON.parse(responseText);
        } catch (e) {
          error = {
            errors: { detail: responseText }
          };
        }
      }
  
      error.status = response.jqXHR.status;
      reject(error);
    }
  }
  </code></pre>