1
votes

I am implementing a wep project using Mean Stack with Angular 6. There I have to submit a form with an uploaded file. Following is my html.

<ng-template #content let-c="close" let-d="dismiss">
  <div class="modal-header">
    <h4 class="modal-title" id="modal-basic-title">New Map</h4>
  </div>
  <div class="modal-body">
    <form #mapsForm="ngForm" enctype="multipart/form-data">
      <div class="form-group">
        <label for="name">Name</label>
        <div class="input-group">
          <input type="text" id="mapNameId" class="form-control form-control-sm  " name="mapName" [(ngModel)]="currentMapDetails.mapName" name="firstName" >
        </div>
        <br>
        <label for="geoRefMap">Geo- reference Map</label>
        <div class="input-group">
          <input type="file" class="form-control" #fileInput name="milespecMap" ng2FileSelect [uploader]="uploader" (change)="handleFileInput($event.target.files)"
          />
        </div>
        <br>
        <div>
          <button type="submit" (click)="updateInfo()" class="btn btn-sm btn-rectangle btn-default text-case" id="updatebtn">Update</button>
        </div>
        <br>
        <label for="shapeFile">Shape Files</label>
        <div class="boxed">
          <div class="input-group">
            <input id="shapeFile" class="form-control" name="shapeFile">
            <img src="../../../../../assets/images/maps/Browse.png" width="40" height="40" style=" position: absolute; top: 1px; right: 1px"
              (click)="search(); " />
          </div>
        </div>
      </div>
    </form>


  </div>
  <div class="modal-footer">
    <nb-card class="action-buttons">
      <div class="form-input-group">
        <div class="row">
          <div class="">
            <button type='button' (click)="modal.close('Save click')" class="btn btn-sm btn-rectangle btn-default text-case">Save
            </button>
          </div>
          <div class="">
            <button type='button' (click)="modal.cancel('cancel click')" class="btn btn-sm btn-rectangle btn-default text-case">Cancel</button>
          </div>

        </div>
      </div>
    </nb-card>
  </div>
  <br>

</ng-template>

<hr>
<pre>{{closeResult}}</pre>
<nb-card>
  <nb-card-header>
  </nb-card-header>
  <nb-card-body>
    <div>
      <div class="col-lg-3" style="float: left; ">
        <div class="verticalLine">
        </div>
      </div>

      <nb-card class="action-buttons">
        <div class="form-input-group">
          <div class="row">
            <div class="">
              <button type='button' (click)="openModal(content)" class="btn btn-sm btn-rectangle btn-default text-case">Add
              </button>
            </div>
            <div class="">
              <button type='button' (click)="editMap()" class="btn btn-sm btn-rectangle btn-default text-case">Edit</button>
            </div>
            <div class="">
              <button type='button' (click)="deleteMap()" class="btn btn-sm btn-rectangle btn-default text-case">Delete</button>
            </div>
          </div>
        </div>
      </nb-card>

    </div>
  </nb-card-body>
</nb-card>

There I have an 'Add' button in map.component.html and clicking that button opens a modal. Following is my ts.

import { Component, OnInit } from '@angular/core';
import { NgbModal, ModalDismissReasons } from '../../../../../../node_modules/@ng-bootstrap/ng-bootstrap';
import { HttpResponse, HttpEventType } from '@angular/common/http';
import { Http } from '../../../../../../node_modules/@angular/http';
import { FileUploader, FileSelectDirective } from 'ng2-file-upload/ng2-file-upload';
import { Map } from './models/map';
import { Router } from '@angular/router';
import { MapsService } from '../../services/maps.service';

const URL = '/mapInfo/uploadMap';
@Component({
  selector: 'maps',
  templateUrl: './maps.component.html',
  styleUrls: ['./maps.component.scss']
})
export class MapsComponent implements OnInit {
  closeResult: string;
  currentMapDetails: Map;
  selectedFile: File = null;

  public uploader: FileUploader = new FileUploader({ url: URL, itemAlias: 'milespecMap', });
  constructor(private modalService: NgbModal,
    private mapsService: MapsService,
    private http: Http,
    private router: Router
  ) { }

  ngOnInit() {
  }
  openModal(content: any) {
    this.modalService.open(content).result.then((result) => {
      this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
  }

  private getDismissReason(reason: any): string {
    if (reason === ModalDismissReasons.ESC) {
      return 'by pressing ESC';
    } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
      return 'by clicking on a backdrop';
    } else {
      return `with: ${reason}`;
    }
  }

  handleFileInput(file: FileList) {
    this.selectedFile = file.item(0);
    var reader = new FileReader();

    reader.onload = (event: any) => {
      this.currentMapDetails.milespecUrl = event.target.result;

    }
    reader.readAsDataURL(this.selectedFile);
  }

  updateInfo() {
    this.uploader.uploadAll(); ///image upload
    this.update();
  }

  update() {

    this.mapsService.updateMap(this.currentMapDetails).subscribe(res => {
      this.currentMapDetails;
    }, (err) => {
      console.log(err);
    });
    console.log(this.currentMapDetails);
  }
}

Following is my map class.

export class Map {
  _id: string;
  mapName: string;
  milespecUrl: string;
}

But when I bind Map Name field with 'currentMapDetails'(eg:[(ngModel)]="currentMapDetails.mapName"). It does not open my modal and it gives following error. Cannot read property 'mapName' of undefined

3
currentMapDetails: Map = {} ;Fateme Fazli

3 Answers

0
votes

You just need to initialize currentMap Details property

currentMapDetails: Map = new Map();

when you declare currentMapDetails you have just set the type of it but still have a value of undefined

you have to change the class name Map to something else it 's will have conflect with javascript Map

0
votes

You are encountered with this undefined error since currentMapDetails is not initialized when the Component was rendered. What you can do is just put one if condition before you use it. It will display the mapName once the currentMapDetails is retrieved and available.

<div class="input-group" *ngIf="currentMapDetails" >
    <input type="text" id="mapNameId" class="form-control form-control-sm "
       name="mapName" [(ngModel)]="currentMapDetails.mapName" name="firstName" >
</div>
0
votes

You have just declared the currentMapDetails as Map. It's not initialized yet. Hence the error occurs. Since currentMapDetails itself undefined. So you can not access its property mapName.

You can solve this by adding ? mark in html view: (Note: This will just avoid the error).

[(ngModel)]="currentMapDetails?.mapName"

OR

You have to initialize it in ngOnInit(),

ngOnInit() { 
    currentMapDetails: Map = new Map();
}

Hope this helps.,