From e6e2bdaf769c8d74b9ac965f1526fa1ff966cc2d Mon Sep 17 00:00:00 2001 From: Alex LaFroscia Date: Mon, 30 May 2016 17:22:13 -0700 Subject: [PATCH 1/5] Add empty content warning from Ember Data --- addon/mixins/ajax-request.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/addon/mixins/ajax-request.js b/addon/mixins/ajax-request.js index bf574c94..a1f17dba 100644 --- a/addon/mixins/ajax-request.js +++ b/addon/mixins/ajax-request.js @@ -34,8 +34,10 @@ const { isNone, merge, run, + runInDebug, Test, - testing + testing, + warn } = Ember; const JSONAPIContentType = 'application/vnd.api+json'; @@ -121,6 +123,14 @@ export default Mixin.create({ }; hash.error = (jqXHR, textStatus, errorThrown) => { + runInDebug(function() { + let message = `The server returned an empty string for ${requestData.type} ${url}, which cannot be parsed into a valid JSON. Return either null or {}.`; + let validJSONString = !(textStatus === 'parsererror' && jqXHR.responseText === ''); + warn(message, validJSONString, { + id: 'ds.adapter.returned-empty-string-as-JSON' + }); + }); + const payload = this.parseErrorResponse(jqXHR.responseText) || errorThrown; let response; From 77046c958599dd8b827601661c5ed4a07d2358ba Mon Sep 17 00:00:00 2001 From: Alex LaFroscia Date: Wed, 1 Jun 2016 15:17:34 -0700 Subject: [PATCH 2/5] Add mixin for ember-data integration --- addon/mixins/ajax-support.js | 28 ++++++++++++++ package.json | 1 + .../acceptance/ember-data-integration-test.js | 38 +++++++++++++++++++ tests/dummy/app/adapters/application.js | 8 ++++ tests/dummy/app/models/post.js | 6 +++ tests/dummy/app/router.js | 1 + tests/dummy/app/routes/ember-data-test.js | 7 ++++ tests/dummy/app/templates/ember-data-test.hbs | 1 + 8 files changed, 90 insertions(+) create mode 100644 addon/mixins/ajax-support.js create mode 100644 tests/acceptance/ember-data-integration-test.js create mode 100644 tests/dummy/app/adapters/application.js create mode 100644 tests/dummy/app/models/post.js create mode 100644 tests/dummy/app/routes/ember-data-test.js create mode 100644 tests/dummy/app/templates/ember-data-test.hbs diff --git a/addon/mixins/ajax-support.js b/addon/mixins/ajax-support.js new file mode 100644 index 00000000..78e5aabd --- /dev/null +++ b/addon/mixins/ajax-support.js @@ -0,0 +1,28 @@ +import Ember from 'ember'; + +const { + Mixin, + inject: { service }, + computed: { alias } +} = Ember; + +export default Mixin.create({ + + ajaxService: service('ajax'), + + host: alias('ajaxService.host'), + + namespace: alias('ajaxService.host'), + + headers: alias('ajaxService.headers'), + + ajax(url, type, options) { + options = this.ajaxOptions(...arguments); + return this.get('ajaxService').request(url, options); + }, + + ajaxOptions(url, type, options = {}) { + options.type = type; + return this.get('ajaxService').options(url, options); + } +}); diff --git a/package.json b/package.json index be398a1c..93ed1f46 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "ember-cli-release": "0.2.8", "ember-cli-sri": "^2.1.0", "ember-cli-uglify": "^1.2.0", + "ember-data": "^2.5.3", "ember-disable-prototype-extensions": "^1.1.0", "ember-disable-proxy-controllers": "^1.0.1", "ember-export-application-global": "^1.0.4", diff --git a/tests/acceptance/ember-data-integration-test.js b/tests/acceptance/ember-data-integration-test.js new file mode 100644 index 00000000..3348d67e --- /dev/null +++ b/tests/acceptance/ember-data-integration-test.js @@ -0,0 +1,38 @@ +import { test } from 'qunit'; +import moduleForAcceptance from '../../tests/helpers/module-for-acceptance'; + +import Pretender from 'pretender'; +import { jsonResponse } from 'dummy/tests/helpers/json'; + +let server; +moduleForAcceptance('Acceptance | ember data integration', { + beforeEach() { + server = new Pretender(); + }, + afterEach() { + server.shutdown(); + } +}); + +test('ember data adapter uses ember-ajax mixin', function(assert) { + assert.expect(2); + + server.get('api/posts/1', function() { + assert.ok(true, 'Used the ember-ajax integration'); + return jsonResponse(200, { + data: { + id: 1, + type: 'post', + attributes: { + title: 'Foo' + } + } + }); + }); + + visit('/ember-data-test'); + + andThen(function() { + assert.equal(currentURL(), '/ember-data-test'); + }); +}); diff --git a/tests/dummy/app/adapters/application.js b/tests/dummy/app/adapters/application.js new file mode 100644 index 00000000..e7006df3 --- /dev/null +++ b/tests/dummy/app/adapters/application.js @@ -0,0 +1,8 @@ +import DS from 'ember-data'; +import AjaxServiceSupport from 'ember-ajax/mixins/ajax-support'; + +const { JSONAPIAdapter } = DS; + +export default JSONAPIAdapter.extend(AjaxServiceSupport, { + namespace: 'api' +}); diff --git a/tests/dummy/app/models/post.js b/tests/dummy/app/models/post.js new file mode 100644 index 00000000..5801c409 --- /dev/null +++ b/tests/dummy/app/models/post.js @@ -0,0 +1,6 @@ +import Model from 'ember-data/model'; +import attr from 'ember-data/attr'; + +export default Model.extend({ + title: attr('string') +}); diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 3bba78eb..bcd5b843 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -6,6 +6,7 @@ const Router = Ember.Router.extend({ }); Router.map(function() { + this.route('ember-data-test'); }); export default Router; diff --git a/tests/dummy/app/routes/ember-data-test.js b/tests/dummy/app/routes/ember-data-test.js new file mode 100644 index 00000000..36961aa6 --- /dev/null +++ b/tests/dummy/app/routes/ember-data-test.js @@ -0,0 +1,7 @@ +import Ember from 'ember'; + +export default Ember.Route.extend({ + model() { + return this.store.find('post', 1); + } +}); diff --git a/tests/dummy/app/templates/ember-data-test.hbs b/tests/dummy/app/templates/ember-data-test.hbs new file mode 100644 index 00000000..c24cd689 --- /dev/null +++ b/tests/dummy/app/templates/ember-data-test.hbs @@ -0,0 +1 @@ +{{outlet}} From 8b79e63737ad1dbcd57e51da46fa03004a97e79b Mon Sep 17 00:00:00 2001 From: Alex LaFroscia Date: Sun, 5 Jun 2016 15:24:53 -0700 Subject: [PATCH 3/5] Add some documentation on Ember Data integration --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 14e39616..bae43375 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,32 @@ export default Ember.Route.extend({ If your errors aren't standard, the helper function for that error type can be used as the base to build your custom detection function. +## Usage with Ember Data + +Ember AJAX provides a mixin that can be used in an Ember Data Adapter to avoid the networking code provided by Ember Data and rely on Ember AJAX instead. This serves as a first step toward true integration of Ember AJAX into Ember Data. + +To use the mixin, you can include the mixin into an Adapter, like so: + +```javascript +// app/adapters/application.js +import Ember from 'ember'; +import DS from 'ember-data'; +import AjaxServiceSupport from 'ember-ajax/mixins/ajax-support'; + +const { + inject: { service } +} = Ember; +const { JSONAPIAdapter } = DS; + +export default JSONAPIAdapter.extend(AjaxServiceSupport, { + ajaxService: service('ajax'), + namespace: 'api' +}); +``` + +In the example, we import the mixin and include it in the `ApplicationAdapter` used by Ember Data. You could also include it in a model-specific adapter. By default, the `ajax` service is used, but you can also inject your own service subclass by overriding the `ajaxService` property. `namespace`, `host` and `headers` can be specified on either the service or adapter. + +Note that instead of using the Ember Data error checking code in your application, you should use the ones provided by Ember AJAX. ## Testing From c329758d2a7853ac9ad4d14ea3c7d4de13a9ea73 Mon Sep 17 00:00:00 2001 From: Alex LaFroscia Date: Sun, 5 Jun 2016 21:36:12 -0700 Subject: [PATCH 4/5] Fix typo in namespace alias --- addon/mixins/ajax-support.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/mixins/ajax-support.js b/addon/mixins/ajax-support.js index 78e5aabd..14259735 100644 --- a/addon/mixins/ajax-support.js +++ b/addon/mixins/ajax-support.js @@ -12,7 +12,7 @@ export default Mixin.create({ host: alias('ajaxService.host'), - namespace: alias('ajaxService.host'), + namespace: alias('ajaxService.namespace'), headers: alias('ajaxService.headers'), From b7ed4baf27c7618b74054861ba3f521e1d4edac7 Mon Sep 17 00:00:00 2001 From: Alex LaFroscia Date: Thu, 16 Jun 2016 18:33:41 -0700 Subject: [PATCH 5/5] Simplify the documentation on using EA in ED --- README.md | 13 ++----------- addon/mixins/ajax-support.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bae43375..d8d0c618 100644 --- a/README.md +++ b/README.md @@ -265,22 +265,13 @@ To use the mixin, you can include the mixin into an Adapter, like so: ```javascript // app/adapters/application.js -import Ember from 'ember'; import DS from 'ember-data'; import AjaxServiceSupport from 'ember-ajax/mixins/ajax-support'; -const { - inject: { service } -} = Ember; -const { JSONAPIAdapter } = DS; - -export default JSONAPIAdapter.extend(AjaxServiceSupport, { - ajaxService: service('ajax'), - namespace: 'api' -}); +export default DS.JSONAPIAdapter.extend(AjaxServiceSupport); ``` -In the example, we import the mixin and include it in the `ApplicationAdapter` used by Ember Data. You could also include it in a model-specific adapter. By default, the `ajax` service is used, but you can also inject your own service subclass by overriding the `ajaxService` property. `namespace`, `host` and `headers` can be specified on either the service or adapter. +That's all the configuration required! If you want to customize the adapter, such as using an alternative AJAX service (like one you extended yourself), hooks to do so are provided; check out the mixin's implementation for details. Note that instead of using the Ember Data error checking code in your application, you should use the ones provided by Ember AJAX. diff --git a/addon/mixins/ajax-support.js b/addon/mixins/ajax-support.js index 14259735..25f8e855 100644 --- a/addon/mixins/ajax-support.js +++ b/addon/mixins/ajax-support.js @@ -8,12 +8,30 @@ const { export default Mixin.create({ + /** + * The AJAX service to send requests through + * + * @property {AjaxService} ajaxService + * @public + */ ajaxService: service('ajax'), + /** + * @property {string} host + * @public + */ host: alias('ajaxService.host'), + /** + * @property {string} namespace + * @public + */ namespace: alias('ajaxService.namespace'), + /** + * @property {object} headers + * @public + */ headers: alias('ajaxService.headers'), ajax(url, type, options) {