Search code examples
javascriptnode.jsfeathersjs

FeathersJs LEFT join another table (MongoDb)


I have a model for a service listings like

  price: { type: Number, required: true, min: 0, default: 0 },
  itemId: {
    type: mongooseClient.Schema.Types.ObjectId,
    ref: 'items',
    required: true,
  },

and with the after all hook I am doing a fastResolve with

joins: {
items: () => async (instance, context) => {
    if (instance && instance.itemId) {
      const item = await context.app
        .service('items')
        .get(instance.itemId);

      instance.item = item;
    }
    return context;

},

so in the end when I do a find for listings, I get the item object. And while I can easily query for fields like price (listings?price%5B%24lt%5D=5000)

How should I query for inner fields of item, like weight? (when doing a listings find)


Solution

  • you can directly pass a $populate query on the front end.

    for eg: ?$populate=itemId, here "itemId" is the data model's key which is referred to items model.

    If you want to populate in the backend, you can create a custom hook for that.

    // src/hooks/setDefaultQuery.js
    
    const setDefaultQuery = (fieldName, defaultValue) => (context) => {
      const { params } = context;
      const { query } = params;
    
      if (typeof query[fieldName] === 'undefined') context.params.query[fieldName] = defaultValue;
      return context;
    };
    
    module.exports = setDefaultQuery;
    

    on hooks, you can use the setDefaultQuery like this

    {
      before: {
        all: [authenticate('jwt')],
        find: [setDefaultQuery('$populate', "itemId")],
        get: [],
        create: [],
        update: [],
        patch: [],
        remove: [],
      },
    }
    

    For more about the querying please check the link bellow https://docs.feathersjs.com/api/databases/querying.html