The issue in a single line: Is it possible to pass a property as a parameter to a functon and update it in the function itself?
Scenario
I have a profile class in my ionic project which opens several modals that are bound to the properties in it (name, gender, email, etc). All these methods are same, the only thing that makes them different is where to set the response after the modal is closed.
One example:
async changeName() {
const modal = await this.modalCtrl.create({
component: ChangeNameModalPage,
cssClass: 'default-modal',
componentProps: {
'content': this.name // get class property value
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
this.name = modalDataResponse.data; // set value back to class property
}
});
return await modal.present();
}
I have 6 functions that are the same as this, the only difference is the property that is consumed/set in the function.
The problem
This view will, probably, grow up in a few months from now receiving other properties and they will do the exact same thing, where the property will be added, which will cause too much code duplication.
My idea is to make it OO so the maintenance would be easier. I'm still learning typescript and I don't know if it has something similar to java reflection, where this kind of update would be a piece of cake.
My dream world would be this (roughly speaking):
async changeField(classProperty, modalPage) {
const modal = await this.modalCtrl.create({
component: modalPage, // the component that will be used
cssClass: 'default-modal',
componentProps: {
'content': classProperty // get current property value
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
classProperty = modalDataResponse.data; // set back the property value
}
});
return await modal.present();
}
async changeName() {
await this.changeField(this.name, ChangeNameModalPage)
}
async changePhone() {
await this.changeField(this.phone, ChangePhoneModalPage)
}
async changeEmail() {
await this.changeField(this.email, ChangeEmailModalPage)
}
What have I found so far
Throughout several posts in stackoverflow I came to know about the generic in keyof operator, but I am able to get the value but not set it back to the property that comes as a parameter.
I've checked the typescript documentation and other posts to know about it, but I can't find something that specifically sets the value back to the property.
The closest that I've found was this post here where the user is able to increment the external variable when it is a number. I've tried doing so with string but when I do so it states that my type cannot be used as an indes type when trying to set the value back to it, although when sending it, it works just fine (I changed the property to any in the example below):
Is this type of interaction in the code that I'm trying to achieve possible with typescript? Or am I doing something wrong that I'm not being able to spot?
Solution
As taught by @Cerbrus in the answer below, here's the (much more tidy, beautiful and maintainable) code.
async changeName() {
await this.changeField('name', ChangeNameModalPage);
}
async changeBirthday() {
await this.changeField('birthday', ChangeBirthdayModalPage);
}
async changeCPF() {
await this.changeField('cpf', ChangeCPFModalPage);
}
async changePhone() {
await this.changeField('phone', ChangePhoneModalPage);
}
async changeEmail() {
await this.changeField('email', ChangeEmailModalPage);
}
async changeGender() {
await this.changeField('gender', ChangeGenderModalPage);
}
async changeField(classProperty: keyof this, modalPage) {
const modal = await this.modalCtrl.create({
component: modalPage,
cssClass: 'default-modal',
componentProps: {
'content': this[classProperty]
}
});
modal.onDidDismiss().then((modalDataResponse) => {
if (modalDataResponse.data !== null && modalDataResponse.data !== undefined) {
this[classProperty] = modalDataResponse.data;
}
});
return await modal.present();
}