0

I am creating an Angular app that requires testing a connection. However the connection can be saved with the fields left blank. I have not been able to successfully integrate Angular validators with the reactive form.

What would be the best way to add the validator to this html code in order to prevent it from being submitted blank? I have updated the HTML with the ngIf code but it is throwing errors which I have included at the bottom.

here is the HTML

<div class="cm-content-blocks">
    <ol class="breadcrumb">
               <li><a routerLink="/"><i class="fa fa-home"></i>Home</a></li>
               <li><a routerLink="/data-sources"><i class="fa fa-database mr-1"></i>Data Sources</a></li>
               <li><a routerLink="/selectdatabase"><i class="fa fa-sitemap mr-1"></i>Configure Data Source</a></li>

               <li  class="active"><i class="fa fa-spinner mr-1"></i>Test Connection</li>  
           </ol>
  </div>
<div class="clearafter headbtnc">
    <h3 class="headc mt-4">
    Test Connection:
    <!-- <div class="subhead">Create new database connection </div> -->
    </h3>
</div>

<section class="menublock">
    


<!-- test connection form -->
    <form [formGroup]="dataSourceCredentials" (ngSubmit)="postConnection()">
        <div class="form-group">
        <input formControlName="id" type="hidden" class="form-control">
        </div>
        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Database Type:</label>
                <select class="form-control" formControlName="databaseType" >
                    <option value="mysql" selected>MySQL</option>
                </select>
            </aside>
        </section>
        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Connection Name:</label>
                <input class="input-field" formControlName="name" type="text"   name="name" placeholder="Connection Name" required>
            </aside>    
            
           <!--ngIf code-->
            <!--*ngIf="driver.invalid && (driver.dirty || driver.touched)" class="alert alert-danger"-->
            <!--*ngIf="driver.errors.required"-->

            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Driver:</label>
                <input class="input-field" formControlName="driver" type="text"   name="driver" placeholder="Driver" required>
                <div *ngIf="!dataSourceCredentials.get('driver').valid &&  dataSourceCredentials.get('driver').touched" class="alert alert-danger">
                    <div>
                        Driver is required
                    </div>
                </div>      
            </aside>    
        </section>
    

        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Host Name:</label>
                <input class="input-field" formControlName="hostName" type="text" placeholder="Host Name (Eg: 40.102.118.70)" >
                <div class="alert alert-danger">
                    <div>
                        Host Name is required
                    </div>
                </div>
            </aside>
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Port:</label>
                <input class="input-field" formControlName="port" type="text" placeholder="Port" >             
                <div class="alert alert-danger">
                    <div>
                        Port is required
                    </div>
                </div>
            </aside>
        </section>

        <section class="inputc">
            <aside class="col-md-6 fieldc" >
                <label class="inputlabel">Username:</label>
                <input class="input-field" formControlName="username" type="text" placeholder="Username" required>
                <div class="alert alert-danger">
                    <div>
                        Username is required
                    </div>
                </div>
            </aside>

            <aside class="col-md-6 fieldc">
                <div class="input-group mb-3">
                    <label for="" class="inputlabel">Password:</label>
                    <input type="text" class="form-control input-field"  formControlName="password" type="password" [type]="hide ? 'password':'text'" placeholder="Password">
                    <div class="input-group-append">
                      <span class="input-group-text bg-light" id="basic-addon2">    
                          <i class="{{hide?'fa fa-eye-slash':'fa fa-eye'}}" (click)="hide = !hide"></i>
                      </span>
                    </div>
                  </div>
                  <div class="alert alert-danger">
                      <div>
                        Password is required
                      </div>
                  </div>
            </aside>
        </section>

        <!-- Saved connections -->

        <section class="inputc" >
            <aside class="col-md-6 fieldc" >
                <h4 cllass="innrcaption">Or select from your saved connections:</h4>
                <mat-form-field appearance="fill">
                <mat-label>Select from previous connections</mat-label>
                <mat-select>
                    <mat-option class="mr-4" *ngFor="let item of rdbmsConnectorList" [value]="item.databaseType" (click)="populateForm(item)">
                    {{item.name}}   
                    </mat-option>
                    <!-- <a href=""><i class="fa fa-trash" (click)="deleteSavedConnection(item.id)"></i></a> -->  
                </mat-select>  
                </mat-form-field>
            </aside>
        </section>
                
        
            
        <div class="graybdrt fifteen_pt fifteen_pb clearafter">
            <button class="tertiary-active fr" click="submit">
                <span>Save connection</span>
                <i class="fa fa-arrow-right fiveml" aria-hidden="true"></i>
            </button>
            <button class="tertiary-active fr" type="button" (click)="testConnection()">
                <span class="mr-2">Test connection</span>
                <i class="fa fa-spinner" aria-hidden="true"></i>
            </button>  
            <button class="tertiary-active fr float-left" type="button" (click)="clearForm(dataSourceCredentials)">Clear</button>      
        </div>

        
    <!-- <button (click)="loadData()" class="btn btn-danger btn-block " type="button">Load Data</button> -->
        
    </form>

</section>

the TS

import { Component, OnInit, Input, NgModule } from '@angular/core';
import { FormControl, NgForm, FormGroup, FormBuilder, Validators, FormArray } from '@angular/forms';
import { Config } from '../../../config'
import { DataSourceControllerService } from '../../../services/api/data-source-controller.service'
import { Router } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { MatSnackBar, MatSnackBarConfig, MatSnackBarHorizontalPosition, MatSnackBarVerticalPosition, } from '@angular/material/snack-bar';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';

import { RdbmsConnector } from "../../../models/rdbms-connector.model"
@Component({
  selector: 'app-create-and-test-connection',
  templateUrl: './create-and-test-connection.component.html',
  styleUrls: ['./create-and-test-connection.component.scss']
})
export class CreateAndTestConnectionComponent implements OnInit {

  //test connection object
  data: any;

  //post connection object
  connection: any;

  rdbmsConnectorList: RdbmsConnector[];
  hide = true;
  //snackbar 
  horizontalPosition: MatSnackBarHorizontalPosition = 'start';
  verticalPosition: MatSnackBarVerticalPosition = 'bottom';
  status: string;

  //validator
  connectionForm: FormGroup;

  form = {driver:''};


  constructor(private formBuilder: FormBuilder, public service: DataSourceControllerService, public router: Router,
    private snackBar: MatSnackBar
  ) {


  }

  //form model

  dataSourceCredentials = this.formBuilder.group({
    id: [""],
    databaseType: ["", Validators.required],
    driver: ["", Validators.required],
    hostName: ["", Validators.required],
    port: ["", Validators.required],
    username: ["", Validators.required],
    password: ["", Validators.required],


  })






  getAllConnections() {
    this.service.getRDBMSConnectors().toPromise()
      .then(response => this.rdbmsConnectorList = response as RdbmsConnector[]
      )
  }

  //populate form with saved connection

  populateForm(savedRecord: RdbmsConnector) {

    this.dataSourceCredentials.setValue({
      id: savedRecord.id,
      databaseType: savedRecord.databaseType,
      driver: savedRecord.driver,
      hostName: savedRecord.hostName,
      port: savedRecord.port,
      username: savedRecord.username,
      password: savedRecord.password,
    })


  }

  //populate form with saved connection

  clearForm(recordToBeCleared: any) {

    this.dataSourceCredentials.setValue({
      id: "",
      databaseType: "",
      driver: "",
      hostName: "",
      port: "",
      username: "",
      password: "",
    })


  }

  // post connection method
  postConnection() {
    if (this.dataSourceCredentials.value.id == "") {

      this.service.postRDBMSConnector(this.dataSourceCredentials.value).subscribe((response) => {
        console.log(response)
        this.connection = response;
        this.router.navigateByUrl(`/configureingestion/${this.connection.id}`);
        this.openSnackBar("New Connection created", '')
      });

    } else {
      this.openSnackBar("Connection already exists", '❗')

    }
  }

  // test connectio nmethod

  testConnection() {
    this.service.testRDBMSConnector(this.dataSourceCredentials.value).subscribe((response) => {
      this.data = response;
      console.log(response)
      if (this.data.status.toLowerCase() == "connection successful") {
        console.log(this.data.status)
        this.openSnackBar(this.data.status, '')
      } else {
        this.openSnackBar(this.data.status, '❌')

      }





    });

  }

  //snackbar
  openSnackBar(status: string, statusLogo: string) {
    this.snackBar.open(status, statusLogo, {
      duration: 3000,
      horizontalPosition: this.horizontalPosition,
      verticalPosition: this.verticalPosition,
      panelClass: ['tertiary-active']

    });
  }


  ngOnInit(): void {
    this.getAllConnections();

    this.connectionForm = new FormGroup ({
      driver: new FormControl(this.form.driver, [
        Validators.required
      ])
    })
  }

  get driver() {return this.connectionForm.get('driver');}

}

Error code

Error: src/app/components/connections/create-and-test-connection/create-and-test-connection.component.html:47:112 - error TS2531: Object is possibly 'null'.

47                 <div *ngIf="!dataSourceCredentials.get('driver').valid &&  dataSourceCredentials.get('driver').touched" class="alert alert-danger">

1 Answers1

0

Use the ngIf condition like this,

<div *ngIf="!dataSourceCredentials.get('type').valid &&  dataSourceCredentials.get('type').touched" class="alert alert-danger">
Barath
  • 51
  • 5