title: Angular- function call errors when called in one place, not in another
body: <p>I have an Angular application, and on one of the pages, I am displaying a table which is populated with information regarding various accounts. One of the columns is titled 'Contact', and displays a drop-down to allow the user to select the contact to be used for that account. The drop down is populated when the page loads with all of the contact names that have previously been added to the given account.</p>
  
  <p>If the user wants to add a new contact (i.e. one whose name does not appear in the drop down), they can click an 'Edit' button in that cell in the table, which will open a dialog with a form to allow them to add a new contact (just first name, last name &amp; email address).</p>
  
  <p>I want to add fields to this dialog to allow the user to set a 'preferred name' to be used for letters &amp; emails, which I've done with the following HTML:</p>
  
  <pre><code>&lt;div class="provContactSelector" *ngIf="payer.editAddresseePanel"&gt;
      &lt;h3&gt;
          Payer Addressee Fields
          &lt;label class="icon icon-close-selected" [class.icon-close-selected]="payer.editAddresseePanel" (click)="displayEditAddressee(payer)"&gt;&lt;span class="vh"&gt;Close edit contact&lt;/span&gt;&lt;/label&gt;
      &lt;/h3&gt;
      &lt;div class="provContacts"&gt;
          If you would like to override the Addressee's&lt;br /&gt;
          salutation in reminder communications... &lt;br /&gt;
          &lt;br /&gt;
          Salutation: Hi {{ payer.preferredAddresseeName }} &lt;br /&gt; &lt;input class="provContacts__new-contact-field provContacts__name" [class.error]="newContactFormErrors.contactPreferredName" placeholder={{payer.preferredAddresseeName}} type="text" (change)="updateTransactionContact" autocomplete="given-name" formControlName="contactPreferredName" /&gt;
          PDF: Hi {{ payer.preferredAddresseeName }}&lt;br /&gt; &lt;input class="provContacts__new-contact-field provContacts__name" [class.error]="newContactFormErrors.contactPreferredAddresseeName" placeholder={{payer.preferredAddresseeName}} type="text" (change)="updateTransactionContact" autocomplete="preferred-address-name" formControlName="contactPreferredAddresseeName" /&gt;
  
          &lt;div class="provContacts__row"&gt;
              &lt;form [formGroup]="newContactForm" class="provContacts__col provContacts__new-contact"&gt;
                  &lt;label&gt;Add new contact&lt;/label&gt;
                  &lt;div class="provContacts__new-contact-fields"&gt;
                      &lt;input class="provContacts__new-contact-field provContacts__name" [class.error]="newContactFormErrors.contactFirstName" placeholder="First name" type="text" autocomplete="given-name" formControlName="contactFirstName" /&gt;
                      &lt;input class="provContacts__new-contact-field provContacts__name" [class.error]="newContactFormErrors.contactLastName" placeholder="Last name" type="text" autocomplete="family-name" formControlName="contactLastName" /&gt;
                      &lt;input class="provContacts__new-contact-field provTaxContacts__email" [class.error]="newContactFormErrors.contactEmail" placeholder="Email address" type="email" autocomplete="email" formControlName="contactEmail" /&gt;
                      &lt;button class="btn btn-primary provContacts__new-contact-button" type="button" (click)="onNewContactAdd(payer.accountId)"&gt;Add contact&lt;/button&gt;
                      &lt;div *ngIf="addContactLoading" class="spinner-loading"&gt;&lt;/div&gt;
                  &lt;/div&gt;
              &lt;/form&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>It's the two lines starting <code>Salutation:</code> &amp; <code>PDF:</code> that I've just added.</p>
  
  <p>When I load the page having added these lines, and click the 'Edit' button to open the dialog, if a name has been selected from the drop downs, I can see it displayed in faded text in the text fields (i.e. the placeholder value), and the name is displayed before the text field (i.e. in the greeting "Hi name").</p>
  
  <p>However, if I enter a new name into the text fields, although that new name value is retained (i.e. if I close the dialog by clicking somewhere else on the page, and then reopen it by clicking the 'Edit' button again, then the new value I've typed is still there), for some reason, that value is not used in the 'greeting' (i.e. the <code>{{ payer.preferredAddresseeName }}</code> variable, even though I am setting that in the <code>updateTransactionContact()</code> function that should be called by the field's <code>ng-change</code> attribute:</p>
  
  <pre><code>updateTransactionContact($event, payer) {
      payer.loading = true;
      const contact = payer['contacts'][$event.currentTarget.selectedIndex];
      const data = (&lt;any&gt;Object).assign({}, payer, { transactionContactId: contact.userId });
      //console.log("updateTransactionContact() called from provisional-tax-reminders.ts ");
      this.provService.updateTransactionContact(data).subscribe(
          (response:any) =&gt; {
              payer.originalTransactionContactId = payer.transactionContactId;
              payer.transactionContactName = response.transactionContactName;
              console.log("payer.transactionContactName (in updateTransactionContact()): ", payer.transactionContactName);
              console.log("response (in updateTransactionContact()): ", response);
              payer.preferredAddresseeName = payer.transactionContactName.firstName;
              console.log("payer.preferredAddresseeName (in updateTransactionContact()): ", payer.preferredAddresseeName);
  
              const message = new Message();
              message.type = MessageType.SUCCESS;
              message.message = 'Transaction Contact has been updated.';
              this.messagingService.emitMessage(message);
  
              payer.loading = false;
  
              if (response.transactionContactId) {
                  payer.originalTransactionContactId = payer.transactionContactId = response.transactionContactId;
              }
          },
          (error:any) =&gt; {
              //reset the amount back to what it was originally because saving failed
              payer.transactionContactId = payer.originalTransactionContactId;
  
              const message = new Message();
              message.type = MessageType.ERROR;
              message.message = error.message || 'There was a problem updating the transaction contact. If the problem persists please contact us.';
              this.messagingService.emitMessage(message);
  
              payer.loading = false;
          }
      );
  </code></pre>
  
  <p>The debug I've added to this function is displayed when selecting another contact from the drop down- and I've added the same function call to the input fields as I have for the drop down:</p>
  
  <p>Drop down:</p>
  
  <pre><code>&lt;select class="transactionContact" *ngIf="!payer.loading &amp;&amp; payer.contacts &amp;&amp; payer.contacts.length" [(ngModel)]="payer.transactionContactId" (change)="updateTransactionContact($event, payer)" [attr.disabled]="loadingTaxpayers ? '' : null"&gt;
  </code></pre>
  
  <p>Input fields:</p>
  
  <pre><code>Salutation: Hi {{ payer.preferredAddresseeName }} &lt;br /&gt; &lt;input class="proContacts__new-contact-field provContacts__name" [class.error]="preferredContactFormErrors.contactPreferredName" placeholder={{payer.preferredAddresseeName}} type="text" ng-change="updateTransactionContact($event, payer)" autocomplete="given-name" formControlName="contactPreferredName" /&gt;
  
  PDF: Hi {{ payer.preferredAddresseeName }}&lt;br /&gt; &lt;input class="provContacts__new-contact-field provContacts__name" [class.error]="preferredContactFormErrors.contactPreferredAddresseeName" placeholder={{payer.preferredAddresseeName}} type="text" ng-change="updateTransactionContact($event, payer)" autocomplete="preferred-address-name" formControlName="contactPreferredAddresseeName" /&gt;
  </code></pre>
  
  <p>and yet for some reason, when trying to change the 'preferred contact name', by typing a new value into the text fields I've just added, when I tab out of them, and the <code>updateTransactionContact()</code> function is called, I get an error in the console that says:</p>
  
  <blockquote>
    <p>Cannot read property 'userId' of undefined
        at ProvisionalRemindersComponent.webpackJsonp../src/app/pages/dashboard/manage-tax/provisional-reminders/provisional-reminders.ts.ProvisionalRemindersComponent.updateTransactionContact</p>
  </blockquote>
  
  <p>Why is this? What am I doing wrong here?</p>
  
  <p>My guess is that this error is coming from the line:</p>
  
  <pre><code>const data = (&lt;any&gt;Object).assign({}, payer, { transactionContactId: contact.userId });
  </code></pre>
  
  <p>at the start of the <code>updateTransactionContact()</code> function, but I don't know why it's happening when the function is called by the <code>(change)</code> attribute of the text fields, and not by the <code>(change)</code> attribute of the drop down?</p>