Dynamically Reference Class Variables from inside a function

Hi,

I was basically wondering how to reference the variables previously set in the class from within a function based on some dynamic input.

as an example to help clarify what I mean, here is my code.

First I have an ion-input field in the HTML file:

         <ion-item>
          <ion-label position="floating">Nickname</ion-label>
          <ion-input 
            type="text"
            name="nickName"
            value="{{this.nickName}}"
            (ionBlur)='verifyFieldUpdate($event.target.name, $event.target.value)'
          ></ion-input>

at the top of the .ts file I declare and set the values (with other functions) of a few variables:

title: string;
firstName: string;
lastName: string;
nickName: string;

Here is the function in the .ts file:

verifyFieldUpdate(key, value) {
// I want to do the following
// let testKey = this.key;
// key would be the name of the ion-input field in question.

    let testKey = this.title;

    if (value === testKey) {
      console.log ('SAME');
    } else {
      console.log ('DIFF');
      console.log('HTML Key: ', key);
      console.log('HTML Value: ', value);
    }
  }

but of course

let testKey = this.key;

gives an error, because it does not exist, but how would I reference that variable (title / nickname / etc) from the Key passed into the function?

Is there a way almost like in the html to do?

let testKey = this.{{key}};

Thank you in advance!
Kind Regards

i really don’t get it Can you provide a StackBlitz?

Sure @EinfachHans ,

Please excuse, this is my first time using StackBlitz and I am getting an error on the (ionBlur) that I do not get on my localhost…

But the code is there.
Here is the link

To simplify I have removed much and tried to stay with what we are talking about, here is the code:

.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  title = 'Mrs.';
  firstName: 'Luzaan';
  lastName: 'Rocks';
  nickName: 'Lu';

  constructor(public navCtrl: NavController) {

  }

  verifyFieldUpdate(key, value) {
    let testKey = this.title;
    // let testKey = this.key;
    
    if (value === testKey) {
      console.log ('SAME');
    } else {
      console.log ('DIFF');
      console.log('HTML Key: ', key);
      console.log('HTML Value: ', value);
    }
  }

}

.html

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>

<ion-content>

  <ion-grid>
   <ion-row>
      <ion-col size-sm="6" offset-sm="3">
        <ion-item>
          <ion-label position="floating">Title</ion-label>
          <ion-input 
            type="text"
            name="title"
            autocomplete
            autocorrect
            value="Mrs."
            (ionBlur)='verifyFieldUpdate($event.target.name, $event.target.value)'

          ></ion-input>
        </ion-item>
      </ion-col>
      <ion-col size-sm="6" offset-sm="3">
        <ion-item>
          <ion-label position="floating">Nickname</ion-label>
          <ion-input 
            type="text"
            name="nickName"
            autocomplete
            autocorrect
            value="Nickname"
            (ionBlur)='verifyFieldUpdate($event.target.name, $event.target.value)'
          ></ion-input>
        </ion-item>
      </ion-col>
    </ion-row>
    <ion-row>
      <ion-col size-sm="6" offset-sm="3">
        <ion-item>
          <ion-label position="floating">First Name</ion-label>
          <ion-input 
            type="text"
            name="firstName"
            autocomplete
            autocorrect
            value="Luzaan"
            (ionBlur)='verifyFieldUpdate($event.target.name, $event.target.value)'
            ></ion-input>
        </ion-item>
      </ion-col>
      <ion-col size-sm="6" offset-sm="3">
        <ion-item>
          <ion-label position="floating">Last Name</ion-label>
          <ion-input 
            type="text"
            name="lastName"
            autocomplete
            autocorrect
            value="Rocks"
            (ionBlur)='verifyFieldUpdate($event.target.name, $event.target.value)'
          ></ion-input>
        </ion-item>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

as mentioned though, (ionBlur) function works fine on my local machine

so basically instead of me having to type out all the conditions manually, ie:

let testKey = this.title;
let testKey = this.firstName;

etc.

I just want to use something like

let testKey = this.{{key}} 

to get the value from the top to validate against.

I hope this makes it more clear?

Okay i think i get it. Key is something like “title”, “nickName” (same as your variables) and you want to check if this is the same.

But how you are doing it is definitely not a good way. You should handle this with ngModel.

Can you give me more details about why you want to check this?

yes this is correct.

Should I still use ngModel even if I just want to update a single field on change?

Basically what needs to happen is that should a user want to update these details, they just change the field ie. Firstname Surname Nickname etc. but on ionBlur it then verifies if the field is the same as what is the current value, else then run an update function.
Dont know if it matters but the update function in this specific case will be a http request that updates a Wordpress User.

Hopes that gives more context?

Okay i understand. So you should use ngModel on every input. Everytime. Going through $event.target.value is a unnecessary bad practice in angular.

Also for your context: You should not directly update after the input blur event. You should think about if a “Save” Button isn’t a better opportunity for you.

But if you really want to do it like this, you should declare 4 variables like “newTitle”, “newName”, etc and bind them via ngModel to the input. When the Page loads (OnInit Methode) you set these variables to the current user data. Then in the ionBlur you can compare this Values to the current user data. But you should not use the key thing, just compare all variables.

Let’s come back to the save Button. I prefer this and you can automatically show or hide it, depends on when the user data changed or not.

1 Like

Thank you very much for your inputs.

Can you perhaps elaborate a bit on why this is a better option? I understand for a blank form the first time, but in the case of just updating a specific field?

then regarding:

the 4 fields I have given was just an example of 4 fields, however in reality there can be X amount of fields.
Will I still have to declare them each individually even if there are 50 fields? This is where my reasoning for “the key thing” :slight_smile: came to be :slight_smile:

Thank you again, I appreciate your inputs!

I understand your question as type of an user is updating his profile. A normal UX is that you have to save the changes, that’s why i’ preffering this.

If you have X Variables (probably in an object) i think you should copy the whole object to use for the two way data binding and then compare the values of the two objects.

1 Like

Thank you very much. I will do as you suggest and move towards the Save Button option as well as then add a proper form element.

Would you perhaps give me a code example of what you mean here?

Lets say you have the current user data with an object like

user = {
  name: "blabla",
  nickName: "..."
  ...
}

than you can deepcopy it to another object and use this second object for the ngModels. For deepcopying there are sone ways. For simple ways i preffer

const copyedUser = JSON.parse(JSON.stringify(user));

than you can compare the user and the copyedUser.

ok thank you, I will have to spend some time to understand how to do this.
Thank you for the inputs! Much appreciated!

In addition to @EinfachHans’s excellent advice here, another option for deep copying that I prefer is lodash’s clone(). If you install it as lodash-es, you won’t pull in the entire library, just the specific functions you’re using.

Additionally, you might want to consider a reactive form instead of ngModel. Reactive form controls know whether they’ve been touched or changed, and have a lot of validation infrastructure.

Thank you @rapropos will look into it, and yes, will use reactive form thank you.