Waiting until static variable completes initialization in constructor - static

If i have classes like the following:
export class ClassA{
static Alpha: string;
static Beta: string[];
constructor(jsonData: any){
ClassA.Alpha = jsonData.alpha;
ClassA.Beta = new Array<string>();
for(let i=0; i<jsonData.betaList.length; i++){
ClassA.Beta.push(jsonData.betaList[i]);
}
//do whatever it takes that takes a really long time
}
}
export function foo(list: string[]){
//something
}
and when i write a code like the following:
let dat = //whatever to parse a certain json file
new ClassA(dat);
foo(ClassA.Beta);
I want to make sure that the initialization of ClassA.Beta is finished before foo() is called. is it possible? or does Typescript automatically handle such cases already?

You can be sure foo() will be executed after ClassA constructor is finished. Unless it uses any kind of async calls (Promises, setTimeout, etc.).
Having said that I think that current design is not the best one. Do you really want to initialize class static properties each time the constructor is called?
The better approach would be to have separate static initialization logic into Init() static method and call it in the proper place of your application:
export class ClassA{
static Alpha: string;
static Beta: string[];
public static Init(jsonData: any): void
{
ClassA.Alpha = jsonData.alpha;
ClassA.Beta = new Array<string>();
for(let i=0; i<jsonData.betaList.length; i++)
{
ClassA.Beta.push(jsonData.betaList[i]);
}
//do whatever it takes that takes a really long time
}
constructor()
{
//Initialize instance members here. Not static
}
}
export function foo(list: string[])
{
//something
}
let dat = {};//whatever to parse a certain json file
ClassA.Init(dat);
foo(ClassA.Beta);
This approach will allow you later to make Init() return Promise to make your code async if you will need to.

Related

how to change value in struct globally in swift

So I have an api request that requests a bunch of data from a fake api url, the data I am getting is being put on a placeholder, I just want to have a global variable to be able to use that array of codable data in my collectionviews.
struct productsList{
static var itemsList = [ProductItem]()
}
func getProducts() {
storeRepo
.getAllProducts()
.subscribe { result in
productsList.itemsList = result
for item in productsList.itemsList{
print(item.category)
}
} onError: { error in
print(error.localizedDescription)
}.disposed(by: disposeBag)
}
func printReuslt() {
for i in productsList.itemsList{
print(i.id)
}
}
note that it's not printing the printResult() but it's looping inside of the .subscribe
note that i am using Moya as well as RXswift
What you're looking for is called a Singleton. Swift makes this extremely easy to do. Basically, the short and sweet is that the struct you create, initializes itself as a property of itself. Anytime you access (In this example) APIHandler.shared you'll get a reference to the only single object, which has your other properties dataObj1 and someObj2 from this example.
class APIHandler {
let shared = APIHandler()
var dataObj1: YourObj?
var someObj2: YourObj2?
init() {
self.someObj1 = yourMethodCall()
self.someObj2 = someCalculation()
}
}
This is how you access it from another class. BE CAREFUL you can access APIHandler.someObj which would result in a null reference exception if you don't have an object created, so when doing this always access the shared property.
class MainClass {
let apiHandler: APIHandler?
override func viewDidLoad(...) {
super.viewDidLoad(...)
apiHandler = APIHandler.shared
}
}

How to call a non-static method from static method in JavaScript

I want to call a non-static method from static method. Both are in same class.
How can I achieve this ?
class Home extends React.Component {
constructor(props) {
super(props);
console.log("in constructor props =", this.props.mainData);
this.state = {
data: null,
isFetch: false,
clickEvent: false
}
this.allDataShow = this.allDataShow.bind(this);
this.upcomingShow = this.upcomingShow.bind(this);
}
allDataShow(){
allData(this.props.mainData);
}
upcomingShow(){
upcoming(this.props.mainData);
}
static changeData(option) {
console.log("I'm home changeData");
switch (option) {
case "All":
console.log("All");
allDataShow();
break;
case "Upcoming":
console.log("Upcoming");
console.log("this",this);
inst.prototype.upcomingShow();
break;
}
}
render(){...}
}
This is updated code in which I am calling changeData in another component, and in changeData I call non-static method. But it doesn't work.
The non-static method will be on the prototype, so reference My.prototype or this.prototype (this will refer to My inside the static method):
class My{
static my1(){
this.prototype.my2();
}
my2(){
console.log("my2 is executing");
}
}
My.my1();
That said, this is very weird - non-static methods are generally useful to refer to and use instance data. If the method uses instance data, it will need an instance to run sensibly. If the method doesn't use instance data, it probably shouldn't be a prototype method, but a static method or a standalone function.
You must instantiate a new "My" class and then call from there. You can either require the class as a parameter or make a new one in the method.
class My{
static my1(instance){
//something like this
instance.my2();
}
my2(){
console.log("my2 is executing");
}
}
var myInstance = new My();
My.my1(myInstance);
OR
class MyOther{
static my1(){
//something like this
var myInstance = new My();
myInstance.my2();
}
my2(){
console.log("my2 is executing");
}
}
MyOther.my1();

Extending class with no copying constructor (with private param)

During trying to enhance Angular's ComponetFixture I noticed that this can not be done because of no copying constructor for this class. (Or am I wrong?)
Let's suppose we have a class:
class A
{
constructor(public pub, private priv) { }
}
And I want to create class BetterA based on class A, so:
class BetterA extends A
{
constructor(a: A)
{
// super(a); <----- this can not be done, so maybe...
// super(a.pub, a.priv) // ...this could be better option, but...
}
myFunction(a: string) { return a; }
}
...second parameter is PRIVATE. I can not access it ;/
What can I do in that case?
I know that one of solutions is to use prototype like this:
A.prototype['myFunction'] = function(a: string) { return a; } // this must be done with function keyword, it's not working with ()=>{} !!! /there are problem with this pointer/
But then I have to write something weird like this:
console.log( classAobject['myFunction']("abc") );
Instead of
console.log( classAobject.myFunction("abc") );
or
I can do it by composition:
class B
{
public a: A; // or constructor(public a: A)
myFunction(a) { return a; }
}
But is seems not too elegant.
Is there any better solution?
Edit #1
I've just discovered that this syntax:
Class.prototype.NewFunction = function() { this.x.y.z = 123 }
is valid but it produces compiler errors, code works but we get:
'Property 'TextOf' does not exist on type 'Class'
and when you try to call it like this:
objectOfClass.NewFunction()
makes:
'Property 'NewFunction' does not exist on type 'Class'
BUT
It's gonna working only when we use function keyword. When we use lambda expression there will be same strange invisible problems with some functions.
I think composition is the way to go here. please remember that you are building a class and not a method which requires the new operator in order to instantiate your object. this may be what your looking for
class A{
tPub;
constructor(public pub, private priv) {
this.tPub=pub
}
}
class B extends A{
constructor(pub){
super(pub)
}
myFunc(){} //equiv to B.prototype.myFunc
}
export const myClass=new B();
//another file
import {myClass} from './file'
let m=myClass.myFunc();
unfortunately, by setting priv to private it will do exactly what it is told and make it a private object. you also could do without the constructor depending on what you would like to do with your class.

Haxe Typedef Array?

I'm very new to Haxe, and trying to make a simple tile-map creation program with OpenFL. However, I'm not sure how to make an array of classes (each individual tile types) I have made. It seems that a typedef is what I want, but I'm not sure how to incorporate this into an array so I can iterate through them.
Thanks in advance,
- RealFighter64
I assume the tile classes are all subclasses of a base class. In this case, just put them into an Array<Class<Base>> as follows:
class Base {
}
class A extends Base {
public function new():Void {}
}
class B extends Base {
public function new():Void {}
}
class C extends Base {
public function new():Void {}
}
class Test {
static function main() {
var classArray:Array<Class<Base>> = [A, B, C];
for (cls in classArray) {
var inst = Type.createInstance(cls, []);
}
}
}
If they do not have a common super class, use an Array<Dynamic> instead.

What is the difference between setting a default value of a class property inside or outside of the constructor?

My code looks like this:
interface IConfigService {
admin: {
x: number;
}
class ConfigService implements IConfigService {
admin = this.getDefaultAdminConfigs();
constructor() {
this.admin = this.getDefaultAdminConfigs();
}
private getDefaultAdminConfigs = () => {
return {
x: 99
};
}
}
Can someone tell me is there any difference between setting the value of admin outside or inside the constructor when I am using AngularJS to set up my configService?
Not in your case. It is simply a matter of what gets executed last. The constructor body is executed after the inline initialization e.g. :
class Foo {
admin = 123;
constructor() {
this.admin = 456;
}
}
var foo = new Foo();
console.log(foo.admin); // 456
It might more relevant when you have an XHR in the constructor or some other property you want to init before this one.
Note: Inline initialization is also executed in order of definition.

Resources