簡體   English   中英

如何在 ember-cli 3.17 中創建 ajax 服務?

[英]How do you create an ajax service in ember-cli 3.17?

我最近嘗試將我的 ember 從ember-cli: 2.6.2升級到ember-cli: 3.17並且我很難嘗試將 ajax 服務的實現並行到更新的 ember-cli 版本。 我不是從頭開始創建應用程序的人,這就是為什么我不知道為什么import { raw } from 'ic-ajax'; 是需要的。 非常感謝任何幫助。

我得到的錯誤: Uncaught (in promise) TypeError: Cannot read property 'status' of undefined

這是我的舊 ajax 服務app/services/ajax.js

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) => {
      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) => this.handleSuccess(response, resolve))
        .catch((response) => this.handleError(response, reject));
    });
  },

  handleSuccess(response, resolve) {
    return resolve({
      status: response.jqXHR.status,
      response: response.response
    });
  },

  handleError(response, reject) {
    if (response.jqXHR.status === 401 && 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);
  }
});

這是我的新 ajax 服務app/services/request.js

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) => {
      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) => this.handleSuccess(raw, resolve))
        .catch((raw) => this.handleError(raw, reject));
    })
  }

  handleSuccess(response, resolve) {
    return resolve({
      status: response.jqXHR.status,
      response: response.response
    });
  }

  handleError(response, reject) {
    if (response.jqXHR.status === 401 && 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);
  }
}

當我從ic-ajax升級到fetch時,我使用了ember-fetch ,它為ic-ajax中的 ajax 提供了替代品:

var ajax = require('ic-ajax');

rsvpAjax: function (options) {
  return ajax.request(options.url, options);
}

import ajax from 'ember-fetch/ajax';

rsvpAjax: function (options) {
  return ajax(options.url, options);
}

這讓我大部分時間都在那里。 但是當從 ajax 切換到 fetch 時,仍然需要處理一些細微的語義變化。 一方面, error.jqXHR.responseJSON不再存在。

前:

if(error && error.jqXHR){
  var errorResponse = error.jqXHR.responseJSON || {};
  // do something with the errorResponse
}

后:

if(error && typeof(error.json) === 'function'){
  return error.json().then((errorResponse) => {
    // do something with the error
  }
}

請注意,錯誤 json 是通過 promise 解決的,這很可能需要一些重構,因為 ajax 版本沒有。

正如您在上面的示例中看到的, jqXHR不再存在。 我想你的狀態問題是相似的。 如果您想查看使用fetch的“ajax-service”示例,請參閱我的ember-rest-client插件。 這是一個超級簡單的ember-fetch包裝器,我使用它而不是使用 ember-data。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM