Introduction
A FileMaker Data API client for NodeJS
easy-fm is a Node.js module that allows you to interact with
a FileMaker database stored on a FileMaker server
or FileMaker Cloud. This module interacts with your server using the
FileMaker Data API.
Contents
Installation
npm install @jd-data-limited/easy-fm --save
easy-fm also requires the following to be configured within your FileMaker enviroment:
- Enable the FileMaker Data API from the server's admin console. This setting is located
in
Connectors > FileMaker Data API
. - Create a FileMaker database account for easy-fm to use. This account must have the 'Access via FileMaker Data API (
fmrest)' extended privilege
Usage
Connecting to a database
import FMHost from "easy-fm";
const host = new FMHost("https://<your-servers-address>")
const database = host.database({
database: "your_database.fmp12",
credentials: {
method: "filemaker",
username: "<username>",
password: "<password>"
},
externalSources: []
})
database.login().then(() => {
})
NOTE: A connection will only give you access to the layouts in the database you are connected to, and not the
layouts
in
any external sources that you have specified.
If you need to interact with layouts on multiple databases, you need to open a separate connection for each.
An important note about timezones
Although it is recommended, timestamps in FileMaker databases are not always stored in UTC time. To account for this,
EasyFM allows you to specify a function/method that determines the server's current timezone.
EasyFM will use this timezone offset to convert timestamps to and from JavaScript Date objects.
import FMHost from "easy-fm";
import {type Moment} from 'moment'
const host = new FMHost("https://<your-servers-address>", (moment: Moment) => {
})
Getting records
One of (if not the) most common interactions you'll need to use is fetching records.
Fetch a range of records
let layout = database.getLayout("Your layout name")
let query = layout.records.list({
portals: {
test: {limit: 10, offset: 1}
},
limit: 10,
offset: 30
})
let records = await query.fetch()
console.log(records)
Searching for records
Searching for records uses the same syntax as above, but with additional steps to add your search parameters.
let layout = database.getLayout("Your layout name")
let query = layout.records.list({
portals: {
test: {limit: 10, offset: 1}
},
limit: 10,
offset: 30
})
query.addRequest({"GroupID": "=abc"})
let records = await query.fetch()
console.log(records)
Fetch a record using its record ID (NOT RECOMMENDED)
Please note: When in FileMaker Pro, a record's ID is returned when using Get(RecordID). If you need to fetch a record
using a different ID, use the search method above.
let layout = database.getLayout("Your layout name")
let record = await layout.records.get(164)
console.log(record)
Create a record
let layout = database.getLayout("Your layout name")
let record = await layout.records.create()
record.fields["Field1"].value = "Value here"
record.fields["Field2"].value = "Value here"
record.fields["Field3"].value = "Value here"
await record.commit()
Modify a record
let layout = database.getLayout("Your layout name")
let record = await layout.records.get(164)
record.fields["Field1"].value = "Value here"
record.fields["Field2"].value = "Value here"
record.fields["Field3"].value = "Value here"
await record.commit()
Field names
When interacting with FileMaker, it is important to remember how FileMaker field names work.
Field name format | Use when.... |
---|
FieldName | Use this when the field you are accessing is in the same table that the layout has been assigned to |
RelatedTableName::FieldName | Use this when the field is not in the same table that the layout has been assigned to |
NOTE: You will not be able to access any fields that are not on the layout.
Portal names
Please read this section carefully if you are working with portals
It is important to note that a portal's name is not the same as the name of the table that it links to. The name of
a
portal matches the object name it was assigned in FileMaker's layout editor.
NOTE: When no name has been manually assigned to it, it will default to the name of the related table.
Typescript Implementation
easy-fm
supports the use of TypeScript. Here's an example of how this works with easy-fm
:
import FMHost, {Portal, Field, Container} from "@jd-data-limited/easy-fm";
interface UsersLayout {
fields: {
first_name: Field<string>
age: Field<number>
birthdate: Field<Date>
profile_picture: Field<Container>
"MyRelatedTable::MyRelatedField": Field<string>
},
portals: {
Files: {
"Files::Field1": Field<string>
}
}
}
interface DatabaseStructure {
layouts: {
users: UsersLayout
}
}
const host = new FMHost("https://example_filemaker_server.com")
const database = host.database<DatabaseStructure>({
database: "ExampleDatabase.fmp12",
credentials: {method: "filemaker", username: "test", passsword: "test"},
externalSources: []
})
await database.login()
const layout = database.getLayout("users")
const record = await layout.records.create()
record.fields["first_name"].value = "Joe"
record.fields["age"].value = 38