0

Not sure how 'smart' of an idea this is but I really wanted to experiement with Vue and Javascript and see if I could condense some code a bit (you could say I've done the opposite).

Anways... I have an data object in vue:

            eventOptions: {
                eventType: {
                    data: [],
                    method: 'getEventTypeList',
                    service: 'ReportEventService',
                },
                eventSeverity: {
                    data: [],
                    service: 'ReportEventService',
                    method: 'getSeverityList',
                },
                eventImpact: {
                    data: [],
                    service: 'ReportEventService',
                    method: 'getBusinessImpactList',
                },
                eventStatus: {
                    data: [],
                    service: 'ReportEventService',
                    method: 'getEventStatusList',
                },
            },

And I want to loop through it in the following method and create a function like:

ReportEventService.getEventStatusList() which is referencing an imported javascript file.

        async setEventOptions() {
            const promises = Object.keys(this.eventOptions).map((key) => {
                const { method, service = this.eventOptions[key]
                return new Promise(async (resolve, reject) => {
                    try {
                        const response = await service[method]();
                        resolve(response);
                    } catch (e) {
                        reject(e);
                    }
                });
            });

            Promise.all(promises)
                .then((responseArray) => {
                    Object.keys(this.eventOptions).forEach((key, index) => {
                        this.eventOptions[key]['data'] =
                            responseArray[index].data;
                    });
                })
                .catch((e) => console.log(e));
        },

Unfortunately, it's not working.

This line fails:

const callback = service[method]();

Any idea how I can convert two strings to make a function that I can execute? I also understand this undertaking is silly and I can probably just list them out and it would be 10x easier.

I did try:

const func = new Function(`${service}.${method}()`)

The error I get is: TypeError: service[method] is not a function

3
  • “Variable” variables in JavaScript - put your services in an object/map and look them up by the name. Commented Jul 15, 2021 at 20:37
  • 1
    Your nearly there, just don't put the service in quotes. eg. service: ReportEventService Commented Jul 15, 2021 at 20:42
  • @Keith put that answer down below and I'll mark it as the answer. Commented Jul 15, 2021 at 20:45

2 Answers 2

4

Object literals can store Object / classes / functions.. etc.

Your currently just storing a string, 'ReportEventService', so when you call the method your doing 'ReportEventService'[method]() and that doesn't make much sense.

But if you store the Object that is ReportEventService instead, you will be calling.. ReportEventService[method]()

IOW: service: ReportEventService, instead of service: 'ReportEventService',

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the awesome explanation!
2

If you can use any as part of eventOperations, then there is no reason at all to use strings.

Instead make them into callbacks:

eventType: {
    data: [],
    method: 'getEventTypeList',
    service: 'ReportEventService',
},

can become

eventType: {
    data: [],
    callback: () => ReportEventService.getEventTypeList(),
},

Then you can call it as

const response = await callback();

It you can use a lot more tools to verify your code. At the very least a rename refactoring will work without needing to consider random strings. You can also verify if the method exists or if it is called with the correct number of parameters.

Moreover, you also get more freedom - if you change ReportEventService.getEventTypeList() in the future to require parameters, you can change the callback to () => ReportEventService.getEventTypeList("foo", 42) without having to change the code that consumes it.

2 Comments

This is certainly good advice, especially with refactoring etc. I think the OP was mainly experimenting with his comment. really wanted to experiement But having this extra info is very useful, so upvote from me..
This is definitely cleaner then my implementation and I will probably end up using it. Thanks for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.