Write and Read Variables and Tables

This page uses the new zw. syntax. It will work starting with agent v1.1.72. If your agent is older, use the non-prefixed calls getRef() and setRef() instead of zw.getRef() and zw.setRef().

Read and write persistent values in variables and tables with zw.getRef() and zw.setRef().

API zw.getRef(), zw.setRef()

// Get a value from a table column or a variable
const profileName = await zw.getRef({ ref_id: 5079, name: "Profile Name" });

// Save a value to a table column or a variable
await zw.setRef({ ref_id: 4372, name: "Profile Name Copy", value: profileName });

At a Glance

  • await zw.getRef({ name: string, ref_id: number }) → returns the string value from a variable or table column.

  • await zw.setRef({ name: string, ref_id: number, value: string }) → saves a string value to a variable or table column.


What’s ref_id?

In ZeroWork, tables and variables are data groups. Each data group has an ID called ref_id.

  • Table ref_id is shown in the left sidebar next to the table name.

  • Variables ref_id is shown in the Variables dialog.

  • name identifies a table column or a variable in the Variables group. Names are case-sensitive.

    // Read a table column by its table ref_id and column name
    const profileName = await zw.getRef({ ref_id: 5079, name: "Profile Name" });
    
    // Same variables ref_id for different variable names
    const date = await zw.getRef({ ref_id: 4379, name: "date" });
    const counter = await zw.getRef({ ref_id: 4379, name: "counter" });


Saving Non-String Values

Values are stored as strings. To store arrays or objects, stringify on write and parse on read. Passing a non-string value to zw.setRef() throws an error.

// Save an array (stringify on write)
await zw.setRef({
  ref_id: 4379,
  name: "animals",
  value: JSON.stringify([{ category: "cat" }, { category: "dog" }]),
});

// Read and use it (parse on read)
const animalsArray = JSON.parse(
  await zw.getRef({ ref_id: 4379, name: "animals" })
);

Loops and Row Behavior

zw.getRef() and zw.setRef() follow ZeroWork’s loop logic:

  • Read existing rows → place Start Repeat with dynamic loop before your Write JavaScript building block.

  • Append new rows → place Start Repeat with standard loop before the block or use a custom append with appendIndex.

Read more about how loops work in ZeroWork: Start Repeat.

Custom append without Start Repeat

Use appendIndex to add rows from a loop in your code. appendIndex: 0 is the first appended row. If a table already has 3 rows, appendIndex: 0 becomes the 4th row.

Important. When using appendIndex, placing this Write JavaScript building block inside a Start Repeat loop might mix in-built loops with custom appendIndex and can cause mismatched rows.

const valuesToSave = ["a", "b", "c"];
const TABLE_REF_ID = 4382;

let i = 0;
for (const val of valuesToSave) {
  await zw.setRef({
    ref_id: TABLE_REF_ID,
    name: "value",
    value: val,
    appendIndex: i,
  });
  i++;
}

The resulting table:

Update existing rows in a custom code loop

Add a dynamic Start Repeat building block to iterate rows and use Write JavaScript block within that loop. As long as your Write JavaScript is inside that loop, it will have access to the values inside the row that is currently being iterated over. If you need true in-code row access, share your use case in Discord in the #ideas-feature-suggestions channel.


Common Pitfalls

  1. Always use await in the browser. Both methods are async in the browser context. Local execution (when “Run locally in the app” is enabled) is sync; await is unnecessary but harmless.

// 🚫 Won't work (running in the browser)
const name = zw.getRef({ ref_id: 5079, name: "Profile Name" }); // missing await → name is a Promise, not a string
await zw.setRef({ ref_id: 4379, name: "Copy", value: name }); // throws error
// Error: The value argument must be a string.

// ✅ Works
const name2 = await zw.getRef({ ref_id: 5079, name: "Profile Name" });
await zw.setRef({ ref_id: 4379, name: "Copy", value: name2 });

  1. Match the exact name (case-sensitive).

// 🚫 Won't work (case mismatch)
await zw.getRef({ ref_id: 5079, name: "profile name" });
// Error: This variable or column does not exist.

// ✅ Works
await zw.getRef({ ref_id: 5079, name: "Profile Name" });

  1. Use correct types. ref_id must be a number. name and value must be strings. For more details on value, see the Saving Non-String Values section above.

// 🚫 Won't work (value must be a string)
await zw.setRef({ ref_id: 4379, name: "chars", value: ["a", "b", "c"] });
// Error: The value argument must be a string.

// ✅ Works
await zw.setRef({ ref_id: 4379, name: "chars", value: "a, b, c" });

// ✅ Also works (stringify on write)
await zw.setRef({
  ref_id: 4379,
  name: "chars",
  value: JSON.stringify(["a", "b", "c"])
});

Last updated

Was this helpful?