1

I have the following structure of classes:

class FilterWeekScheduleClass {

}

class FilterClassJournal { 

}

const registryFilterClasses = {
  FilterWeekScheduleClass,
  FilterClassJournal
};

class SingletonClassRegister {
  public registeredClasses = {};

  public constructor() {
    for (let obj in registryFilterClasses) {
      // CREATE INSTANCE OF obj LIKE new obj();
    }
  }
}

let a = new SingletonClassRegister();

In constructor of SingletonClassRegister class, I try to create instance based on registryFilterClasses. How to create instances proper?

I tried to do this:

class SingletonClassRegister {
  public registeredClasses = {};

  public constructor() {
    for (let obj of registryFilterClasses) {
      registryFilterClasses[obj.constructor.name] = new obj();
    }
  }
}

Is it right?

POV
  • 11,293
  • 34
  • 107
  • 201

1 Answers1

2

First I think you want an array, so let's fix registryFilterClasses:

const registryFilterClasses = [
  FilterWeekScheduleClass,
  FilterClassJournal
];

Then simply create the instances:

for (let cls of registryFilterClasses) {
  let myInstance = new cls();
}

Or the same with an object as data source:

const registryFilterClasses = {
  FilterWeekScheduleClass,
  FilterClassJournal
};
// see https://eslint.org/docs/rules/object-shorthand
// same as
//    const registryFilterClasses = {
//      FilterWeekScheduleClass: FilterWeekScheduleClass,
//      FilterClassJournal: FilterClassJournal
//    };

for (let key in registryFilterClasses) {
  // key is now the name of the class as string
  let myInstance = new registryFilterClasses[key]();
}

Update: Get class name:

class Test {}
Test.name => "Test"

const t = Test;
t.name => "Test"

const i = new t();
i.constructor.name => "Test"

Possible implementation for your registry:

class SingletonClassRegister {
  public registeredClasses = {
    MyClass
  };

  private instances = {};

  getInstanceByClassName(name) {
    if(this.instances[name] == undefined)
      this.instances[name] = new this.registeredClasses[name]();
    return this.instances[name];
  }

  getInstancesForAllRegisteredClasses() {
    return Object.keys(this.registeredClasses)
       .map(name => this.getInstanceByClassName(name));
  }
}
Christoph Lütjen
  • 5,403
  • 2
  • 24
  • 33
  • But why I can not store in object? – POV Oct 21 '18 at 19:41
  • I need object to provide only one item in object, without duplicates – POV Oct 21 '18 at 19:42
  • If you prefer an object, that's ok, but the syntax for objects is { propertyName: value }. In your code the property name is missing. – Christoph Lütjen Oct 21 '18 at 19:43
  • Okay, how to get name of `cls`? I want to do this: `registryFilterClasses[cls] = new cls()` – POV Oct 21 '18 at 19:45
  • In your question, obj is the class, not an instance, that's why you need to use obj.name instead. "After the new" you have an instance of your class and then it's instance.constructor.name. S.a. https://stackoverflow.com/questions/13613524/get-an-objects-class-name-at-runtime-in-typescript – Christoph Lütjen Oct 21 '18 at 19:58
  • How to create instance base on string name? – POV Oct 21 '18 at 20:06
  • To be hornest, I forgot the shorthand syntax, I fixed this in my answer, so now you have an object with key=class name pointing to the class where it's easy to do a lookup. Will this work for you? – Christoph Lütjen Oct 21 '18 at 20:21