Matt Barr
Matt Barr

Reputation: 494

Why would a member variable that is initialized in the constructor be undefined in ngInit in ionic / angular?

I have a modal consisting of a form that is bound to an instance of "Foo." During construction of the modal, foo is set correctly. I double-checked both using breakpoints and console.log. However, at any time after the constructor, this.foo is undefined.

--

EDIT: I have found a solution, but my question still stands. My solution was to move my assignment of foo to ngOnInit() instead of the constructor.

--

Template:

<ion-header>
    <ion-toolbar>
      <ion-title>New Foo</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-content>
    <ion-list>
      <ion-item>
        <ion-input placeholder="Name" [(ngModel)]="foo.name"></ion-input>
      </ion-item>
      <!-- etc... -->
    </ion-list>

    <ion-button expand="block" color="primary" (click)="create()">
      Create
    </ion-button>
</ion-content>

Component:

export class FooModalComponent implements OnInit {

  foo: Foo = new Foo();

  constructor(
    private modalController: ModalController,
    private navParams: NavParams
  ) { 
    const inputFoo = this.navParams.get("foo");

    if (inputFoo) {
      // this shouldn't matter, as foo would have to be truthy (not undefined)
      this.foo = inputFoo;
    }

    // logs this.foo as expected
    console.log(this.foo);
  }

  ngOnInit() {
    // logs: undefined
    console.log(this.foo);
  }

  close() {
    this.modalController.dismiss();
  }

  create() {
    this.modalController.dismiss(this.foo);
  }
}

Model:

export class Foo {
    name: string;
}

Upvotes: 3

Views: 754

Answers (1)

Cedric Reichenbach
Cedric Reichenbach

Reputation: 9319

In newer Ionic versions (probably 4+), data passed to modals as componentProps/NavParams get automatically assigned to corresponding class variables in the component to be presented. If you pass an undefined variable, the corresponding field will effectively get deleted. This happens after object construction, but before ngOnInit is called, that's why your workaround did the trick.

Ionic 5 documentation mentions @Input annotations for this, but the same seems to happen without as well, though I can't find any confirmation for that claim.

What you probably did:

this.modalController.create({
  component: FooModalComponent,
  componentProps: { foo: foo } // foo might be undefined
})

To avoid passing an undefined foo, you could do something like:

this.modalController.create({
  component: FooModalComponent,
  componentProps: foo ? { foo } : {}
})

Or, as you did, re-assign variables in ngOnInit as needed. On a side note, you might not need NavParams anymore in the constructor, since passed params are already assigned at this point.

Upvotes: 1

Related Questions