6
votes

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.

1
Your API response seems to be invalid for ember-data. Can you update your post with what your server sends? Ember-data expects data to be formatted as described here : guides.emberjs.com/v2.0.0/models/connecting-to-an-http-serverdynamic_cast
Can you show your router ? You are probably missing a routeQuantumLicht
What's going on here is that I have a single element (right now) which contains many divisions, each of which contain many sets. When I had this working with the static JSON object, I used {{#each in my .hbs template to list out each division, and within that division each set. So the model for my template is an element.ed94133
Do you use custom adapter or something? Also try removing divisions: [1, 2] from config.js and see if it eliminates error.Daniel Kmak
So, if you look here. The top level attribute in your Mirage response needs to be either: "data", "errors", or "meta". The first step is to wrap your "element(s)" attribute inside of a "data" attribute. That didn't solve the problem for me, but it's a logical first step.Derek Dowling

1 Answers

4
votes

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.