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.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
Ilja
  • 44,142
  • 92
  • 275
  • 498
  • 1
    Possible duplicate of [unable to get component variables inside a RxJS subscribe() function](http://stackoverflow.com/questions/34647449/unable-to-get-component-variables-inside-a-rxjs-subscribe-function) – drew moore Jan 14 '16 at 14:55

1 Answers1

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

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • I'm getting following error now: Cannot set property value of # which has only a getter – Ilja Jan 14 '16 at 14:34
  • And within my text editor following error: Property 'mapLatitudeInput' does not exist on type '{ [key: string]: AbstractControl; }' – Ilja Jan 14 '16 at 14:37
  • I think that you should leverage the `ngModel` directive... I updated my answer ;-) – Thierry Templier Jan 14 '16 at 14:38
  • 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 – Ilja Jan 14 '16 at 14:47
  • 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. – Thierry Templier Jan 14 '16 at 14:53
  • Adding it this way prompts an error: ``` Property mapLatitudeModel does not exist on type 'NewListingComponent' ``` I added [(ngModel)]="mapLatitudeModel" to appropriate input – Ilja Jan 14 '16 at 15:00
  • Here is a plunkr showing you how to use this: https://plnkr.co/edit/0l9KxsuT9fLV3A64Sw4X?p=preview. – Thierry Templier Jan 14 '16 at 15:14
  • It seems that it just doesn't work inside that drag function. Thank you for clearing this out. I'll keep digging into the issue – Ilja Jan 14 '16 at 15:23