SELECT Models

The real value of the FieldResolver is its' ability to create "views" or "models" which can be used in any query to ensure that you always pull consistent data for an object.

To do so, simply create a function that accepts a FieldResolver<T> and returns a string[]

const userModel = (userFields: FieldResolver<User>): string[] => {
    return userFields.select('address', 'aboutMe', 'email')
}

const accountModel = (accFields: FieldResolver<Account>): string[] => {
    return [
        ...accFields.select('accountNumber', 'active', 'billingCity'),
        ...userModel(accFields.parent('owner')),
        ...userModel(accFields.parent('lastModifiedBy'))
    ]
}

const contactModel = (contactFields: FieldResolver<Contact>): string[] => {
    return [
        ...contactFields.select('email', 'name'),
        ...accountModel(contactFields.parent('account')),
        ...userModel(contactFields.parent('owner')),
        ...userModel(contactFields.parent('lastModifiedBy')),
    ]
}

// See output in tab
let accountQuery = buildQuery(Account, cFields => (
    {
      select: accountModel(cFields),
      limit: 1
    }
));

let contactQuery = buildQuery(Contact, cFields => (
    {
      select: contactModel(cFields),
      limit: 1
    }
));

Recursive Models

In some cases you might need a model that SELECTS a parent of the same type. This can be done by adding an "termination condition" that checks the traversed array in the model function:

const contactViewRecursive = (contactFields: FieldResolver<Contact>): string[] => {
    if(contactFields.traversed.length == 5){
        return [];
    }
    return [
        ...contactFields.select('email', 'name'),
        ...contactViewRecursive(contactFields.parent('reportsTo'))
    ]
}
let qry = buildQuery(Contact, cFields => (
    {
      select: contactViewRecursive(cFields),
      limit: 1
    }
));

Last updated

Was this helpful?