<!DOCTYPE html>
<html>

  <head>
    <base href="." />
    <title>angular2 playground</title>
    <link data-require="bootstrap-css@*" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" />
    <link data-require="font-awesome@*" data-semver="4.5.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.css" />
    <link rel="stylesheet" href="style.css" />
    <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
    <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>

  <body>
    <my-app>
    loading...
  </my-app>
  </body>

</html>

<html>
/* Styles go here */

pre {
            display: block;
            padding: 9.5px;
            margin: 0 0 10px;
            font-size: 13px;
            line-height: 1.42857143;
            color: #333;
            word-break: break-all;
            word-wrap: break-word;
            background-color: #f5f5f5;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
### Angular Starter Plunker - Typescript
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
    
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.0.2/lib/typescript.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';

platformBrowserDynamic().bootstrapModule(AppModule)
//our root app component
import {Component, NgModule, OnInit } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormGroup, FormArray, FormBuilder, Validators } from '@angular/forms'

@Component({
  selector: 'my-app',
  templateUrl: './src/app.component.html',
})
export class App implements OnInit {
  
  private _form: FormGroup;
  title:string;
  
  constructor(
    private _fb: FormBuilder
    ) {
    this.title = 'Deep Nested Fields in Nested Array (Model Driven)! '
  }
  ngOnInit() {
    this._form = this._fb.group({
      'teacher': ['', Validators.required],
      'schools': this._fb.array([
          this._fb.group({
            'school_name': ['', Validators.required],
            'school_description': [''],
            'events': this._fb.array([
              this._fb.group({
                'event_name': ['']
              })
            ])
          })
      ])
    });
  }
  onSubmit() {
    console.log(this._form.value)
  }
  initSchool() {
    return this._fb.group({
        'school_name': ['', Validators.required],
        'school_description': [''],
        'events': this._fb.array([
          this._fb.group({
            'event_name': ['', Validators.required]
          })
        ])
    });
  }

  addSchool() {
    const control = <FormArray>this._form.controls['schools'];
    control.push(this.initSchool());
  }
  removeSchool(i: number) {
    const control = <FormArray>this._form.controls['schools'];
    control.removeAt(i);
  }

  initEvents() {
    return this._fb.group({
      'event_name': ['', Validators.required]
    });
  }

  addEvent(i: number) {
    const control = (<FormArray>this._form.controls['schools']).at(i).get('events') as FormArray;
    control.push(this.initEvents());
  }

  removeEvent(i: number) {
    const control = (<FormArray>this._form.controls['schools']).at(i).get('events') as FormArray;
    control.removeAt(i);
  }
}

@NgModule({
  imports: [ 
    BrowserModule
    FormsModule,
    ReactiveFormsModule
    ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}
<div class="container">
<div class="col-md-8 col-xs-12">
    <form [formGroup]="_form" novalidate (ngSubmit)="onSubmit()">
      <div class="row">
        <div class="col-xs-12">
          <div class="card">
            <div class="card-header">
              <h6>{{title}}</h6>
            </div>
            <div class="card-block">
              <div class="form-group">
                <label class="form-control-label">Teacher Name:</label>
                <input type="text" class="form-control" placeholder="Teacher" formControlName="teacher" />
                <small [hidden]="_form.controls.teacher.valid" class="text-danger">
                  Teacher Name is required!
                </small>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12" formArrayName="schools">
          <div *ngFor="let school of _form.controls['schools'].controls; let i=index">
            <div class="card">
              <div class="card-header text-primary">
                <span style="font-weight: 500;">{{i + 1}} -</span>
                <span>School Name: {{ _form.value.schools[i].school_name }}</span>
                <span class="pull-right" *ngIf="_form.controls['schools'].controls.length > 1" (click)="removeSchool(i)">
                  <i class="fa fa-remove text-danger"></i>
                </span>
              </div>
              <div class="card-block" formGroupName="{{i}}">
                <div class="form-group">
                  <label class="form-control-label">School Name</label>
                  <input type="text" class="form-control" placeholder="School Name" formControlName="school_name" />
                  <small [hidden]="_form.controls.schools.controls[i].controls.school_name.valid" class="text-danger">
                      School Name is required!
                  </small>
                </div>
                <div class="form-group">
                  <label class="form-control-label">School Description</label>
                  <textarea rows="3" type="text" class="form-control" 
                        placeholder="Description" formControlName="school_description"></textarea>
                </div>
                <div class="row" formArrayName="events">
                  <div *ngFor="let event of school.controls['events'].controls; let idx=index">
                    <div class="card">
                      <div class="card-header">
                        <span style="font-weight: 500;">{{idx + 1}} -</span>
                        <span>Event Name</span>
                          <span class="pull-right" *ngIf="school.controls['events'].controls.length > 1" (click)="removeEvent(i)">
                            <i class="fa fa-remove text-danger"></i>
                          </span>                       
                      </div>
                      <div formGroupName="{{idx}}">
                        <div class="card-block">
                          <div class="form-group col-xs-12">
                          <label class="form-control-label">Event Name</label>
                          <input type="text" class="form-control" placeholder="Event Name" formControlName="event_name">
                              <small [hidden]="school.controls.events.controls[idx].controls.event_name.valid" class="text-danger">
                                  Event Name is required!
                              </small>
                          </div>                          
                        </div>
                      </div>
                      <div class="card-footer">
                        <a class="btn btn-success btn-minimize pull-right" (click)="addEvent(i)">Add another event +</a>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div class="card-footer text-primary">
                <a class="btn" (click)="addSchool()">Add another school +</a>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="col-xs-12" style="margin-bottom:10px;">
        <button class="btn btn-primary pull-right" 
                type="submit" [disabled]="!_form.valid">Submit</button>
      </div>
    </form>
</div>


  <div class="col-md-4 col-xs-12">
    <div class="card-footer">
      <h5>Field Values</h5>
      <pre>{{ _form.value | json }}</pre>
    </div>
  </div>
  </div>