js-composedb
js-composedb copied to clipboard
Allow for always true filter.
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.
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 });
}
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.