If an endpoint supports searching or custom inclusions via query parameters, these parameters
can be specified using a QueryBuilderType
. See FreshBooks API - Parameters
documentation.
type QueryBuilderType = PaginationQueryBuilder | IncludesQueryBuilder | SearchQueryBuilder
An appropriate method on the API client will support an array of builders:
public readonly invoices = {
list: (accountId: string, queryBuilders?: QueryBuilderType[]) => Promise<Result<{
invoices: Invoice[];
pages: Pagination;
}>>;
}
Pagination results are included in list
responses. The data
object will contain a pages
property, with the following:
{
page: number // The current page of results
pages: number // The number of pages of results
total: number // The total number of results
size: number // The number of results per page
}
To make a paginated call, first create a PaginationQueryBuilder
object set using the page
and perPage
functions
and pass it in the list
call.
import { PaginationQueryBuilder } from '@freshbooks/api/dist/models/builders/PaginationQueryBuilder'
const paginator = new PaginationQueryBuilder()
paginator.page(1).perPage(10)
let page = 1
let totalPages = 1
while (page <= totalPages) {
let response = await fbClient.clients.list(accountId, [paginator])
let { clients, pages } = response.data
console.log(clients)
console.log(`Page ${pages.page} of ${pages.pages} pages`)
console.log(`Showing ${pages.size} per page for ${pages.total} total clients`)
page++
totalPages = pages.pages
paginator.page(page)
console.log('Clients:')
clients.map((client) => console.log(client.organization))
}
To filter which results are return by list
method calls, construct a SearchQueryBuilder
and pass and pass it in
the list
call.
The SearchQueryBuilder
supports the patterns: equals
, in
, like
, between
, and boolean
.
s = SearchQueryBuilder()
s.in("email", "api@freshbooks.com")
console.log(s.build()) // "&search[email]=api@freshbooks.com"
s = SearchQueryBuilder()
s.in("clientids", [123, 456])
console.log(s.build()) // "&search[clientids][]=123&search[clientids][]=456"
s = SearchQueryBuilder()
s.like("email_like", "@freshbooks.com")
console.log(s.build()) // "&search[email_like]=@freshbooks.com"
s = SearchQueryBuilder()
s.between("amount", 1, 10)
console.log(s.build()) // "&search[amount_min]=1&search[amount_max]=10)"
s = SearchQueryBuilder()
s.between("start_date", date.today())
console.log(s.build()) // "&search[start_date]=2020-11-21"
s = SearchQueryBuilder()
// Boolean filters are mostly used on Project-like resources
s.boolean('complete', false) // "&complete=false"
Example API client call with SearchQueryBuilder
:
import { SearchQueryBuilder } from '@freshbooks/api/dist/models/builders/SearchQueryBuilder'
//create and populate SearchQueryBuilder
const searchQueryBuilder = new SearchQueryBuilder()
.like('address_like', '200 King Street')
.between('date', { min: new Date('2010-05-06'), max: new Date('2019-11-10') })
try {
// Get invoices matching search query
const { data } = await client.invoices.list(accountId, [searchQueryBuilder])
console.log('Invoices: ', data)
} catch ({ code, message }) {
// Handle error if API call failed
console.error(`Error fetching user: ${code} - ${message}`)
}
To include additional relationships, sub-resources, or data in a response an IncludesQueryBuilder
can be constructed
which can then be passed into list
, single
, create
, and update
calls.
Example API client call with IncludesQueryBuilder
:
import { IncludesQueryBuilder } from '@freshbooks/api/dist/models/builders/IncludesQueryBuilder'
//create and populate IncludesQueryBuilder
const includesQueryBuilder = new IncludesQueryBuilder().includes('lines')
console.log(includesQueryBuilder.build()) // "&include[]=lines"
try {
// Get invoices with included line items
const { data } = await client.invoices.list(accountId, [includesQueryBuilder])
console.log('Invoices: ', data)
} catch ({ code, message }) {
// Handle error if API call failed
console.error(`Error fetching user: ${code} - ${message}`)
}
Generated using TypeDoc