首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ember-cli 3.17中创建ajax服务?

如何在ember-cli 3.17中创建ajax服务?
EN

Stack Overflow用户
提问于 2020-04-13 23:19:06
回答 1查看 122关注 0票数 0

我最近正在尝试将我的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

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-14 18:35:37

当我从ic-ajax升级到fetch时,我使用了ember-fetch,它提供了来自ic-ajax的ajax的临时替代品

在此之前

代码语言:javascript
复制
var ajax = require('ic-ajax');

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

之后

代码语言:javascript
复制
import ajax from 'ember-fetch/ajax';

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

这让我走了很长一段路。但是,在从ajax切换到fetch时,仍然需要处理一些细微的语义变化。首先,error.jqXHR.responseJSON已不复存在。

之前:

代码语言:javascript
复制
if(error && error.jqXHR){
  var errorResponse = error.jqXHR.responseJSON || {};
  // do something with the errorResponse
}

之后:

代码语言:javascript
复制
if(error && typeof(error.json) === 'function'){
  return error.json().then((errorResponse) => {
    // do something with the error
  }
}

请注意,错误json是通过promise解决的,这很可能需要一些重构,因为ajax版本没有这样做。

正如您在上面的示例中看到的,jqXHR已不复存在。我假设你的状态问题是相似的。如果您想查看使用fetch的“ajax服务”示例,请参阅我的ember-rest-client插件。它是ember-fetch的一个非常简单的包装器,我使用它而不是使用ember data。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61191018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档