4

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.

1

1 Answer 1

5

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

Sign up to request clarification or add additional context in comments.

8 Comments

I'm getting following error now: Cannot set property value of #<AbstractControl> which has only a getter
And within my text editor following error: Property 'mapLatitudeInput' does not exist on type '{ [key: string]: AbstractControl; }'
I think that you should leverage the ngModel directive... I updated my answer ;-)
I tried using ngModel before for this, but didn't figure it out. How do I bind mapCoordinates inside a component? I have tried puting mapCoordinates: Object; under my class export line and accessing it like this.mapCoordinates.latitude, but this doesn't seem to work
I updated my answer. In fact, you simply need to initialize the component attribute... Then your input is linked on it using [(ngModel)] with two way binding.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.