Kaushik
Kaushik

Reputation: 133

Add methods dynamically inside a class

I am trying to add setters & getters for items that will be put in session storage. I am writing these methods inside a service. But I am getting transpile error when I try to invoke these functions in my component.

Here is the service:

@Injectable()
export class UtilitiesService {
    public keySet = [
        "CalendarDates", 
        "LastPublishedSchedule", 
        "ManageStores",
        "SelectedStore"
    ];

    constructor() {
        this.addGetSetClearFunctions();
    }

    addGetFunction(key: string) {
        UtilitiesService["get" + key] = function() {
            return JSON.parse(sessionStorage.getItem(key));
        }
    }

    addSetFunction(key: string) {
        UtilitiesService["set" + key] = function(value) {
            sessionStorage.setItem(key, JSON.stringify(value));
        }
    }

    addClearFunction(key: string) {
        UtilitiesService["clear" + key] = function() {
            sessionStorage.removeItem(key);
        }
    }

    clearAll() {
        sessionStorage.clear();
    }

    addGetSetClearFunctions() {
        for(let i = 0; i < this.keySet.length; i++) {
            this.addGetFunction(this.keySet[i]);
            this.addSetFunction(this.keySet[i]);
            this.addClearFunction(this.keySet[i]);
        }
    }
}

I am trying to call inside a set method inside a component:

this.utilService.setLastPublishedSchedule(JSON.stringify(response));

Note: utilService is injected correctly and other auxiliary functions of it(which I didn't put here are executing successfully).

Edit # 1: This is the error I am getting:

ERROR in src/app/dashboard/components/schedule/schedule.component.ts(344,22): error TS2339: Property 'setLastPublishedSchedule' does not exist on type 'UtilitiesService'.

Edit # 2: I tried calling the method by:

this.utilService['setLastPublishedSchedule'](argument here)

I got this run-time error:

ERROR TypeError: _this.utilService.setLastPublishedSchedule is not a function

Upvotes: 1

Views: 897

Answers (1)

Igor
Igor

Reputation: 62213

The error indicates the method does not exist. There are ways around this (like casting to any) but they break typesafety. A better solution is to add a method that takes a key as parameter to your service and call it that way.

setValue(key: "CalendarDates"|"LastPublishedSchedule"|"ManageStores"|"SelectedStore", value: string) {
   sessionStorage.setItem(key, value);
}
this.utilService.setValue("LastPublishedSchedule", JSON.stringify(response));

You can repeat this pattern for other methods like retrieval of the value or clearing of the value.

Also you do not have to constrain the key to a list of values but because I noticed you did have a constraint on what keys you were using I added it to the key argument parameter.

Upvotes: 2

Related Questions