npm package: @humancloudnetwork/hcn-schemas
Description: Reusable JSON schemas for validation
Author: Human Cloud Network
Latest version: 1.0.15


# HCN Schemas: Using Templates in React Applications

This guide demonstrates how to use the HCN Schemas `extractConstValues` utility and templates in a React application. Templates simplify the creation of credentials by predefining certain fields, while leaving others to be filled dynamically.

---

## Installation

Install the `@hcn/schemas` package in your React project:

```bash
npm install @hcn/schemas
```

---

## Importing Templates and Utilities

The `StudentCard` template provides a structure for creating student credentials. The `extractConstValues` utility helps prepopulate predefined fields from the schema.

### Example Import:

```javascript
import { extractConstValues } from "@hcn/schemas/utils";
import studentCardTemplate from "@hcn/schemas/schemas/credentials/templates/studentCard";
```

---

## Example Usage

### Step 1: Extract Predefined Values

Use `extractConstValues` to get the predefined fields from the template schema:

```javascript
const predefinedValues = extractConstValues(studentCardTemplate);

console.log(predefinedValues);
// Output:
// {
//   type: ["VerifiableCredential", "StudentCard"]
// }
```

### Step 2: Combine Predefined and User-Provided Data

Merge predefined values with user-provided data to create the final credential object. You can use a library like `lodash.merge` for deep merging.

```javascript
import merge from "lodash.merge";

const userValues = {
  credentialSubject: {
    educationalOrganisation: "Open University",
    program: "Computer Science",
    studentId: "STU56789",
    extraField: "Optional dynamic field",
  },
};

const finalCredential = merge({}, predefinedValues, userValues);

console.log(finalCredential);
// Output:
// {
//   type: ["VerifiableCredential", "StudentCard"],
//   credentialSubject: {
//     educationalOrganisation: "Open University",
//     program: "Computer Science",
//     studentId: "STU56789",
//     extraField: "Optional dynamic field"
//   }
// }
```

### Step 3: Validate the Credential

Use a JSON Schema validator like [AJV](https://ajv.js.org/) to ensure the final credential conforms to the template schema.

```javascript
import Ajv from "ajv";

const ajv = new Ajv({ allErrors: true });
const validate = ajv.compile(studentCardTemplate);

if (!validate(finalCredential)) {
  console.error("Validation failed:", validate.errors);
} else {
  console.log("Credential is valid:", finalCredential);
}
```

---

## Example React Component

Here’s how you can integrate the process into a React form component:

```javascript
import React, { useState } from "react";
import { extractConstValues } from "@hcn/schemas/utils";
import studentCardTemplate from "@hcn/schemas/schemas/credentials/templates/studentCard";
import merge from "lodash.merge";
import Ajv from "ajv";

const StudentCardForm = () => {
  const [formData, setFormData] = useState({
    educationalOrganisation: "",
    program: "",
    studentId: "",
  });

  const handleChange = (field, value) => {
    setFormData({ ...formData, [field]: value });
  };

  const handleSubmit = () => {
    const predefinedValues = extractConstValues(studentCardTemplate);
    const finalCredential = merge({}, predefinedValues, {
      credentialSubject: formData,
    });

    const ajv = new Ajv({ allErrors: true });
    const validate = ajv.compile(studentCardTemplate);

    if (!validate(finalCredential)) {
      console.error("Validation failed:", validate.errors);
      alert("Validation failed. Check console for details.");
    } else {
      console.log("Credential is valid:", finalCredential);
      alert("Credential created successfully!");
    }
  };

  return (
    <div>
      <h1>Create Student Card</h1>
      <label>
        Educational Organisation:
        <input
          type="text"
          value={formData.educationalOrganisation}
          onChange={(e) => handleChange("educationalOrganisation", e.target.value)}
        />
      </label>
      <br />
      <label>
        Program:
        <input
          type="text"
          value={formData.program}
          onChange={(e) => handleChange("program", e.target.value)}
        />
      </label>
      <br />
      <label>
        Student ID:
        <input
          type="text"
          value={formData.studentId}
          onChange={(e) => handleChange("studentId", e.target.value)}
        />
      </label>
      <br />
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
};

export default StudentCardForm;
```

---

## Key Features

1. **Predefined Values**:
   - Fields like `type` are automatically filled using the schema.
2. **Dynamic Fields**:
   - Additional user-provided data is seamlessly merged with predefined values.
3. **Validation**:
   - Ensure compliance with JSON Schema using AJV.

---

## Summary

Using templates and `extractConstValues` simplifies the creation of credentials while ensuring they are valid and adhere to the schema's requirements.