Ilja
Ilja

Reputation: 46527

Setting form input value from component in angular 2

I have following input inside a form:

<form [ngFormModel]="newListingForm" (ngSubmit)="submitListing(newListingForm.value)">

<input type="text" placeholder="00.000" #mapLatitudeInput="ngForm" [ngFormControl]="newListingForm.controls['mapLatitudeInput']">

</form>

I need to update its value when I'm dragging map around, so from related component that looks like this:

import {Component} from 'angular2/core';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators} from 'angular2/common';

@Component({
  templateUrl : 'app/components/new-listing/new-listing.html',
  directives: [FORM_DIRECTIVES]
})

export class NewListingComponent {

  //Costructor
  constructor(
    fb: FormBuilder
  ){

    //New Listing Form
    this.newListingForm = fb.group({
      'mapLatitudeInput': ['', Validators.required]
    });
  }

  //Google maps
  loadMap(latitude, longitude) {
    var map = new google.maps.Map(document.getElementById('listing-map'), {
      center: {lat: latitude, lng: longitude},
      zoom: 18,
      scrollwheel: false,
      mapTypeControl: false,
      streetViewControl: false
    });

    //Update coordinates on map drag
    map.addListener('drag', function(event) {

      //ISSUE HERE
      this.newListingForm.controls.mapLatitudeInput.value = map.getCenter().lat()

      //console.log(map.getCenter().lat());
      //console.log(map.getCenter().lng());
    });
  }

  //TODO Form submission
  submitListing(value: string): void {
    console.log("Form Submited");
  }

  //Log error
  logError(err) {
   console.error('Error: ' + err);
  }

}

What I thought would be a correct way is where //ISSUE HERE comment is, but that throws an undefined error.

Upvotes: 4

Views: 5947

Answers (1)

Thierry Templier
Thierry Templier

Reputation: 202296

You should use an arrow function for your drag callback:

map.addListener('drag', (event) => {
  this.newListingForm.controls.mapLatitudeInput.value
                                  = map.getCenter().lat()
});

In this case, the this keywork will be the instance of the component itself.

Perhaps you could leverage the ngModel directive to set the value of your input instead of the control. It allows to use two way binding.

<input type="text" placeholder="00.000"
       #mapLatitudeInput="ngForm"
       [ngFormControl]="newListingForm.controls['mapLatitudeInput']"
       [(ngModel)]="mapCoordinates.latitude">

The mapCoordinates object would be an attribute of your component with two fields: longitude and latitude.

@Component({
  templateUrl : 'app/components/new-listing/new-listing.html',
  directives: [FORM_DIRECTIVES]
})
export class NewListingComponent {
  constructor() {
    this.mapCoordinates = {
      longitude: 0, latitude: 0
    };
  }
}

Hope it helps you, Thierry

Upvotes: 5

Related Questions