Skip to content

Iterating Over Settings

Shadowfen edited this page Jul 29, 2026 · 1 revision

LibSavedVars settings normally behave like regular Lua tables, allowing direct access to individual values.

Example:

local enabled = settings.enabled
settings.scale = 1.5

For simple settings access, direct table usage is recommended.

However, some addons need to process all available settings dynamically. Examples include:

  • Building configuration menus.
  • Exporting settings.
  • Debugging saved data.
  • Resetting settings.
  • Displaying current configuration.
  • Processing settings without knowing their names in advance.

LibSavedVars provides iteration support for these advanced scenarios.


Basic Table Iteration

For a normal saved variables object, Lua table iteration works as expected.

Example:

for key, value in pairs(settings) do
    d(key, value)
end

This iterates over values that are currently present in the table.

However, when using defaults, account-wide settings, character settings, or pinned settings, the stored table may not represent the complete active configuration.


Effective Settings vs. Stored Data

There are two different concepts when iterating:

Effective Settings

The values your addon sees after defaults and storage rules are applied.

Example:

settings.enabled

may return:

true

even if the value does not exist in SavedVariables because it comes from the defaults table.


Stored Data

The values that are physically saved.

Example:

{
    scale = 1.5
}

Only contains values explicitly stored by the user.

For raw data iteration, use:

local rawData = settings:GetRawDataTable()

for key, value in pairs(rawData) do
    d(key, value)
end

Iterating with LSV_Data

When using LSV_Data, settings may come from multiple sources:

              LSV_Data
                 |
        -------------------
        |                 |
 Account Settings   Character Settings
        |
 Pinned Account Keys

A normal table iteration cannot represent this combined view.

For this reason, LSV_Data provides:

data:GetIterator()

which returns an iterator over the active settings.


Using GetIterator()

Example:

for key, value in data:GetIterator() do
    d(key, value)
end

The iterator provides the effective settings view, including:

  • Active account-wide settings.
  • Active character settings.
  • Pinned account settings.

Your addon does not need to know where each value is stored.


Example: Building a Configuration Display

Suppose an addon wants to display all current settings:

for key, value in settings:GetIterator() do

    d(zo_strformat(
        "<<1>> = <<2>>",
        key,
        tostring(value)
    ))

end

The output represents the active configuration rather than only the underlying saved table.


Nested Settings

Iteration returns top-level keys.

Example:

local defaults = {
    window = {
        x = 100,
        y = 100,
    },

    display = {
        scale = 1.0,
    },
}

Iteration returns:

window = { ... }
display = { ... }

To process nested values, recursively iterate the returned table.

Example:

local function DumpTable(tbl, indent)

    indent = indent or ""

    for key, value in pairs(tbl) do

        if type(value) == "table" then
            d(indent .. key)

            DumpTable(
                value,
                indent .. "  "
            )
        else
            d(indent .. key .. " = " .. tostring(value))
        end

    end
end

Iteration and Pinned Settings

Pinned account settings are one of the main reasons to use LSV_Data:GetIterator().

Example:

settings:AddAccountWideToggle("window")
settings:AddAccountWideToggle("theme")

Active storage:

Account:
    window
    theme

Character:
    combat

The iterator returns:

window
theme
combat

even though those values come from different saved variable tables.


Iteration and Defaults

Depending on the iterator being used, values may include defaults.

If you need only explicitly stored values:

local raw = settings:GetRawDataTable()

for key, value in pairs(raw) do
    d(key, value)
end

If you need the values the addon currently uses:

for key, value in settings:GetIterator() do
    d(key, value)
end

Choose the iterator based on the purpose of your operation.


Common Uses

Configuration Menus

for setting, value in settings:GetIterator() do

    CreateOption(setting, value)

end

Debugging

for key, value in settings:GetIterator() do

    d(key .. ": " .. tostring(value))

end

Exporting Settings

local export = {}

for key, value in settings:GetIterator() do

    export[key] = value

end

Resetting Settings

Iteration can be used to process settings dynamically:

for key in settings:GetIterator() do

    settings[key] = nil

end

Use caution when resetting settings and consider restoring defaults instead.


Best Practices

When iterating over LibSavedVars settings:

  • Use direct access for normal addon operation.
  • Use GetIterator() when working with LSV_Data.
  • Use GetRawDataTable() when you need only stored values.
  • Do not assume missing values are errors.
  • Remember that defaults may provide values that are not stored.
  • Handle nested tables explicitly when required.

Summary

LibSavedVars supports several ways to iterate over settings depending on what your addon needs:

Method Returns Use Case
pairs(settings) Stored table values Simple saved variable objects
GetRawDataTable() Values actually saved Migrations, debugging, exports
GetIterator() Active effective settings LSV_Data, pinned settings, unified views

Understanding the difference between stored data and effective settings is essential when building advanced addon features.

Clone this wiki locally