Lesson 6
Code Page Here - PeoplePage_edit.htmlEdit Records with the Quickbase REST API
Select an existing People record, place its current values into an edit form, change those values, and send the updated record back to Quickbase.
Lesson Objective
Identify an Existing Record and Update It
Lesson 5 taught us how to create a new Quickbase record. Lesson 6 keeps the same REST endpoint and basic JSON record structure, but adds one crucial piece of information: the identity of the existing record we want Quickbase to update.
The Important Change
Record ID# Is No Longer Just Something We Display
We have displayed Record ID# since the beginning of the Developer Lab. In Lesson 5, Quickbase returned the new Record ID# after CREATE. Now that identifier becomes part of the request itself.
Lesson 5 — CREATE
{
6: { value: "Walter" },
7: { value: 44 },
8: { value: "Orange" }
}No Record ID# is supplied. Quickbase creates a new record and assigns one.
Lesson 6 — UPDATE
{
3: { value: 14 },
6: { value: "Walter" },
7: { value: 45 },
8: { value: "Orange" }
}Field ID 3 identifies the existing Quickbase record that should be updated.
Core Quickbase Concept
Same Endpoint. Same Basic Payload. Different Record Identity.
| Operation | Endpoint | Record ID# | Result |
|---|---|---|---|
| CREATE | POST /v1/records | Not supplied | Quickbase creates a new record. |
| UPDATE | POST /v1/records | Existing ID supplied | Quickbase updates that record. |
Lesson 6 Roadmap
Six Steps from Existing Record to Updated Record
This lesson builds the UPDATE workflow in six stages. The roadmap gives you the entire process before we examine each piece.
Add an Edit action
Give every displayed People record a way to begin the edit workflow.
Select the existing record
Capture its Record ID# and place the current values into the edit form.
Build the UPDATE payload
Include Field ID 3 so Quickbase knows which existing record is being targeted.
Send the UPDATE request
Submit the payload to the Quickbase REST records endpoint.
Read Quickbase's acknowledgment
Inspect metadata.updatedRecordIds to confirm which record changed.
Reload and verify
Read the People table again and display the authoritative updated values.
Add an Edit Action to Each Record
The existing People table already knows the Record ID#, Name, Age, and Favorite Color for every returned record. Lesson 6 adds an Edit button that carries those values into the edit workflow.
function createEditCell(
recordId,
name,
age,
favoriteColor,
) {
const cell = document.createElement("td");
const button = document.createElement("button");
button.type = "button";
button.textContent = "Edit";
button.className = "edit-button";
button.addEventListener("click", () => {
beginEditPerson(
recordId,
name,
age,
favoriteColor,
);
});
cell.appendChild(button);
return cell;
}During rendering, the same values already extracted from each Quickbase record are passed to the Edit button.
row.appendChild(
createEditCell(
recordId,
name,
age,
favoriteColor,
),
);Select the Existing Quickbase Record
Clicking Edit does not update Quickbase yet. It establishes which record the learner intends to edit and copies that record's current values into the form.
function beginEditPerson(
recordId,
name,
age,
favoriteColor,
) {
document.getElementById(
"editRecordId",
).value = recordId;
document.getElementById(
"editPersonName",
).value = name;
document.getElementById(
"editPersonAge",
).value = age;
document.getElementById(
"editPersonColor",
).value = favoriteColor;
const status =
document.getElementById("editStatus");
status.textContent =
`Editing Quickbase Record ID ${recordId}.`;
}The hidden Record ID# matters most.
The visible fields contain values the user may change. The hidden editRecordId preserves the identity of the Quickbase record being edited.
<input type="hidden" id="editRecordId" />
Keep the Stages Separate
Clicking Edit Does Not Change Quickbase
Click Edit
↓
Select existing record
↓
Copy current values into browser form
↓
User changes values
↓
Click Update Person
↓
Only now is an UPDATE request sentThis distinction is important. The first interaction prepares the browser. The second interaction changes Quickbase.
Build the UPDATE Payload
The UPDATE payload looks almost exactly like Lesson 5's CREATE payload. The important addition is Field ID 3.
function buildUpdatePersonPayload(
recordId,
name,
age,
favoriteColor,
) {
return {
to: TABLE_DBID,
data: [
{
[FIELD_IDS.recordId]: {
value: Number(recordId),
},
[FIELD_IDS.name]: {
value: name,
},
[FIELD_IDS.age]: {
value: Number(age),
},
[FIELD_IDS.favoriteColor]: {
value: favoriteColor,
},
},
],
};
}Payload Anatomy
{
to: TABLE_DBID,
data: [
{
3: { value: 14 }, // existing record
6: { value: "Walter" },
7: { value: 45 },
8: { value: "Orange" }
}
]
}Aha Moment
CREATE and UPDATE Are Two Outcomes of the Same Records Endpoint
Lesson 5 and Lesson 6 both send record data to POST /v1/records. The payload determines whether we are creating a new record or targeting one that already exists.
CREATE
POST /v1/records
6 → Walter
7 → 44
8 → Orange
↓
Quickbase creates
a new recordUPDATE
POST /v1/records
3 → 14
6 → Walter
7 → 45
8 → Orange
↓
Quickbase updates
Record ID 14Send the UPDATE Request
The edit form submission follows the same fundamental REST process we already learned: prevent normal form submission, get temporary authorization, build a JSON payload, and send it to Quickbase.
async function updatePerson(event) {
event.preventDefault();
const recordId =
document.getElementById(
"editRecordId",
).value;
const name =
document.getElementById(
"editPersonName",
).value.trim();
const age =
document.getElementById(
"editPersonAge",
).value;
const favoriteColor =
document.getElementById(
"editPersonColor",
).value.trim();
const temporaryToken =
await getTemporaryToken();
const payload =
buildUpdatePersonPayload(
recordId,
name,
age,
favoriteColor,
);
// Send payload to Quickbase...
}The actual API request uses the same endpoint introduced during CREATE:
const response = await fetch(
"https://api.quickbase.com/v1/records",
{
method: "POST",
headers: {
"QB-Realm-Hostname": REALM,
Authorization:
`QB-TEMP-TOKEN ${temporaryToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
},
);Read Quickbase's UPDATE Acknowledgment
Quickbase again answers the request with structured JSON metadata. This time the important property is updatedRecordIds.
const data = await response.json();
if (!response.ok) {
throw new Error(
`HTTP ${response.status}: ${JSON.stringify(data)}`,
);
}
const updatedRecordId =
data.metadata?.updatedRecordIds?.[0];The successful training response
metadata
├── createdRecordIds: []
├── totalNumberOfRecordsProcessed: 1
├── unchangedRecordIds: []
└── updatedRecordIds:
└── 14createdRecordIds: [] — no new record was created.
unchangedRecordIds: [] — the submitted record was not left unchanged.
updatedRecordIds: [14] — existing Record ID 14 was updated.
totalNumberOfRecordsProcessed: 1 — Quickbase processed one submitted record.
Request / Acknowledgment
Quickbase Tells Us What Kind of Write Occurred
JavaScript
│
│ UPDATE REQUEST
│ Record ID 14
▼
Quickbase
│
│ Finds existing record
│ Changes submitted values
▼
JSON Response
│
│ metadata.updatedRecordIds
▼
[14]This is stronger than simply receiving an HTTP success status. Quickbase's response describes the outcome of the record operation.
Reload the People Table and Verify the Change
Once Quickbase acknowledges the UPDATE, the form reports success, clears its values, and performs another READ so the table reflects the current Quickbase data.
status.textContent =
`Quickbase Record ID ${updatedRecordId} was updated successfully.`;
event.target.reset();
await loadPeople();The table is not manually patched with the edited values.
The page performs another READ from Quickbase. The updated table therefore reflects the data Quickbase currently stores.
Complete Flow
SELECT → EDIT → UPDATE → CONFIRM → READ → VERIFY
READ People records
↓
Render Edit button
↓
Click Edit
↓
beginEditPerson(...)
↓
Store Record ID#
↓
Populate current values
↓
Change values
↓
Submit edit form
↓
buildUpdatePersonPayload(...)
↓
Include Field ID 3
↓
POST /v1/records
↓
Quickbase updates existing record
↓
metadata.updatedRecordIds
↓
Show success message
↓
Reset edit form
↓
await loadPeople()
↓
POST /v1/records/query
↓
Render authoritative updated valuesConnect Lesson 5 and Lesson 6
The Metadata Reveals the Outcome
| Lesson | Operation | Response Metadata |
|---|---|---|
| Lesson 5 | CREATE | metadata.createdRecordIds |
| Lesson 6 | UPDATE | metadata.updatedRecordIds |
The endpoint remains the same, but Quickbase's acknowledgment explicitly tells us what happened to the submitted record.
A Debugging Lesson from the Lab
A Broken Page Does Not Always Mean the Quickbase Request Is Wrong
During the Lesson 6 build, an abandoned test line prevented JavaScript from reaching the normal page initialization. The Quickbase UPDATE architecture itself was correct.
That accidental failure reinforced an important debugging habit: when the table suddenly stops loading, first determine whether JavaScript reached the API call at all before changing working Quickbase code.
Lesson 6 Complete
You Can Now Update Existing Quickbase Records
You selected an existing record, preserved its Record ID#, populated an edit form, changed its field values, built an UPDATE payload, submitted it through the REST API, interpreted metadata.updatedRecordIds, and re-read the table to verify the result.
Next: Lesson 7 — Delete Records
CREATE and UPDATE are now working. Lesson 7 will use the identity of an existing People record again—but this time the operation removes it from Quickbase and completes the CRUD sequence.