Search code examples
feathersjsfeathers-sequelizefeathers-hook

Using feathers-client and sequelize many-to-many relation


I'm trying to get data from an n:m association using feathers. I'm using react for my front-end and connecting to feathers using the feathers-client and socketio.

    //connection string where the feathers api is running
const host = 'http://localhost:3030';


const socket = io(host, {
    transports: ['websocket'],
    forceNew: true
});

// construct feathers app
export const client = feathers()
    .configure(hooks())
    .configure(auth({ storage: window.localStorage }))
    .configure(socketio(socket));

But when I use the myService.find() the include param gets removed from the hook.params

function (hook) {
        hook.params.sequelize = {
          include: [{ model: hook.app.services.users.Model,
                      as: 'teamOwner'
                      },{
                      model: hook.app.services.users.Model,
                      as: 'Trainer'
                      },{
                      model: hook.app.services.users.Model,
                      as: 'Member'
            }
          ]
        };
      return Promise.resolve(hook);
    }

When I configure it in my before hook it works fine, but then every time the service us used all the tables are joined together. So I want to specify in the query which tables to include. Like this

client.service('team').find({
                include: [
                { model:client.service('users').Model,
                    as: 'teamOwner'
                },{
                    model:client.service('users').Model,
                    as: 'Trainer'
                },{
                    model:client.service('users').Model,
                    as: 'Member'
                }],
                query: {
                    $sort: {
                        id: 1
                    }
                }
            })

Thanks in advance


Solution

  • Since only params.query is passed between the client and the server the best way is usually to create a custom query parameter that indicates what you want to include:

    function (hook) {
      const { $include } = hook.params.query;
    
      // Remove from the query so that it doesn't get included
      // in the actual database query
      delete hook.params.query.$include;
    
      const sequelize = {
        include: []
      };
    
      if(Array.isArray($include)) {
        $include.forEach(name => {
          sequelize.include.push({
            model: hook.app.services.users.Model,
            as: name
          });
        });
      }
      return Promise.resolve(hook);
    }
    

    Now the client can indicate what they want in the query, e.g. { query: { $include: [ 'teamOwner', 'Trainer' ] } }