-1

I have a Observable that returns Data from an API. In this case there are 3 type of Addresses which could be returned, Office, Mailing and Home. But in the case user did not provide a Home Address that element does not exist in the API response.

i use

setInitialValue() {
this.userForm.setValue( {
  home_address_city = this.userProfile.home_address.city
})
}

this works fine as long as that element exists. So i am wondering what is the safest way to handle this in case that this.userProfile.home_address.city does not exist

NoSoup4you
  • 640
  • 1
  • 10
  • 34
  • Why not add a null check? `home_address_city = this.userProfile.home_address.city ? this.userProfile.home_address.city: 'No address'`. And if the property does not exists in the response, `undefined` will be set, which is still ok because its not an error. – Amit Chigadani Jan 07 '20 at 18:24
  • a slight corection to Amit's response. home_address_city = this.userProfile.home_address? this.userProfile.home_address.city: 'No address' the previous response sill assumed the userprofile always had a home address. and if doesn't, you would get an error. – Edward Jan 07 '20 at 18:28
  • @Edward Yeah perfect. Thanks! TBH, I did not notice the `city` property. I thought `home_address.city` was all a single prop under `userProfile`. – Amit Chigadani Jan 07 '20 at 18:37
  • yes i just tried Amit's answer and as long as there is a home_address: {} in the response it works fine but as soon as its missing i get the error "Can not Read Property. So how would i correctly check for null on home_address as well as city. I assume checking this.userProfile.home_address? will only check if home_address exist not the city element underneath – NoSoup4you Jan 07 '20 at 18:42
  • @NoSoup4You `home_address_city = this.userProfile.home_address ? this.userProfile.home_address.city : ''`; this will only try to get the "city" property if home_address is defined. if you need to also check if "userProfile" exists, then you can do `home_address_city = (this.userProfile && this.userProfile.home_address) ? this.userProfile.home_address.city : ''` – Edward Jan 08 '20 at 21:49

2 Answers2

0

If your project has TypeScript 3.7 installed, you can make use of optional chaining.

setInitialValue() {
  this.userForm.setValue({
    home_address_city: this.userProfile?.home_address?.city
  })
}

Otherwise, you will have to chain the checking of the properties within the if statement to check for home_address and city:

 setInitialValue() {
  if (this.userProfile && this.userProfile.home_address && this.userProfile.home_address.city) {
    this.userForm.setValue({
      home_address_city: this.userProfile.home_address.city
    });
  }
}

I would like to note that your syntax for setValue is wrong, you should replace the = with :.

EDIT

Following up on your comment, you can try this:

setInitialValue() {
  this.userForm.setValue({
    home_address_city: (this.userProfile && this.userProfile.home_address && this.userProfile.home_address.city) ? this.userProfile.home_address.city : '',
    home_address_zip: (this.userProfile && this.userProfile.home_address && this.userProfile.home_address.zip) ? this.userProfile.home_address.zip : '',
  });
}
wentjun
  • 40,384
  • 10
  • 95
  • 107
  • Typescript 3.7 is not compatible with Angular. – Maihan Nijat Jan 07 '20 at 18:39
  • 1
    @MaihanNijat Actually, you can install it, but it is not officially supported by Angular. I have explained it over here https://stackoverflow.com/a/57216166/10959940 – wentjun Jan 07 '20 at 18:40
  • Okay. In null case, would it assign undefined or would not assign anything at all? – Maihan Nijat Jan 07 '20 at 18:42
  • 1
    @MaihanNijat it would assign undefined. – wentjun Jan 07 '20 at 18:45
  • Ok if i modify your code to setInitialValue() { if (this.userProfile && this.userProfile.home_address && this.userProfile.home_address) { this.userForm.setValue({ home_address_city: this.userProfile.home_address.city ? this.userProfile.home_address.city : '', home_address_zip: this.userProfile.home_address.zip ? this.userProfile.home_address.zip : '', }); } }i run into the issue that i can not use it to setValue for othe controls and check them as setValue requires me to provide values for all controles – NoSoup4you Jan 07 '20 at 19:06
  • @NoSoup4you in that case, you can use patchValue instead (https://stackoverflow.com/questions/55275025/how-to-set-value-to-form-control-in-reactive-forms-in-angular/55275042#55275042) – wentjun Jan 07 '20 at 19:08
  • iknow but i was wondering if there was a way to move the if (this.userProfile && this.userProfile.home_address ) inside the setValue part but i guess that is not an option – NoSoup4you Jan 07 '20 at 19:13
  • But what happens in the case that this.userProfile.home_address does not exist ? arent we then back to the issue from before ? – NoSoup4you Jan 07 '20 at 19:20
  • @NoSoup4you sorry I misread your code. I have updated my answer – wentjun Jan 07 '20 at 19:29
0

You can try

setInitialValue() {
    this.userForm.setValue(this.userProfile.home_address.city || '')
}
Maihan Nijat
  • 9,054
  • 11
  • 62
  • 110
pratikch
  • 670
  • 5
  • 19