Skip to content

itemMapProperties — GTM Variable Template for Items

VARIABLES › ITEMS
itemMapProperties CORE Items

Maps each item in an array to a new object with a fixed set of key/value pairs. Supports type conversion and default values.


When to Use This

GA4 Ecommerce

Build and transform ecommerce data structures for GA4 event tracking.

Type Conversion

Safely convert between data types — strings, numbers, booleans, arrays, objects.


Examples

Basic property mapping
INPUT
Input Array: [
{name: 'John', age: 30},
{name: 'Jane', age: 25}
]
Property Mapping:
[
{val: 'name', key: 'userName', typ: 'non', def: 'non'},
{val: 'age', key: 'userAge', typ: 'non', def: 'non'}
]
OUTPUT
[ {userName: 'John', userAge: 30}, {userName: 'Jane', userAge: 25} ]
With type conversion
INPUT
Input Array: [
{price: '10.7', quantity: '3', label: 42}
]
Property Mapping:
[
{val: 'price', key: 'price', typ: 'num', def: 'non'},
{val: 'quantity', key: 'quantity', typ: 'int', def: 'non'},
{val: 'label', key: 'label', typ: 'str', def: 'non'}
]
OUTPUT
[ {price: 10.7, quantity: 3, label: '42'} ]

GTM Configuration

This is what you'll see when you open this variable in Google Tag Manager. Hover the icons for details.

itemMapProperties
Input Array
💾 The array of objects to map.

Supported formats:
  ✓ Array of objects: {{ecommerce.items}}
Property Mapping
Source PropertyOutput KeyDefault (if falsy)Type Conversion
e.g. id
e.g. item_id
e.g. id
e.g. item_id
Advanced Settings
☑️ When enabled, properties not listed in the mapping table are preserved in the output object.
☑️ When enabled, the original property name is preserved alongside the renamed key in the output object.
Input Setup
Input Function (optional)
⚙️ Optional pre-processing function applied to the input array before internal logic (e.g., filter items, normalize values). Internal transformations will still apply afterward.
Result Handling
Output Function (optional)
⚙️ Optional function to apply to the result before returning it (e.g., arr => arr.filter(x => x.id), arr => arr.length). Useful for chaining transformations on the output.
Input Array array
💡 Type any text to see the result update live
🎯 Using special value — click input to type instead
Test with:
Falsy
Truthy
Property Mapping table
Source PropertyOutput KeyDefault (if falsy)Type Conversion
itemMapProperties()


Under the Hood

📜 View Implementation Code
/**
 * Maps each object in an array of objects to a new object with a fixed set of key/value pairs,
 * with optional type conversion and default values for missing or falsy properties.
 * Supports keeping unmapped properties and preserving original keys when renaming.
 *
 * @param {Array} data.src - Array of objects to map.
 * @param {Array<{val: string, key: string, typ: 'non'|'str'|'num'|'int', def: 'non'|'emp'|'zer'}>} data.map - Mapping table.
 * @param {boolean} [data.kup] - Keep unmapped properties from source object.
 * @param {boolean} [data.kor] - Keep original key when renaming.
 * @param {Function|string} [data.out] - Optional output handler.
 *
 * Direct-mode specific parameters:
 * @param {Function} [data.pre] - Optional pre-processor function to transform src before processing.
 *
 * @returns {Array} Array of new objects with mapped properties.
 * Note: falsy values (null, undefined, '', 0, false) trigger the default value if one is set.
 *
 * @framework ggLowCodeGTMKit
 */
const getType = require('getType');
const makeString = require('makeString');
const makeNumber = require('makeNumber');
const makeInteger = require('makeInteger');

const getDefault = function(defCode, originalValue) {
    if (defCode === 'emp') return '';
    if (defCode === 'zer') return 0;
    return originalValue; // 'non' — passthrough
};
const itemMapProperties = function(arr, mappings, keepUnmapped, keepOriginal) {
    return arr.map(function(item) {
        if (!item) return {};
        const obj = {};

        // build a map of source keys that are being renamed
        // to exclude them from unmapped copy if not keeping original
        const renamedKeys = {};
        mappings.forEach(function(pair) {
            if (pair.val && pair.key && pair.val !== pair.key) {
                renamedKeys[pair.val] = true;
            }
        });

        // copy unmapped properties first
        if (keepUnmapped) {
            const mappedSourceKeys = {};
            mappings.forEach(function(pair) {
                if (pair.val) mappedSourceKeys[pair.val] = true;
            });
            for (const k in item) {
                if (item.hasOwnProperty(k) && !mappedSourceKeys[k]) {
                    obj[k] = item[k];
                }
            }
            // if keeping original, also copy renamed source keys
            if (keepOriginal) {
                for (const k in renamedKeys) {
                    if (item.hasOwnProperty(k)) {
                        obj[k] = item[k];
                    }
                }
            }
        }

        // apply mappings
        mappings.forEach(function(pair) {
            var raw = item[pair.val];
            var value = raw ? raw : getDefault(pair.def, raw);
            if (pair.typ === 'str') value = makeString(value);
            else if (pair.typ === 'num') value = makeNumber(value);
            else if (pair.typ === 'int') value = makeInteger(value);
            obj[pair.key] = value;

            // k
🧪 View Test Scenarios (6 tests)
✅ '[example] Basic property mapping'
✅ Keep unmapped properties (kup)
✅ Keep original key when renaming (kor)
✅ Keep unmapped + keep original
✅ '[example] With type conversion'
✅ Falsy default (zer)