js-composedb icon indicating copy to clipboard operation
js-composedb copied to clipboard

Allow for always true filter.

Open nathanielc opened this issue 9 months ago • 2 comments

Description

I would like the ability to define a filter that always evaluates to true. This way I can dynamically construct the filter on the client dependent on the inputs to my query.

Technical Information

Given a model like:

type Pin
  @createModel(accountRelation: LIST, description: "A pin to a location")
  @createIndex(fields: [{ path: "tag" }]) {
  author: DID! @documentAccount
  name: String! @string(minLength: 1, maxLength: 100)
  description: String! @string(minLength: 1, maxLength: 300)
  tag: String! @string(minLength: 1, maxLength: 100)
  lat: Float! @float(min: -90, max: 90)
  lon: Float! @float(min: -180, max: 180)
}

I want to write a function that can load pins based on a provided tag or all pins if no tag is provided.

I currently need to implement this function this way, which create lots of duplication of the query string.

  async function loadPins(tag) {
    let pins = {};
    if (tag !== undefined) {
      const input = { where: { tag: { equalTo: tag } } };
      await compose.executeQuery(`
        query($input: PinFiltersInput) {
          pinIndex(first:100, filters: $input) {
            edges {
              node {
                id
                name
                description
                tag
                lat
                lon
                author { id }
              }
            }
          }
      }`, { input });
    } else {
      pins = await compose.executeQuery(`
      query() {
        pinIndex(first:100) {
          edges {
            node {
              id
              name
              description
              tag
              lat
              lon
              author { id }
            }
          }
        }
      }`);
    }
    return pins
  }

Instead I would prefer to implement the function in this way:

  async function loadPins(tag) {
    let input = { };
    if (tag !== undefined) {
      input = { where: { tag: { equalTo: tag } } }
    };
    const pins = await compose.executeQuery(`
    query($input: PinFiltersInput) {
      pinIndex(first:100, filters: $input) {
        edges {
          node {
            id
            name
            description
            tag
            lat
            lon
            author { id }
          }
        }
      }
    }`, { input });
    return pins
  }

However the second function gets error about the input value not being a valid PinFiltersInput object. I would be fine with an explicit value like {where: "true" } instead of just the empty object {}. Anything that makes it so its possible to define a filter that is always true.

nathanielc avatar Sep 27 '23 23:09 nathanielc

That seems like an unnecessary hack, couldn't you simply not initialize your input to an empty object? Ex:

  async function loadPins(tag) {
    const input = tag ? { where: { tag: { equalTo: tag } } } : undefined
    return await compose.executeQuery(`...`, { input });
  }

PaulLeCam avatar Sep 28 '23 08:09 PaulLeCam

I am pretty sure I tried that and it didn't work, but maybe I was sending null ? I was able to figure out a solution using in and an empty list, which worked better for my use case as I needed to use the in operator in either case.

nathanielc avatar Oct 02 '23 16:10 nathanielc