Both are generic containers from the System Data toolkit for data whose structure is not known at design time:
- Map - a key / value dictionary (tw.object.Map): put(key, value), get(key), remove(key), containsKey(key), keys through keySet(); values are ANY (strings, numbers, business objects, lists). Use it for lookups by name (configuration, code tables, headers), for data whose field names change per call, and as the payload of generic services.
- Record - a business object without a fixed class whose properties are created on the fly: var r = new tw.object.Record(); r.customerName = "Ana"; r.total = 12; - it serialises like a normal business object (JSON with the property names), can be passed where ANY is expected, and is what the JSON-to-object helpers return for unknown structures. Use it for dynamic forms, generic REST responses, and case property bags (createCase takes a Record).
// Map: name -> value with typed access
var m = new tw.object.Map();
m.put("maxAmount", 5000); m.put("currency", "EUR");
if (m.containsKey("maxAmount") && tw.local.order.total > m.get("maxAmount")) tw.local.needsApproval = true;
// Record: dynamic object, property names decided at run time
var rec = new tw.object.Record();
var fields = JSON.parse(tw.local.json); // {"customerName":"Ana","score":710}
for (var k in fields) rec[k] = fields[k];
tw.local.dynamic = rec; // ANY variable; coaches can bind to rec.customerNameDifferences that matter: a Map is accessed through methods and iterated over its keys; a Record is accessed like any business object (rec.total) and can be bound to coach controls by path; Maps are not bindable to coaches directly. Both are slower and less safe than typed business objects - use ANY containers at the edges (integration in / out) and convert to typed objects as early as possible (question 159).
References