1

I searched everywhere but can't seem to find an answer for this simple problem here on SO.

Problem:

I have a hasMany relationship in a model that is loaded by the route in a findAll(). Payload looks fin according to many answers I've seen here, but I get "TypeError: Cannot read property 'replace' of undefined". More details below.

How can I get this hasMany relationship to work? I'm using asynch:false and sending the sideload as recommended.

Using: Ember 2.1.0, Ember-Data 2.1.0.

Stacktrace:

TypeError: Cannot read property 'replace' of undefined
    at Object.func (ember.debug.js:36026)
    at Object.Cache.get (ember.debug.js:13165)
    at decamelize (ember.debug.js:36068)
    at Object.func (ember.debug.js:35974)
    at Object.Cache.get (ember.debug.js:13165)
    at Object.dasherize (ember.debug.js:36072)
    at ember$data$lib$system$normalize$model$name$$normalizeModelName (normalize-model-name.js:13)
    at ember$data$lib$serializers$json$serializer$$default.extend.modelNameFromPayloadKey (json-api-serializer.js:267)
    at ember$data$lib$serializers$json$serializer$$default.extend._extractType (json-api-serializer.js:258)
    at ember$data$lib$serializers$json$serializer$$default.extend.normalize (json-api-serializer.js:290)

Route:

app/routes/search.js

export default Ember.Route.extend({

    model(params) {
        if(params.query){
            return this.store.findAll('search-result');
        }
        return null;
    },

    actions:{
        sendSearch: function(queryString){
            this.store.unloadAll('search-result');
            this.refresh();
        }
    }

});

Models:

app/models/search-result.js

import DS from 'ember-data';

export default DS.Model.extend({

  title:        DS.attr('string'),
  description:  DS.attr('string'),
  url:          DS.attr('string'),
  tags:         DS.hasMany('search-result-tag', {async:false})

});

app/models/search-result-tag.js

import DS from 'ember-data';

export default DS.Model.extend({

  name: DS.attr('string'), 

});

Adapter (for search-result)

import DS from 'ember-data';

export default DS.RESTAdapter.extend({

    host: 'http://localhost:8080',
    urlForFindRecord(id, modelName, snapshot) {
        let url = this._super(...arguments);
        let query = Ember.get(snapshot, 'adapterOptions.query');
        if (query) {
            url += '?' + Ember.$.param(query); // assumes no query params are present already
        }
        return url;
    },
    urlForFindAll(modelName) {

        var queryDict = {};
        location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})

        let url = this._super(...arguments);
        let query = queryDict['query'];

        if (query) {
            url += '?query=' + query; // assumes no query params are present already
        }

        return url;
    }

});

Payload

{
  "search-result-tags": [
    {
      "name": "this-is-tag-#-0",
      "id": 0
    }
  ],
  "search-results": [
    {
      "description": "This is description for blabla2",
      "id": 0,
      "title": "Blabla 2",
      "url": "http://blablabla2.com",
      "tags": []
    },
    {
      "description": "This is description for blabla",
      "id": 1,
      "title": "Blabla",
      "url": "http://blabla.com",
      "tags": [
        0
      ]
    }
  ]
}
11
  • It looks like it's using the JSONAPISerializer. Have you set it to use the RESTSerializer? Commented Nov 12, 2015 at 14:55
  • I'll try. I need to create a RESTSerializer as search-result.js and just extend the default one, right? Commented Nov 12, 2015 at 15:25
  • You probably want your ApplicationSerializer to extend DS.RESTSerializer Commented Nov 12, 2015 at 15:32
  • emberjs.com/api/data/classes/DS.RESTSerializer.html, or if you're using Rails API - github.com/ember-data/active-model-adapter Commented Nov 12, 2015 at 15:43
  • 1
    yes, since your 3rd answer. please write an answer here and I'll accept it :) Commented Nov 12, 2015 at 19:41

1 Answer 1

2

You need to use the RESTSerializer in addition to the RESTAdapter. So app/serializers/application.js would be -

import DS from 'ember-data';

export default DS.RESTSerializer.extend({
});

See the docs. You may need to override keyForAttribute, if you need to change cases / underscores of your keys.

Note that if you are using Rails API for the backend you want ActiveModelAdapter and ActiveModelSerializer, which are available as an addon.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.