falcondatabase
Sign in

← Blog

Tutorial · 2 min read · kevin

Tutorial: query your tables with the JavaScript SDK

Filter, sort, paginate and write data from any web page with falcondb.js, a single file with no dependencies.

falcondb.js is a tiny ES module served by your own falcondatabase server. There is nothing to install and no build step: import it from a <script type="module"> and start querying.

Create the client

<script type="module">
  import { createClient } from "http://falcondatabase.com/sdk/falcondb.js"

  const db = createClient("http://falcondatabase.com", "PROJECT_REF", "ANON_KEY")
</script>

Use the anon key in the browser. It is public by design: what it can do is limited by the access rule of each table.

Read rows

db.from(table) returns a query builder. Chain filters and await it:

const { data, count, error } = await db.from("products")
  .select("id,name,price")      // optional: only these columns
  .gte("price", 10)             // price >= 10
  .ilike("name", "%coffee%")    // case-insensitive pattern
  .order("price", { desc: true })
  .limit(20)
Method SQL
eq(col, v) / neq(col, v) = / <>
gt, gte, lt, lte >, >=, <, <=
like(col, p) / ilike(col, p) LIKE / ILIKE (% is the wildcard)
is(col, "null") IS NULL (also true / false)
in(col, ["a", "b"]) IN ('a', 'b')

count is the total number of matching rows, perfect for pagination.

Paginate

const page = 2, size = 20
const { data, count } = await db.from("products")
  .order("id")
  .range((page - 1) * size, page * size - 1)

const pages = Math.ceil(count / size)

range(from, to) is a shortcut for offset(from).limit(to - from + 1).

Get a single row

const { data: product } = await db.from("products").get(7)          // by id
const { data: first } = await db.from("products").eq("name", "Tea").single()  // first match or null

Write data

await db.from("products").insert({ name: "Croissant", price: 2.2 })
await db.from("products").insert([{ name: "A" }, { name: "B" }])  // several rows, all or nothing
await db.from("products").update(7, { price: 3 })
await db.from("products").delete(7)

Writes respect the table's access rule. With Public read, for example, inserting requires a signed-in user (see the to-do app tutorial).

Handle errors

The SDK never throws for API errors. Every call resolves to { data, error }:

const { data, error } = await db.from("products").insert({ price: "cheap" })
if (error) {
  console.error(error.status, error.message)   // 400 invalid input syntax for type numeric...
}

Error messages follow the browser language (English or Spanish).

Discover the schema

const { data } = await db.schema()
console.log(data.tables)   // tables visible with your key, with their columns and types

That's all you need for most apps. Next: build a to-do app where each user only sees their own tasks.