ember.jsember-dataember-cli-mirage

Error returning promise from Ember Data


I am working on my first Ember app and got it to display the way I wanted with the route returning a static JSON object from model():

element: {
  name: "First Element",
  divisions: [{
    name: "First Division",
    sets: [{name: "Set 1"},{name: "Set 2"},{name: "Set 3"}]
  }, {
    name: "Second Division",
    sets: [{name: "Set 1"},{name: "Set 2"},{name: "Set 3"}]
  }]
}

Now I am trying to refactor to use Ember Data + Mirage and having an awful time.

Here’s my index.js route

export default Ember.Route.extend({
    model() {
        return this.store.find('element', 1);
    },

If I set up my Mirage config.js like this:

  this.get('/elements', function() {
    return {
      elements: [
          {
            id: 1,
            name: 'First Element',
            divisions: [1, 2]
          }
      ]
    }
  });

then I get this error:

Your Ember app tried to GET '/elements/1', but there was no route defined to handle this request.

If I set up my Mirage config.js like this:

  this.get('/elements/1', function() {
    return {
       id: 1,
       name: 'First Element',
       divisions: [1, 2]
    }
  });

then I get this error:

22:46:40.883 "Error while processing route: index" "Assertion Failed: normalizeResponse must return a valid JSON API document:
    * One or more of the following keys must be present: "data", "errors", "meta"." "EmberError@http://localhost:4200/assets/vendor.js:25582:15

EDIT:

So this isn't a solution to the problem as stated but it got me past this. I gave up on Pretender and started again creating an actual Rails server according to this excellent tutorial: http://emberigniter.com/modern-bridge-ember-and-rails-5-with-json-api/

I was able to do everything I wanted this way and if I ever want to make this a production app, I'm a lot closer.


Solution

  • So the issue is that you aren't actually adhering to the JSON API specification. You can solve this by reading Mirage's page on how to conform.

    Essentially you need to either be returning an object at the top level of your JSON response in the case of a GET /foo/1 call. You'll also need to change your "elements" attribute to "data" for GET /foo and that should do the trick. Right now there isn't a simple, re-usable way to do this Mirage out of the box. The best bet right now for both issues is to use the solution presented in this issue.