> ## Documentation Index
> Fetch the complete documentation index at: https://docs.joyfill.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Populating and Extracting Data

This guide explains how to populate and extract data from JoyDoc, focusing on text fields and table fields.

## 1. Accessing Fields

You can access fields using `doc.fields`. The `fields` property contains an array of all field objects in the document.

```jsx theme={null}
// Access all fields
const allFields = doc.fields;

// Example field structure
{
  "_id": "name-field",
  "identifier": "name",
  "type": "text",
  "title": "Your Name",
  "value": "",
  "file": "file1"
}

```

## 2. Finding Fields

Fields can be found using their `fieldId` (which is the `_id` property of the field).

```jsx theme={null}
// Find a specific field by its ID
const findFieldById = (doc, fieldId) => {
  return doc.fields.find(field => field._id === fieldId);
};

// Example usage
const nameField = findFieldById(doc, "name-field");
console.log(nameField.title); // "Your Name"

```

## 3. Extracting Data for Non-Table Fields (Text)

At any moment, you can get the latest document from `JoyDoc.onChange` and extract text field values using the fieldId.

```jsx theme={null}
// In your JoyDoc component
<JoyDoc
  doc={doc}
  onChange={(changelog, updatedDoc) => {
    // Extract text field value
    const textField = updatedDoc.fields.find(
      (field) => field._id === "name-field"
    );
    const textValue = textField.value;
    console.log("Text field value:", textValue);
  }}
/>;
```

## 4. Populating Data

You can populate fields by injecting values into `doc.fields[].value`. Here's how to populate text fields:

```jsx theme={null}
// Populate text fields
const populateTextFields = (doc) => {
  const updatedDoc = { ...doc };
  const updatedFields = [...doc.fields];

  // Find and populate specific text fields
  const nameField = updatedFields.find(field => field._id === "name-field");
  if (nameField) {
    nameField.value = "John Doe";
  }

  const emailField = updatedFields.find(field => field._id === "email-field");
  if (emailField) {
    emailField.value = "john.doe@example.com";
  }

  updatedDoc.fields = updatedFields;
  return updatedDoc;
};

// Example usage
const populatedDoc = populateTextFields(doc);

```

## 5. Extracting Data for Table Fields

You can get a table field value by mapping through fields and accessing the table field's `value` using the table fieldId.

```jsx theme={null}
// Extract table field data
const extractTableData = (doc, tableFieldId) => {
  const tableField = doc.fields.find((field) => field._id === tableFieldId);

  if (tableField && tableField.type === "table") {
    return tableField.value.map((row) => {
      const rowData = {};
      // Extract data from each cell
      Object.keys(row.cells).forEach((columnId) => {
        const column = tableField.tableColumns.find(
          (col) => col._id === columnId
        );
        rowData[column.title] = row.cells[columnId];
      });
      return rowData;
    });
  }

  return [];
};

// Example usage
const tableData = extractTableData(doc, "68ef815e4c716f176ea8d2ba");
console.log("Table data:", tableData);
```

## 6. Populating Table Fields

You can populate table rows by updating the `value.cells` property. Here's how to populate table fields:

```jsx theme={null}
// Populate table fields
const populateTableFields = (doc, tableFieldId) => {
  const updatedDoc = { ...doc };
  const updatedFields = [...doc.fields];

  const tableField = updatedFields.find((field) => field._id === tableFieldId);

  if (tableField && tableField.type === "table") {
    // Create cells object with column data
    const cells = {};
    tableField.tableColumns.forEach((column) => {
      if (column.type === "text") {
        cells[column._id] = "Sample text data";
      } else if (column.type === "dropdown") {
        cells[column._id] = column.options[0]._id; // Select first option
      }
    });

    // Create new rows with populated cells
    const newRows = [
      {
        _id: "row1",
        deleted: false,
        cells: { ...cells },
      },
      {
        _id: "row2",
        deleted: false,
        cells: { ...cells },
      },
    ];

    tableField.value = newRows;
    tableField.rowOrder = ["row1", "row2"];
  }

  updatedDoc.fields = updatedFields;
  return updatedDoc;
};

// Example usage
const populatedTableDoc = populateTableFields(doc, "68ef815e4c716f176ea8d2ba");
```

## Complete Example

Here's a complete example showing both population and extraction:

```jsx theme={null}
import React, { useState } from "react";
import JoyDoc from "./JoyDoc";

const MyForm = () => {
  const [doc, setDoc] = useState(initialDoc);

  // Populate data function
  const populateData = () => {
    const updatedDoc = { ...doc };
    const updatedFields = [...doc.fields];

    // Populate text field
    const nameField = updatedFields.find((field) => field._id === "name-field");
    if (nameField) {
      nameField.value = "Jane Smith";
    }

    // Populate table field
    const tableField = updatedFields.find(
      (field) => field._id === "68ef815e4c716f176ea8d2ba"
    );
    if (tableField && tableField.type === "table") {
    
      const cells = {};
    
      tableField.tableColumns.forEach((column) => {
        if (column.type === "text") {
          cells[column._id] = "Table cell data";
        }
      });

      tableField.value = [{ _id: "row1", deleted: false, cells: { ...cells } }];
      tableField.rowOrder = ["row1"];
    }

    updatedDoc.fields = updatedFields;
    setDoc(updatedDoc);
  };

  // Extract data function
  const extractData = () => {
  
    // Extract text field
    const nameField = doc.fields.find((field) => field._id === "name-field");
    console.log("Name:", nameField?.value);

    // Extract table data
    const tableField = doc.fields.find(
      (field) => field._id === "68ef815e4c716f176ea8d2ba"
    );
    
    if (tableField && tableField.type === "table") {
    
      const tableData = tableField.value.map((row) => {
      
        const rowData = {};
       
        Object.keys(row.cells).forEach((columnId) => {
       
          const column = tableField.tableColumns.find(
            (col) => col._id === columnId
          );
       
          rowData[column.title] = row.cells[columnId];
       
        });
        return rowData;
        
      });
      console.log("Table data:", tableData);
    }
  };

  return (
    <div>
      <button onClick={populateData}>Populate Data</button>
      <button onClick={extractData}>Extract Data</button>

      <JoyDoc
        doc={doc}
        onChange={(changelog, updatedDoc) => {
          setDoc(updatedDoc);
        }}
      />
    </div>
  );
};
```

## Key Points to Remember

* **Field Access**: Use `doc.fields` to access all fields
* **Field Finding**: Use `field._id` to find specific fields
* **Text Fields**: Access value directly with `field.value`
* **Table Fields**: Access rows through `field.value` array, each row has `cells` object
* **Population**: Modify `field.value` for text fields, or `field.value[].cells` for table fields
* **Extraction**: Use `onChange` callback to get the latest document state
* **Immutable Updates**: Always create new objects when updating to avoid mutation issues
