How to implement findQuery?


#1

I am creating a custom adapter for Socket.io, and trying to implement findQuery.

  1. What should the JSON returned from the Server look like? I tried several approaches, without success

  2. Can I load relations in the same response? Or should they be loaded separately?

Thank you!


#2

Any ideas from my new found friends @jthoburn and @billybonks? :slight_smile:


#3

If you’re creating a custom adapter you can take the JSON returned from the server and massage it into something that works better with ember data.

EDIT: I’m not sure if your adapter is a extension of the RestAdapter or not but this should give you an idea of what the payload returned from your server should be massaged into: http://emberjs.com/guides/models/the-rest-adapter/


#4

Thanks @hooper, for taking the time to help! I am indeed extending RestAdapter.

The code I am using client side in my SocketAdapter is this (the makeSocketRequest was borrowed from @jthoburn). It works great for the find() and findAll() functions I have implemented. However I am struggling with findQuery().

findQuery: function (store, type, query) {
	var url = '/'+type.typeKey+'/find';
    return this.makeSocketRequest(store, url, {
        query : query
    });
},

makeSocketRequest : function (store, eventType, query) {
    var self = this;
    return new Ember.RSVP.Promise(function (resolve, reject) {
        try {
            self.socket.emit(eventType, query, function (data) {
                if (data.status) {
                	data.content = JSON.parse(data.content);
                    resolve(data.content);
                } else {
                    reject(data);
                }
            });
        } catch (e) {
            reject({ message : 'App.Socket is not available for requests'+e});
        }
    });

},

The JSON being returned from the server is this:

{"room":{"id":1,"url":"xx","name":"Lobby","messages":[]}} 

This throws the following error:

Error while processing route: room.index Assertion Failed: The response from a findQuery must be an Array, not {room: [object Object]} Error: Assertion Failed: The response from a findQuery must be an Array, not {room: [object Object]}

It obviously wants an array, but this is where I am stuck. I don’t know if the JSON should be formatted in another way (not clear from the link you sent) or if I should be doing something else in the adapter with the resulting JSON returned from the server.

Please point me in the right direction!


#5

findQuery assumes that the server will return possibly more than one result. If your response was {"rooms": [{"id":1,"url":"xx","name":"Lobby","messages":[]}]} then things would probably work. Does your endpoint only return one record?

EDIT: pluralized room


#6

If your endpoint always returns one record then what you could do is:

    self.socket.emit(eventType, query, function(data) {
        var ret;
        ret = { rooms: [data.room]  };
        resolve(ret);
    });

#7

@hooper the error I get now is

Error while processing route: room.index Assertion Failed: The response from a findQuery must be an Array, not {rooms: [object Object]} Error: Assertion Failed: The response from a findQuery must be an Array, not {rooms: [object Object]}

The incoming JSON from the server is now:

{"rooms":[{"id":1,"url":"xx","name":"Lobby","messages":[]}]} 

And after JSON.parse() it’s obviously

Object {rooms: Array[1]} 

Any ideas?


#8

Any input från @jthoburn and @billybonks?


#9

I’m not sure what the problem is, then. That JSON should work.


#10

@hooper it now seems to work! When I add the following to app.js

App.ApplicationSerializer = DS.ActiveModelSerializer;

#11

With my socket adapter I use the default rest serializer

App.ApplicationSerializer = DS.RESTSerializer;