<!DOCTYPE html>

<html>
  <head>
    <script src="./lib/main.ts"></script>
  </head>

  <body>
    <my-app></my-app>
  </body>
</html>
//our root app component
import { Component, NgModule, VERSION } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  template: `
    <div>
      {{ data.title }}
      <div *ngFor="let item of data.items">
        {{ item.title }}
        <input
          class="input-field"
          type="text"
        />
      </div>
    </div>
  `,
})
export class App {
  name: string;
  data: any;
  formSchema: any = {
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "http://example.com/example.json",
    "type": "object",
    "title": "Form Title",
    "properties": {
      "form_item_1": {
        "type": "integer",
        "title": "Form Item 1",
        "description": "This is an integer Required",
      },
      "form_item_2": {
        "type": "integer",
        "title": "Form Item 2",
        "description": "This is thing",
        "properties": {
          "nested1": {
            "type": "string",
            "title": "Nested 1",
            "description": "Nested desc 1",
            "properties": {
              "nested 2": {
                "type": "string",
                "title": "Nested 2",
                "description": "Nested desc 2",
                "properties": {
                  "nested 3": {
                    "type": "string",
                    "title": "Nested 3",
                    "description": "Nested desc 3"
                  }
                }
              }
            }
          }
        }
      }
    }
  };
  
  constructor() {
    this.name = `Angular! v${VERSION.full}`;
    this.data = this.buildForm();
  }

  buildForm(): any {
    const listItems: any = [];
    const recursiveBuild = (items: any, listItems: Array<any>): void => {
      for (const key in items) {
        if (items.hasOwnProperty(key)) {
          listItems.push(this.buildPropertyObj(items, key));
          recursiveBuild(items[key].properties, listItems);
        }
      }
    };
    recursiveBuild(this.formSchema.properties, listItems);

    listItems.map((item: any, index: number) => {
      item.index = index + 1;
    });

    return { title: this.formSchema.title, items: listItems };
  }

  buildPropertyObj(data: string, key: string) {
    return {
      id: key,
      index: null,
      required: null,
      type: data[key].type,
      title: data[key].title,
      description: data[key].description,
      widget: 'defaultWidget',
      pattern: data[key].pattern || null,
      default: data[key].default || null,
      minimum: isNaN(data[key].minimum) ? null : data[key].minimum,
      maximum: isNaN(data[key].maximum) ? null : data[key].maximum,
      grouped: data[key].grouped || null,
      enum: data[key].enum || null,
    };
  }
}

@NgModule({
  imports: [BrowserModule],
  declarations: [App],
  bootstrap: [App],
})
export class AppModule {}
// Shim the environment
import 'core-js/client/shim';

// Angular requires Zones to be pre-configured in the environment
import 'zone.js/dist/zone';

//main entry point
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app';

import './style.css';

platformBrowserDynamic().bootstrapModule(AppModule);
h1,
p {
  font-family: sans-serif;
}
{
  "name": "@plnkr/starter-angular",
  "version": "1.0.3",
  "description": "Angular starter template",
  "dependencies": {
    "@angular/common": "^8.2.14",
    "@angular/compiler": "^8.2.14",
    "@angular/core": "^8.2.14",
    "@angular/platform-browser": "^8.2.14",
    "@angular/platform-browser-dynamic": "^8.2.14",
    "core-js": "2.6.11",
    "rxjs": "6.5.4",
    "zone.js": "0.10.2"
  },
  "main": "./lib/main.ts",
  "plnkr": {
    "runtime": "system",
    "useHotReload": true
  }
}
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}