Skip to main content

Quick Setup

1

Install Angular CLI

npm install -g @angular/cli
2

Create New Angular Project

ng new <project-name>
3

Install OneSDK Package

npm install @frankieone/one-sdk

Webpack Configuration

1

Install Dependencies

npm install -D @angular-builders/custom-webpack file-loader style-loader css-loader @types/react
2

Update angular.json

Add custom Webpack configuration:
{
  "projects": {
    "<project-name>": {
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./webpack.config.js"
            }
          }
        },
        "serve": {
          "builder": "@angular-builders/custom-webpack:dev-server"
        }
      }
    }
  }
}
3

Create webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "assets/[name].[hash:8].[ext]",
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: [{ loader: "style-loader" }, { loader: "css-loader" }],
        exclude: /src/,
      },
    ],
  },
};

TypeScript Configuration

Update your tsconfig.json or tsconfig.app.json:
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "skipLibCheck": true
  }
}

Implementation

app.component.ts
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  async ngOnInit() {
    await this.initializeOneSdk();
  }

  private async initializeOneSdk() {
    const session = await this.getSessionToken();
    const oneSdk = await this.setupSDK(session);
    await this.configureSDK(oneSdk);
  }

  private async getSessionToken() {
    const config = {
      CUSTOMER_ID: '',
      CUSTOMER_CHILD_ID: '',
      API_KEY: ''
    };

    const response = await fetch(
      "https://backend.latest.frankiefinancial.io/auth/v2/machine-session",
      {
        method: "POST",
        headers: {
          authorization: "machine " + btoa([
            config.CUSTOMER_ID,
            config.CUSTOMER_CHILD_ID,
            config.API_KEY
          ].filter(Boolean).join(":")),
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          permissions: {
            preset: "one-sdk",
            reference: `demo-${new Date().toISOString()}`
          }
        })
      }
    );

    return response.json();
  }

  private async setupSDK(session: any) {
    return await OneSdk({
      session,
      recipe: {
        form: {
          provider: {
            name: 'react',
            googleApiKey: "YOUR_GOOGLE_API_KEY"
          },
        }
      }
    });
  }

  private async configureSDK(oneSdk: any) {
    // Setup event logging
    oneSdk.on('*', console.log);

    // Initialize individual flow
    const individual = oneSdk.individual();
    await this.setupConsent(individual);

    // Configure IDV flow
    await this.setupIDVFlow(oneSdk);
  }

  private async setupConsent(individual: any) {
    individual.addConsent("general");
    individual.addConsent("docs");
    individual.addConsent("creditheader");
    await individual.submit();
  }

  private async setupIDVFlow(oneSdk: any) {
    const component = oneSdk.component as unknown as (arg0: any, arg1?: any) => any;
    const flow = oneSdk.flow as unknown as (arg0: any) => any;

    const idv = flow("idv");
    const loading1 = component("form", {
      name: "LOADING",
      title: { label: "Loading..." },
      descriptions: [{ label: "" }]
    });

    const loading2 = component("form", {
      name: "LOADING",
      title: { label: "Processing results..." },
      descriptions: [{
        label: "Hold tight, this can take up to 30 seconds. Please don't refresh this page."
      }]
    });

    const review = component("form", {
      name: "REVIEW",
      type: "ocr"
    });

    this.setupIDVEventHandlers(idv, loading1, loading2, review);
    idv.mount("#e2e-idv-container");
  }

  private setupIDVEventHandlers(idv: any, loading1: any, loading2: any, review: any) {
    let before = true;

    idv.on("loading", (display: boolean) => {
      if (display && before) {
        loading1.mount("#e2e-idv-loading1");
      } else if (before) {
        loading1.unmount();
        before = false;
      }
    });

    idv.on("results", async ({ checkStatus }: { checkStatus: boolean }) => {
      if (checkStatus) {
        loading2.unmount();
        review.mount("#e2e-idv-container");
      }
    });

    idv.on("detection_complete", () => {
      loading2.mount("#e2e-idv-loading2");
    });

    // Error handling
    idv.on("error", ({ message, payload }: { message: string, payload: any }) => {
      console.error("IDV Error:", message, payload);
    });
  }
}

Running the Application

1

Start Development Server

npm run start
2

Access Application

Open your browser and navigate to http://localhost:4200
Security Note
Never store API keys or credentials in your frontend code. Use environment variables and a secure backend service to handle authentication.

Troubleshooting

  • Webpack Configuration Errors: Ensure all loaders are properly configured in webpack.config.js
  • TypeScript Errors: Verify tsconfig.json settings, especially allowSyntheticDefaultImports
  • Component Mounting Issues: Check if container IDs match in both component and template files
  • Use environment variables for API keys and endpoints
  • Implement proper error handling for API calls
  • Follow Angular’s lifecycle hooks for initialization
  • Implement proper cleanup in ngOnDestroy

Need Help?

If you encounter issues, check our sample code repository or reach out to our support team.