Search code examples
angularnativescriptangular2-nativescript

NativeScript / Angular Page.getViewById returns 'undefined'


I'm working on a NativeScript/Angular app. I am new to NativeScript and following a tutorial based on an earlier version (mine is 4.1.0, not sure what they're using). There's a modal dialog with a DatePicker element. I would like it to return the selected date to the parent element. The app compiles and launches just fine. But when I try to open the modal, I get the error, "Cannot set property 'year' of undefined".

The HTML is as follows:

<StackLayout class="modal-view-style">
  <StackLayout>
    <DatePicker id="datePicker"></DatePicker>
  </StackLayout>
  <Button class="btn btn-primary btn-active" text="submit" (tap)="submit()"></Button>
</StackLayout>

And here's the class:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { ModalDialogParams } from 'nativescript-angular/modal-dialog';
import { DatePicker } from 'tns-core-modules/ui/date-picker';
import { Page } from 'tns-core-modules/ui/page';

@Component({
  moduleId: module.id,
  templateUrl: './date-picker-modal.component.html'
})
export class DatePickerModalComponent implements OnInit {

  constructor(private params: ModalDialogParams, private page: Page) { }

  ngOnInit() { 
    let datePicker: DatePicker = <DatePicker>this.page.getViewById<DatePicker>('datePicker');

      let currentdate: Date = new Date();
      datePicker.year = currentdate.getFullYear();
      datePicker.month = currentdate.getMonth() + 1;
      datePicker.day = currentdate.getDate();
      datePicker.minDate = currentdate;
      datePicker.maxDate = new Date(2045, 4, 12);
  }

  public submit() {
      let datePicker: DatePicker = <DatePicker>this.page.getViewById<DatePicker>('datePicker');
      let selectedDate = datePicker.date;

      let reserveTime = new Date(
        selectedDate.getFullYear(),
        selectedDate.getMonth(),
        selectedDate.getDate()
      ));
      this.params.closeCallback(reserveTime.toISOString());
  }

}

Does anyone know what's going on? I'm assuming it's just that the api has changed, but I haven't been able to find it in the documentation. If I'm right about that, a link to the appropriate place in the docs would be much appreciated. Also, if this is not the "preferred" way to do this sort of thing, I would love to know what is. Thanks.


Solution

  • If you are using NativeScript with Angular then use Angular template variable syntax like so:

    <StackLayout class="modal-view-style">
      <StackLayout>
        <!-- notice the # -->
        <DatePicker #datePicker></DatePicker>
      </StackLayout>
      <Button class="btn btn-primary btn-active" text="submit" (tap)="submit()"></Button>
    </StackLayout>
    

    and your component should look like this:

    import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
    import { ModalDialogParams } from 'nativescript-angular/modal-dialog';
    import { DatePicker } from 'tns-core-modules/ui/date-picker';
    import { Page } from 'tns-core-modules/ui/page';
    
    @Component({
      moduleId: module.id,
      templateUrl: './date-picker-modal.component.html'
    })
    export class DatePickerModalComponent implements OnInit {
      @ViewChild('datePicker') dp: ElementRef;
    
      datePicker: DatePicker;
      constructor(private params: ModalDialogParams, private page: Page) { }
    
      ngOnInit() { 
          this.datePicker = <DatePicker>this.dp.nativeElement;
    
          let currentdate: Date = new Date();
          this.datePicker.year = currentdate.getFullYear();
          this.datePicker.month = currentdate.getMonth() + 1;
          this.datePicker.day = currentdate.getDate();
          this.datePicker.minDate = currentdate;
          this.datePicker.maxDate = new Date(2045, 4, 12);
      }
    
      public submit() {
          let selectedDate = this.datePicker.date;
    
          let reserveTime = new Date(
            selectedDate.getFullYear(),
            selectedDate.getMonth(),
            selectedDate.getDate()
          ));
          this.params.closeCallback(reserveTime.toISOString());
      }
    }