Search code examples
graphqlapollo

filtering in apollo giving a null value instead of expected return


I'm working on a project where I need to filter by the values of certain variables. I tried to follow a couple of examples on how to do this, but for some reason I'm getting null instead of the value that I was expecting.

schema.js

type User {
    _id: ID!
    email: String!
    firstName: String
    lastName: String
    lifeStyle: [LifeStyle]
    date: Date
  }

type LifeStyle {
  diet: [Diet]
  strick_diet: Boolean
}

 input UserFilters {
     strick_diet: Boolean
  }

  input UserFilterInput {
     filter: UserFilters 
  }

 type Query {
    filter(input: UserFilterInput):[User]
  }

user-resolvers.js

import User from '../../models/User.js';
import { requireAuth } from '../../services/auth.js';

export default {
  filter: async(parent, args, context, info) => {
    try {
      const { filter } = args;
      const shouldApplyFilters = filter !== null;
      let users = context.db.User;
   
      let lifeStylefilter = users.lifeStyle
  
      if (!shouldApplyFilters) {
        return users;
      }

      const shouldApplyStrickDietFilter = filter.strick_diet;


      if (shouldApplyStrickDietFilter) {
        users = lifeStylefilter.filter((a) => a.strick_diet === filter.strick_diet)
      }

      return {
        firstName: users.firstName,
      };
    }
  catch (error) {
    throw error;
  }
  },
};

In Apollo, I have:

query($input: UserFilterInput){
   filter(input: $input)  {
    firstName
  }
}

with variables:

{
  "input": {
    "filter": {
    "strick_diet": true
  }
  }
}

This is giving me:

{
  "data": {
    "filter": null
  }
}

Solution

  • Your query is defined to return an array [User] but you're just returning a single object (and not even a complete user object at that):

    return {
      firstName: users.firstName,
    };
    

    Instead do:

    return [users];
    

    But by the way, your resolver as written will only ever return a single user in that array. If it's your intent to eventually return multiple users you'll need to find multiple users and filter them all.

    let users = someQueryThatReturnsAnArrayOfUsers();
    if (!shouldApplyFilters) {
      return users;
    } else {
      return users.filter((user) => user.lifestyle.strick_diet === filter.strick_diet);
    }
    

    Finally note that if you are running this over a database you may find it faster to do the filtering in the database than in javascript afterwards.