Reputation: 4830
I have 2 functions which modifies lists. That lists are fields of an object. This object has a lot of lists and I don't want to write the same code few times. I need reusable function.
Now that looks like below:
setLists(): void {
if (this.product.orders !== null) {
this.orders = this.product.orders.join(', ');
} else {
this.orders = '';
}
if (this.product.relatedProducts !== null) {
this.relatedProducts = this.product.relatedProducts.join(', ');
} else {
this.relatedProducts = '';
}
}
Here are only 2 fields but in fact product has many lists. I don't want to repeat the same operation for each list.
Second boilerplate function looks like below:
updateProductLists(): void {
let splittedOrders: string[] = this.orders.split(",");
splittedOrders = splittedOrders.map(o => o.trim());
this.product.orders = new Array<string>();
this.project.orders.push(...splittedOrders);
let splittedRelatedProducts: string[] = this.relatedProducts.split(",");
splittedRelatedProducts = splittedRelatedProducts.map(r => r.trim());
this.product.relatedProducts = new Array<string>();
this.product.relatedProducts.push(...splittedRelatedProducts);
}
Upvotes: 0
Views: 95
Reputation: 8186
Here are an example of how you can create the two more generic functions listToString
and stringToList
and how you can use them in your code instead of writing the same thing over and over
// Your old method will now look like this
setLists(): void {
this.orders = this.listToString(this.product.orders);
this.relatedProducts = this.listToString(this.product.relatedProducts);
}
// Generic method for joining the arrays into strings the way you did
listToString(sourceList: any[]): string {
return sourceList ? sourceList.join(', ') : '';
}
// Your old method will now look like this
updateProductLists(): void {
this.product.orders = this.stringToList(this.orders);
this.product.relatedProducts = this.stringToList(this.relatedProducts);
}
// Generic method for splitting the strings into lists the way you did
stringToList(sourceString: string): any[] {
return sourceString.split(',').map(i => i.trim());
}
Upvotes: 2
Reputation: 435
Like you said: you should write a generic function that takes a list of any kind and performs the logic on it. Then you put all your lists in an array and iterate over it with the function you wrote. Example:
function stringifyArray(array: any[], separator: string): string {
if (!array) { // Checks for undefined, null, NaN, 0, empty string
return '';
}
return array.join(separator);
}
const oldLists: any[][] = [
this.orders,
this.relatedproducts
]
const newLists: string[] = [];
for (let i = 0; i < oldLists.length; i++) {
newLists.push(stringifyArray(oldLists[i], ','));
}
Figure out how to define generic functions for the rest of the actions you need to perform, then loop over your lists in the same way.
By the way, it might be a good idea to have separate fields for your lists and their stringified versions. That way you might not have to convert back and forth so much.
Also note that the function in my example is actually redundant, as it duplicates the behavior already present in Array.prototype.join()
. The non-redundant code would be:
const oldLists: any[][] = [
this.orders,
this.relatedproducts
]
const newLists: string[] = [];
for (let i = 0; i < oldLists.length; i++) {
newLists.push(oldLists[i].join(','));
}
Upvotes: 1