FieldedText TypeScript Library
    Preparing search index...

    Write Events Example

    This example demonstrates how to use event callbacks during writing to validate data, track progress, and compute statistics.

    1. Creates metadata for a product list (Product, Quantity, Price)
    2. Sets up event callbacks on SerializationWriter:
      • onRecordStarted - Fires when starting to write a record
      • onFieldValueReady - Fires when each field value is set and ready to write
      • onRecordFinished - Fires when a record is completely written
    3. Writes CSV data while events validate values and calculate totals
    4. Displays warnings for invalid data (negative quantities/prices)
    5. Displays statistics and generated CSV output
    npx tsx examples/write-events/index.ts
    
    Writing CSV with event callbacks:
    =================================
    
    [Event] Record 1 started
    [Event] Field 0 (Product) value ready: Widget
    [Event] Field 1 (Quantity) value ready: 10
    [Event] Field 2 (Price) value ready: 19.99
      → Line total: 10 × 19.99 = 199.90
    [Event] Record 1 finished
    
    [Event] Record 2 started
    [Event] Field 0 (Product) value ready: Gadget
    [Event] Field 1 (Quantity) value ready: 5
    [Event] Field 2 (Price) value ready: 29.99
      → Line total: 5 × 29.99 = 149.95
    [Event] Record 2 finished
    
    [Event] Record 3 started
    [Event] Field 0 (Product) value ready: Doohickey
    [Event] Field 1 (Quantity) value ready: 8
    [Event] Field 2 (Price) value ready: 14.99
      → Line total: 8 × 14.99 = 119.92
    [Event] Record 3 finished
    
    [Event] Record 4 started
    [Event] Field 0 (Product) value ready: Thingamajig
    [Event] Field 1 (Quantity) value ready: -2
      ⚠ Warning: Negative quantity detected: -2
    [Event] Field 2 (Price) value ready: 9.99
      → Line total: -2 × 9.99 = -19.98
    [Event] Record 4 finished
    
    [Event] Record 5 started
    [Event] Field 0 (Product) value ready: Whatsit
    [Event] Field 1 (Quantity) value ready: 12
    [Event] Field 2 (Price) value ready: -5
      ⚠ Warning: Negative price detected: -5
      → Line total: 12 × -5.00 = -60.00
    [Event] Record 5 finished
    
    =================================
    Statistics:
      Total records written: 5
      Total fields written: 15
      Total order value: 389.79
    
    =================================
    Generated CSV:
    =================================
    Product,Quantity,Price
    Widget,10,19.99
    Gadget,5,29.99
    Doohickey,8,14.99
    Thingamajig,-2,9.99
    Whatsit,12,-5.00
    
    • Event Callbacks: Hook into the writing process at specific points
    • Data Validation: Check field values before they're written
    • Progress Tracking: Monitor writing progress
    • Statistics: Calculate running totals and metrics
    • Quality Assurance: Detect and log invalid data
    • NameConstant Heading Constraint: Demonstrates generating headings from field name

    Events are useful for:

    • Validation: Ensure data quality before writing
    • Progress reporting: Display progress for large exports
    • Logging: Record what data was written
    • Auditing: Track changes and data flow
    • Statistics: Calculate aggregates during export
    • Error detection: Identify data issues early
    // Write Events Example
    // Demonstrates using event callbacks during writing

    import {
    FtStringWriter,
    FtWriter,
    FtXmlMetaSerialization,
    } from "@pbkware/fielded-text-web";

    // Meta XML for writing data
    const metaXml = `<?xml version="1.0" encoding="utf-8"?>
    <FieldedText HeadingLineCount="1" HeadingConstraint="NameConstant">
    <Field Name="Product" />
    <Field DataType="Integer" Name="Quantity" />
    <Field DataType="Decimal" Name="Price" Format="N2" />
    </FieldedText>`;

    // Load metadata from XML
    const meta = FtXmlMetaSerialization.deserialize(metaXml);

    // Create writer
    const stringWriter = new FtStringWriter();
    const writer = new FtWriter(meta, stringWriter);

    // Track statistics
    let recordCount = 0;
    let fieldCount = 0;
    let totalValue = 0;

    // Set up event callbacks
    writer.onRecordStarted = (args) => {
    recordCount++;
    console.log(`[Event] Record ${args.recordIndex} started`);
    };

    writer.onFieldValueWriteReady = (args) => {
    fieldCount++;
    const fieldIndex = writer.fieldList.indexOf(args.field);
    console.log(
    `[Event] Field ${fieldIndex} (${args.field.name}) value ready: ${args.field.value}`,
    );

    // Validate data before writing
    if (args.field.name === "Quantity") {
    const quantity = Number(args.field.asBigInt);
    if (quantity < 0) {
    console.warn(` ⚠ Warning: Negative quantity detected: ${quantity}`);
    }
    }

    if (args.field.name === "Price") {
    const price = args.field.asDecimal;
    if (price < 0) {
    console.warn(` ⚠ Warning: Negative price detected: ${price}`);
    }

    // Calculate line total
    const quantity = Number(writer.fieldList.get(1).asBigInt);
    const lineTotal = quantity * price;
    totalValue += lineTotal;
    console.log(
    ` → Line total: ${quantity} × ${price.toFixed(2)} = ${lineTotal.toFixed(2)}`,
    );
    }
    };

    writer.onRecordFinished = (args) => {
    console.log(`[Event] Record ${args.recordIndex} finished`);
    };

    console.log("Writing CSV with event callbacks:");
    console.log("=================================\n");

    writer.writeHeader();

    // Write some products
    const products = [
    { product: "Widget", quantity: 10, price: 19.99 },
    { product: "Gadget", quantity: 5, price: 29.99 },
    { product: "Doohickey", quantity: 8, price: 14.99 },
    { product: "Thingamajig", quantity: -2, price: 9.99 }, // Invalid quantity!
    { product: "Whatsit", quantity: 12, price: -5.0 }, // Invalid price!
    ];

    for (const item of products) {
    console.log(); // Blank line between records
    writer.fieldList.get(0).asString = item.product;
    writer.fieldList.get(1).asBigInt = BigInt(item.quantity);
    writer.fieldList.get(2).asDecimal = item.price;
    writer.write();
    }

    // Print statistics and output
    console.log("\n=================================");
    console.log("Statistics:");
    console.log(` Total records written: ${recordCount}`);
    console.log(` Total fields written: ${fieldCount}`);
    console.log(` Total order value: ${totalValue.toFixed(2)}`);

    console.log("\n=================================");
    console.log("Generated CSV:");
    console.log("=================================");
    console.log(stringWriter.toString());