BigRetroMike BigRetroMike - 16 days ago 5
Javascript Question

Ember.js linking application to real api after mirage success

As I'm going deeper and deeper into Ember.js application building process I hit another wall.

Before I was using mirage with great success - I just copy output from API that I wanted build around to mirage fixtures and it was working great.

Now I have problem with making it work with real API.

I first disabled mirage in config/environment.js

ember g adapter filter


import ApplicationAdapter from './application';
export default ApplicationAdapter.extend({
findAll: function(store, type, label) {
var url = `${this.host}/${this.namespace}/${type.modelName}`;
console.log(`${url}`);
return this.ajax(url, 'GET');
},
});


The application adapter looks like this

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
host: 'http://127.0.0.1:1234',
namespace: 'api',

headers: Ember.computed(function(){
return {"secret": "1234"};
})
});


And that way when I enter /filter
app/routes/filter/index


import Ember from 'ember';

export default Ember.Route.extend({
model() {
return this.store.findAll('filter');

}
});


I can see that url is build ok as
http://127.0.0.1:1234/api/filter
and there is no 404 but I get error

Error while processing route: filter.index The adapter operation was aborted EmberError@http://127.0.0.1:4200/assets/vendor.js:29616:15


and as I don't fully grasp the know-how of Ember Inspector im trying to figure this out somehow

My filter model that worked before (with mirage) looks like this:

import DS from 'ember-data';

export default DS.Model.extend({
name: DS.attr(),
url: DS.attr()
});


The api returns list
[{"id":1, "name": "namex", "url": "http://"},{"id":2, "name": "namey", "url": "http://"}]


I'm sure If its the way api return data as its not "filters" as I had problem with plurals before.

Edit: THIS RESOLVE THe problem

import DS from 'ember-data';

export default DS.RESTSerializer.extend(
{
normalizeFindAllResponse(store, type, payload)
{
var data = [];
payload.forEach(
function(item, index, enumerable)
{
var ob = {};
Ember.set(ob, 'id', item.id);
Ember.set(ob, 'type', 'filter');
Ember.set(ob, 'attributes', item);
data[index]=ob;
console.log(data[index]);
}
);
return {
data: data
};
}
});


This is almost the fix but not quite.
I can access some of model attributes like name, but there is a array object with 3 arrays inside, 2 of them are array the one in middle is Getter (what ever is that) and I cannot access it as its not array anymore. So im not sure if it binding to object correctly this way. Also I wasn't able to do anything with "data" because no matter what RESTAdapter here and there I put it would ignore it and ask for object with data/meta/errors attribute... dunno if its a bug or not.

Answer

As you are using JSONAPIAdapter your api response should follow the JSON format specification.

{      
  "data": [{
    "type": "filter",
    "id": "1",
    "attributes": {
      "name": "namex",
      "url": "http://"    
    }
  }, {
    "type": "filter",
    "id": "2",
    "attributes": {
      "name": "namey",
      "url": "http://"
    }
  }]
}

or if you are not following JSONAPI in that case either you can change application adapter to extend RESTAdapter.

import DS from 'ember-data';

export default DS.RESTAdapter.extend({
    host: 'http://127.0.0.1:1234',
    namespace: 'api',

    headers: Ember.computed(function(){
        return {"secret": "1234"};
    })
});

RESTAdapter response would be like,

{"filters":[{"id":1, "name": "namex", "url": "http://"},{"id":2, "name": "namey", "url": "http://"}]}

either you need to send it like above format or manipulate it to produce the required format.(override normalizeFindAllResponse)

Comments