Understanding Parameters and Return Values
What does .update() accept? What does it give you back? This chapter answers both questions — and shows how to use return values for chaining, error checking, and debugging.
Quick Start (30 Seconds)
// Single element: returns the element itself
const el = Elements.myButton.update({ disabled: true });
el.update({ textContent: 'Loading...' }); // Chain it!
// Bulk update: returns a results object
const results = Elements.update({
header: { textContent: 'Welcome' },
subTitle: { textContent: 'Get started' }
});
// Check if updates succeeded
if (results.header.success) {
console.log('Header updated!');
}What Is the Parameter?
.update() takes a single parameter: the update object.
element.update(updateObject);
// ^^^^^^^^^^^
// This is the only parameterThe update object is a plain JavaScript object whose keys describe what to change and whose values describe what to set. (For a full breakdown, see the previous chapter on the Update Object.)
What Counts as a Valid Parameter?
| Input | Valid? | Behavior |
|---|---|---|
{} | ✅ Yes | Valid no-op (does nothing) |
{ textContent: 'Hi' } | ✅ Yes | Applies update |
{ style: { color: 'red' } } | ✅ Yes | Applies nested update |
null | ⚠️ Warning | Logs warning, returns element |
'hello' | ⚠️ Warning | Logs warning, returns element |
42 | ⚠️ Warning | Logs warning, returns element |
undefined | ⚠️ Warning | Logs warning, returns element |
The method is forgiving: it never throws an error for bad input — it warns and returns gracefully.
Syntax
Form 1: Single Element (via Elements registry)
Elements.myElement.update(updateObject);
// Returns: the element itself (HTMLElement)Form 2: Bulk Update (via Elements.update)
Elements.update({
elementId1: updateObject1,
elementId2: updateObject2
});
// Returns: results object { elementId1: {...}, elementId2: {...} }Form 3: Collection (via Collections.update)
Collections.update({
collectionName1: updateObject1,
collectionName2: updateObject2
});
// Returns: results object { collectionName1: {...}, collectionName2: {...} }Form 4: Selector Results
Selector.query('.my-element').update(updateObject);
// Returns: the matched element (or null if no match)
Selector.queryAll('.my-items').update(updateObject);
// Returns: the collection of matched elementsWhy Does This Exist?
When Chaining Updates Is Your Priority
The single-element form returns the element itself, enabling clean method chaining:
Elements.modal.update({ style: { display: 'block' } })
.update({ classList: { add: 'open' } })
.update({ setAttribute: { 'aria-hidden': 'false' } });This approach is great when you need: ✅ Sequential updates where each step builds on the last ✅ Functional pipeline style ✅ To pass the element through utility functions
When Verification Is Your Goal
In scenarios where elements might be missing (dynamic UIs, SPAs, conditional rendering), the bulk update form provides a results object with success/failure info per element:
const results = Elements.update({
paymentForm: { style: { display: 'block' } },
cardInput: { value: '', disabled: false },
cvvInput: { value: '' }
});
if (!results.paymentForm.success) {
console.error('Payment form not found!');
showFallback();
}This approach is especially useful when: ✅ You need to know which elements were found and which weren't ✅ You're building critical UI flows where missing elements are serious ✅ You want to log or handle errors gracefully without throwing ✅ You're updating elements that might not yet be in the DOM
The Choice Is Yours:
- Use single-element form when you know the element exists
- Use bulk form when you need confirmation of success
- Both approaches return something useful — it's about what you need
Mental Model: The Vending Machine
Think of .update() like a vending machine:
You put in: You get out:
───────────── ────────────────────────────
Update object → Single element? → Element itself
→ Bulk update? → Dispensed items report
→ Bad input? → Warning + element (no crash)Single element is like getting your drink directly — you get back the thing you put in your money for, ready to use.
Bulk update is like getting a vending report — "Item A: dispensed ✅, Item B: out of stock ❌" — so you know exactly what happened.
How Does It Work?
Single Element Return
Elements.myButton.update({ disabled: true })
│
▼
┌─────────────────────────────────────┐
│ Process update object │
│ Apply each property/handler │
│ Change detection: skip if same │
└─────────────────────────────────────┘
│
▼
return element ←── The actual HTMLElement
│
▼
Elements.myButton.update({ disabled: true }).update({ textContent: '...' })
↑ chaining works because element is returnedBulk Update Return
Elements.update({ header: {...}, footer: {...} })
│
▼
┌─────────────────────────────────────────────┐
│ For each key in the bulk object: │
│ 1. Look up element by ID │
│ 2. If found: apply update, mark success │
│ 3. If not found: mark failure with error │
└─────────────────────────────────────────────┘
│
▼
{
header: {
success: true,
element: <HTMLElement>,
error: null
},
footer: {
success: false,
element: null,
error: 'Element not found: footer'
}
}The Return Values in Detail
Single Element Return Value
When you call .update() on an element directly, you get the element itself back:
const element = Elements.myButton.update({ textContent: 'Click me' });
// element === the actual HTMLElement
element instanceof HTMLElement; // true
element === Elements.myButton; // true
// So you can immediately call any DOM method
element.focus();
element.scrollIntoView();
// Or chain another update
element.update({ disabled: false });When the element doesn't exist:
const element = Elements.nonExistent.update({ textContent: 'Hi' });
// element: null (the element wasn't found)Always handle the null case for optional elements:
const el = Elements.optionalBanner?.update({ textContent: 'Welcome' });
if (el) {
el.focus();
}Bulk Update Return Value
When you call Elements.update({}) with an object (the bulk form), you get a results object:
const results = Elements.update({
header: { textContent: 'Hello' },
missing: { textContent: 'World' } // Doesn't exist in DOM
});
// results looks like:
{
header: {
success: true, // Was the element found & updated?
element: HTMLElement, // The actual element (or null)
error: null // Error message (or null)
},
missing: {
success: false,
element: null,
error: 'Element not found: missing'
}
}Results Object Properties
| Property | Type | Description |
|---|---|---|
success | boolean | true if element was found and update was applied |
element | HTMLElement | null | The found element, or null if not found |
error | string | null | Error description if success is false |
Deep Dive: Using Return Values Effectively
Pattern 1: Simple Chaining
The most common use of the return value:
// Chain sequential updates
Elements.myInput
.update({ value: '' })
.update({ disabled: false })
.update({ focus: [] });
// Or combine them (even better):
Elements.myInput.update({
value: '',
disabled: false,
focus: []
});Pattern 2: Storing the Element for Later
// Capture the element for repeated use
const button = Elements.submitBtn.update({
textContent: 'Submit',
disabled: false
});
// Use it multiple times
setTimeout(() => {
button.update({ disabled: true });
}, 3000);Pattern 3: Checking Critical Element Existence
async function showPaymentForm() {
const results = Elements.update({
paymentForm: { style: { display: 'block' } },
cardNumber: { value: '', disabled: false },
expiryDate: { value: '' },
cvvCode: { value: '' }
});
// Check all critical elements exist
const allFound = Object.values(results).every(r => r.success);
if (!allFound) {
const missing = Object.entries(results)
.filter(([, r]) => !r.success)
.map(([id]) => id);
console.error('Missing elements:', missing);
showErrorPage('Payment form unavailable');
return;
}
// Safe to proceed — all elements found
results.cardNumber.element.focus();
}Pattern 4: Partial Success Handling
const results = Elements.update({
primaryContent: { textContent: data.main },
secondaryContent: { textContent: data.secondary },
sidebar: { textContent: data.sidebar }
});
// Handle each result individually
if (!results.primaryContent.success) {
// This is critical — abort
throw new Error('Primary content area missing');
}
if (!results.secondaryContent.success) {
// This is optional — log and continue
console.warn('Secondary content not found, skipping');
}
if (!results.sidebar.success) {
// This is optional — use a fallback
console.info('Sidebar not available');
}Pattern 5: Logging for Debugging
const results = Elements.update({
header: { textContent: 'New Title' },
nav: { classList: { add: 'active' } },
footer: { textContent: 'Footer text' }
});
// Log all results
Object.entries(results).forEach(([id, result]) => {
if (result.success) {
console.log(`✅ Updated: ${id}`);
} else {
console.warn(`❌ Failed: ${id} — ${result.error}`);
}
});Pattern 6: Functional Pipeline
function applyLoadingState(elementId) {
return Elements[elementId].update({
disabled: true,
textContent: 'Loading...',
classList: { add: 'loading' }
});
// Returns the element — can be further processed
}
function applyReadyState(element) {
return element.update({
disabled: false,
textContent: 'Submit',
classList: { remove: 'loading' }
});
}
// Pipeline: applyLoadingState → wait → applyReadyState
const btn = applyLoadingState('submitBtn');
setTimeout(() => applyReadyState(btn), 2000);Deep Dive: Return Values in Collection Updates
When updating a collection (multiple elements sharing a class/group), the behavior differs:
// Update a collection of buttons — returns the collection itself
const buttons = Collections.allButtons.update({
disabled: true,
classList: { add: 'inactive' }
});
// buttons is the collection — you can chain collection methods
buttons.update({ textContent: 'Disabled' });Bulk collection updates (via Collections.update({})) also return a results object:
const results = Collections.update({
navLinks: { classList: { remove: 'active' } },
menuItems: { disabled: false }
});
// results.navLinks.success — was the collection found?
// results.navLinks.element — the collection (not a single element)Common Mistakes and How to Fix Them
Mistake 1: Ignoring Return Value for Chaining
// ❌ WRONG — can't chain after this
Elements.myBtn.update({ textContent: 'Hi' });
.update({ disabled: false }); // Error! No element returned to chain
// ✅ CORRECT — chain directly
Elements.myBtn
.update({ textContent: 'Hi' })
.update({ disabled: false });Mistake 2: Not Checking Results for Critical Elements
// ❌ WRONG — silent failure if element missing
Elements.update({
paymentForm: { style: { display: 'block' } }
});
// Continues even if paymentForm doesn't exist
// ✅ CORRECT — verify critical elements
const { paymentForm } = Elements.update({
paymentForm: { style: { display: 'block' } }
});
if (!paymentForm.success) {
throw new Error('Payment form not found');
}Mistake 3: Assuming Element Exists After Update
// ❌ WRONG — element might be null
const el = Elements.myElement.update({ textContent: 'Hi' });
el.focus(); // TypeError if el is null!
// ✅ CORRECT — guard against null
const el = Elements.myElement.update({ textContent: 'Hi' });
el?.focus(); // Optional chaining — safeMistake 4: Confusing Single vs Bulk Return
// ❌ WRONG — expecting bulk result from single update
const result = Elements.myButton.update({ disabled: true });
result.myButton.success; // TypeError! result is the HTMLElement
// ✅ CORRECT — use bulk form for results object
const results = Elements.update({
myButton: { disabled: true }
});
results.myButton.success; // Works!Quick Reference: Return Value Summary
Call form Returns
────────────────────────────────────────── ────────────────────────────────
Elements.myEl.update({...}) HTMLElement (or null)
Elements.update({ id1: {}, id2: {} }) { id1: {success, element, error} }
Collections.myCol.update({...}) Collection
Collections.update({ col1: {}, col2: {} }) { col1: {success, element, error} }
Selector.query('...').update({...}) HTMLElement (or null)
Selector.queryAll('...').update({...}) CollectionSummary
Understanding parameters and return values gives you full control over .update():
- One parameter: the update object (plain
{}) - Forgiving input: won't throw on bad input, logs warning
- Single element form returns the element itself — enabling chaining
- Bulk form returns a results object — enabling verification
- Results object has
{ success, element, error }per element ID - Null handling: elements not found return
nullfrom single form,success: falsefrom bulk - Chain pattern: use for sequential or functional-style updates
- Verification pattern: use for critical UI paths where element existence matters
What's Next?
Next chapter: Update Properties Deep Dive — a complete reference for every property category you can include in an update object.