2

I have a google place directive; when I type on my input field it suggests places and upon selection it outputs the place name. I see the selected value in input field, but my form control value shows only what I typed in the input field. I am using model driven form. For example: if I type bha and then select Bharat Diamond House, the input field shows correctly Bharat Diamond House but the form value gets only bha. My problem is similar to this and this

My directive looks like this:

import {Directive, ElementRef, EventEmitter, Output} from '@angular/core';
import {NgModel} from '@angular/forms';
import {Address} from './model/google_place';

declare var google:any;

@Directive({
  selector: '[googleplace]',
  providers: [NgModel],
  host: {
    '(input)' : 'onInputChange($event)'
  }
})
export class GoogleplaceDirective  {
  @Output() setAddress: EventEmitter<any> = new EventEmitter();
  @Output() adr_address: EventEmitter<any>  = new EventEmitter();
  @Output() place_id: EventEmitter<any>  = new EventEmitter();
  @Output() formatted_address: EventEmitter<any>  = new EventEmitter();

  modelValue:any;
  autocomplete:any;
  private _el:HTMLElement;
  place:Address;

  constructor(el: ElementRef, private model:NgModel) {
    this._el = el.nativeElement;
    this.modelValue = this.model;
    var input = this._el;
    this.autocomplete = new google.maps.places.Autocomplete(input, {});
    google.maps.event.addListener(this.autocomplete, 'place_changed', ()=> {

      (<HTMLInputElement>input).value=(<HTMLInputElement>input).value.split(',')[0];

      this.place = this.autocomplete.getPlace();
      if (this.place && this.place.place_id){
        this.invokeEvent();
      }
    });
  }

  //invokeEvent(place:Object) {
  invokeEvent() {
    this.setAddress.emit(this.place);
    this.adr_address.emit(this.place.adr_address ? this.place.adr_address : null);
    this.formatted_address.emit(this.place.formatted_address ? (this.place.formatted_address) : null);
  }

  onInputChange() {

  }
}

PLUNK

Community
  • 1
  • 1
Jane
  • 283
  • 3
  • 5
  • 16

1 Answers1

1

Not familiar with Google places, but I can tell you that much that the changes are not affected, because you need to use patchValue here, and patch the value you get from the directive.

HOW you do this, you would need to figure out, probably need to add EventEmitter from your directive, that returns your value, which you can then patch something like the following:

this.createEventForm.patchValue({venue_name: theValue}) 

And as I have noticed from questions before, there seems to be change detection issues with google map/places, so you'll probably need to use ChangeDetectorRef

import { ChangeDetectorRef} from '@angular/core';

constructor(public createEventFb:FormBuilder, private ref: ChangeDetectorRef) { }

and when you need to detect the changes:

this.ref.detectChanges();

This I noticed when I tested your plunker and it was needed. Here is your Plunker, where I did a EXTREMELY POOR solution. But I wanted to test it, and here I manually assign the value you get from your directive in the venue_name (only), to showcase the patchValue on that field.

AT82
  • 71,416
  • 24
  • 140
  • 167
  • 1
    I already figured it out, I used setValue. Forgot to post the solution, posting now. But, thanks anyway for looking into it. – Jane Mar 20 '17 at 12:09
  • Yeah, setValue and patchValue are almost the same, with some minor differences, but both will work :) But yes, no problem! Have great day and happy coding :) – AT82 Mar 20 '17 at 12:24
  • In Angular 5+ `patchValue` is not working for me until you focus and then blur any input of the form. The only working solution is triggering the change detection manually as indicated in this answer. – Elias Garcia Jan 03 '18 at 02:17