Reputation: 2161
I want to call a method automatically when a TS class is accessed, similar to java's static{ }
.
For example, if I implement a constants class in Java:
public class Constants
{
public static final String FOO;
static
{
// ... creates a http request ...
FOO = // ... gets "http:/.../api/foo" from server
}
}
How can I implement something like this in TypeScript?
Currently, I'm using:
export class Constants
{
public static FOO;
public static ensureInitialized(callback)
{
if (this.FOO == null)
{
let request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4)
{
FOO = request.responseText;
callback();
}
};
request.open('POST', "http:/.../api/foo", true);
request.send('');
}
else callback();
}
}
But that requires an active call to ensureInitialized()
to all the methods using this constant. Are there any TS equivalent to static{ }
in Java?
Upvotes: 2
Views: 916
Reputation: 1138
Normally we are expecting to execute static upfront before even using that value
export class Constants {
static foo: any;
static __static_initialized: boolean = false;
static __static_initialize() {
if (Constants.__static_initialized) { return; }
Constants.__static_initialized = true;
fetch("http:/.../api/foo", { method: "POST" })
.then(response => Constants.foo = response.text())
.catch(console.error);
}
}
Constants.__static_initialize();
Upvotes: 1
Reputation: 31803
You really should try to learn the TypeScript language and write idiomatic code. Many programmers come to TypeScript under the mistaken impression that the addition of static typing by TypeScript turns JavaScript into Java when nothing could be further from the truth. In order to use TypeScript effectively, you must understand JavaScript.
One can learn JavaScript very well from learning TypeScript, but only when understanding that TypeScript does not add any of the following:
In idiomatic TypeScript/JavaScript, such an approach would make no sense since the same behavior can be concisely and elegantly achieved, while the idea of a static initializer on a class is borderline incoherent.
Here is a revised version
let foo: string | undefined;
export const Constants = {
get FOO() {
if (!foo) {
fetch("http:/.../api/foo", { method: "POST" })
.then(response => foo = response.text())
.catch(console.error);
}
return foo;
}
}
Advantages include brevity, encapsulation, and having people understand what you are doing via recognition of an idiom.
Note: There is a problem of asynchronous lazy initialization that this answer does not attempt to address since it is out of scope.
Upvotes: 1