Reputation: 1939
I have a string that I want to use in an API factory to instantiate the correct object from a class. Here is the code:
import StoryApiService from './story'
import AssignmentApiService from './assignment'
let apiTypes = {
story: null,
assignment: null
}
let token
const getApi = (newToken, apiType = 'story') => {
const isNewToken = newToken => newToken !== token
const shouldCreateService = !apiTypes[apiType] || isNewToken
if( shouldCreateService ) {
const capitalizedServiceType = apiType.charAt(0).toUpperCase() + apiType.slice(1)
// this line is what I need help with
apiTypes[apiType] = new `${capitalizedServiceType}ApiService`(token)
}
return apiTypes[apiType]
}
So basically depending on the apiType
argument that is passed in I want to instantiate a new object from the correct class. I want to avoid using if/else
and switch
statements if possible because I have a bunch of different apiServices that I will use and I think this way will be cleaner if its possible.
I know the line in the code above won't work as written but its pseudo code to show the effect I want to achieve.
Upvotes: 1
Views: 56
Reputation: 106077
Rather than trying to instantiate a class from a string name (with some complex capitalization/concatenation logic), create an object that maps apiType
names directly to their corresponding classes:
import StoryApiService from './story'
import AssignmentApiService from './assignment'
const services = {
story: StoryApiService,
assignment: AssignmentApiService,
}
const serviceInstances = {
story: null,
assignment: null,
}
let token
const getApi = (newToken, apiType = 'story') => {
const isNewToken = newToken !== token
const shouldCreateService = !serviceInstances[apiType] || isNewToken
if (shouldCreateService) {
token = newToken
serviceInstances[apiType] = new services[apiType](token)
}
return serviceInstances[apiType]
}
Upvotes: 4
Reputation: 53616
Do the same thing you're already doing with apiTypes[apiType]
: access the object that holds that class/constructor function.
E.g. if it's a class that you defined in window
scope:
const ObjectType = window[`${capitalizedServiceType}ApiService`];
And then remember to verify that's defined because you have no guarantee your string actually maps to a function or class:
if (ObjectType) {
apiTypes[apiType] = new ObjectType(token);
} else {
console.error(`Api service for "${capitalizedServiceType}" does not exist.`);
}
Upvotes: -1