FieldedText TypeScript Library
    Preparing search index...

    Read Events Example

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

    1. Deserializes metadata from an XML string for a product list (Product, Quantity, Price)
    2. Sets up event callbacks on SerializationReader:
      • onRecordStarted - Fires when a new record begins
      • onFieldHeadingReady - Fires when heading is read
      • onFieldValueReady - Fires when each field value is ready
      • onRecordFinished - Fires when a record completes
    3. Reads CSV data while events track progress and calculate totals
    4. Displays statistics after reading completes
    npx tsx examples/read-events/index.ts
    
    Reading CSV with event callbacks:
    =================================
    [Event] Field 0 heading ready: "Product"
    [Event] Field 1 heading ready: "Quantity"
    [Event] Field 2 heading ready: "Price"

    [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

    =================================
    Statistics:
    Total records: 3
    Total fields: 9
    Total order value: $469.77
    • Event Callbacks: Hook into the reading process at specific points
    • Meta Deserialization: Load metadata from XML text with FtXmlMetaSerialization.deserialize()
    • Progress Tracking: Monitor record and field processing
    • Validation: Check field values as they're read
    • Statistics: Calculate running totals and metrics
    • Debugging: Event callbacks help debug parsing issues

    Events are useful for:

    • Progress reporting: Display progress for large files
    • Data validation: Validate field values immediately
    • Statistics: Calculate aggregates without storing all records
    • Logging: Record parsing activity for debugging
    • Conditional processing: Handle different record types differently
    // Read Events Example
    // Demonstrates using event callbacks during reading

    import {
    FtFieldHeadingReadyEventArgs,
    FtFieldValueReadyEventArgs,
    FtReader,
    FtXmlMetaSerialization,
    } from "@pbkware/fielded-text-web";

    // Sample CSV data
    const csvData = `Product,Quantity,Price
    Widget,10,19.99
    Gadget,5,29.99
    Doohickey,8,14.99`;

    // Load metadata from XML string
    const metaXml = `<?xml version="1.0" encoding="utf-8"?>
    <FieldedText HeadingLineCount="1">
    <Field Name="Product" />
    <Field DataType="Integer" Name="Quantity" />
    <Field DataType="Decimal" Name="Price" Format="C2" />
    </FieldedText>`;

    const meta = FtXmlMetaSerialization.deserialize(metaXml);

    // Create reader
    const reader = new FtReader(meta);

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

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

    reader.onFieldHeadingReadReady = (args: FtFieldHeadingReadyEventArgs) => {
    const heading = args.field.headings[args.lineIndex] || args.field.name;
    const fieldIndex = reader.fieldList.indexOf(args.field);
    console.log(`[Event] Field ${fieldIndex} heading ready: "${heading}"`);
    };

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

    // Calculate running total
    if (args.field.name === "Quantity" || args.field.name === "Price") {
    if (args.field.name === "Price") {
    const quantity = Number(reader.fieldList.get(1).asBigInt);
    const price = reader.fieldList.get(2).asDecimal;
    const lineTotal = quantity * price;
    totalValue += lineTotal;
    console.log(
    ` → Line total: ${quantity} × $${price.toFixed(2)} = $${lineTotal.toFixed(2)}`,
    );
    }
    }
    };

    reader.onRecordFinished = () => {
    console.log(`[Event] Record ${recordCount} finished\n`);
    };

    // Read the data
    console.log("Reading CSV with event callbacks:");
    console.log("=================================");

    reader.open(csvData);

    while (reader.read()) {
    // Processing happens in event callbacks
    }

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