4

I'm passing data into a child component that is accessible and I can build out my view using this data. But, I'm needing to access a property on the @Input object to "find" an item in an array with the same value. Fairly simple and straight forward. I'm doing this in my constructor function when the component loads so it's available right away.

BUT, the @Input object is coming back undefined so I cannot access the property. Can someone take a look and tell me what's going on here?

The Object that comes back undefined is "this.ConfirmOrderData" and like I said, I can do ngFor repeats on this objects property arrays etc, so I'm stumped why it is undefined.

CODE:

@Input() ConfirmOrderData:{
    orderRefillData: Array<any>,
    selectedUser: any,
    DeliveryTypeId: any,
    PickupLocationId: any,
    PaymentTypeId: any,
    AddressType: any
};

constructor(
fb: FormBuilder,
public refillService: refillService,
public globalService: globalService
) {
   this.userInfo = this.globalService.getUserInfo();
   this.deliveryAddress = this.userInfo.userInfo.StreetAddresses.find((item) => item.DeliveryTypeId == this.ConfirmOrderData.AddressType.AddressTypeId)
   //the this.ConfirmOrderData object in the above line comes back undefined. Don't know why.
}
billy_comic
  • 867
  • 6
  • 27
  • when you use properties directly in the template, like data that is not observed it has to be defined or you can use ? like `data?.item?.couldbelate` – Dylan Apr 21 '17 at 21:16

2 Answers2

3

This is because you are trying to perform action on the @Input in the constructor. At the time the action in the constructor is executed, the input values have yet to been set. You need to move this logic to ngOnInit, so that the values have been set, also see this: Difference between Constructor and ngOnInit

So move your logic to OnInit and it should be good :)

ngOnInit() {
   this.userInfo = this.globalService.getUserInfo();
   this.deliveryAddress = this.userInfo.userInfo.StreetAddresses.find((item) => 
        item.DeliveryTypeId == this.ConfirmOrderData.AddressType.AddressTypeId)
}
Community
  • 1
  • 1
AT82
  • 71,416
  • 24
  • 140
  • 167
  • Did you try either answer, did either help or do you need further help? :) – AT82 Apr 24 '17 at 19:34
  • 1
    I actually performed this action in the parent component and included it int he data object passed to the child, so it was already available and stored in the variable the way i needed it, BUT your way is definitely much more flexible and I will use it moving forward (or when I refactor this piece). Thanks. – billy_comic May 03 '17 at 13:44
0

Create a model

export interface ConfirmOrderData:{
    orderRefillData: Array<any>,
    selectedUser: any,
    DeliveryTypeId: any,
    PickupLocationId: any,
    PaymentTypeId: any,
    AddressType: any
};

Use it in your component as

@Input() confirmOrderData :Array<ConfirmOrderData>;

To avoid the undefined problem you need to instantiate it as

in your definition as

@Input() confirmOrderData :Array<ConfirmOrderData>= new Array<ConfirmOrderData>();

or inside your constructor as

constructor(...){
    this.confirmOrderData  = new Array<ConfirmOrderData>();
}

When you do as above you will be getting another error in orderRefillData as undefined. To fix it you should instantiate that property after your object is instantiated as

this.confirmOrderData.orderRefillData = new Array<any>();

A simple fix would be assigning empty values to all properties

this.confirmOrderData ={
        orderRefillData:new Array<any>(),
        selectedUser: '',
        DeliveryTypeId: '',
        PickupLocationId: '',
        PaymentTypeId: '',
        AddressType: ''
} 
Aravind
  • 40,391
  • 16
  • 91
  • 110