Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

262
Vistas
Singleton config - how to avoid returning a Promise in typescript

I have my Configuration class:

interface ConfigObject {
  apiUrl: string;
  identityPoolId: string;
  identityPoolRegion: string;
  region: string;
  userPoolId: string;
  userPoolWebClientId: string;
}

class Configuration {
  private static _instance: ConfigObject;

  public static get Instance() {
    return (
      this._instance ||
      this.getConfig<ConfigObject>().then((config) => {
        this._instance = config;
        return config;
      })
    );
  }

  private static async getConfig<TConfig>(): Promise<TConfig> {
    const response = await fetch('env.json', {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data = await response.json();
    return data;
  }
}

export default Configuration.Instance;

and I want to access it's values in my service:

export default class APIService {
  static baseURL: string = `${Config.apiUrl}/mocked`;

Yet at the time of accessing Config.apiUrl is undefined

How can I make sure that the getConfig fetch gets executed and the actual object is returned instead?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You can't make an asynchronous process synchronous. But you can make your module wait to load until you've read that JSON file, by using top-level await, which is now broadly supported in browsers and by bundlers.

async function getConfigData(): Promise<ConfigObject> {
    const response = await fetch('env.json', {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data: ConfigObject = await response.json();
    return data;
}
const data = await getConfigData(); // *** Module load waits here

class Configuration {
    private static _instance: ConfigObject;

    public static get Instance() {
        if (!this._instance) {
            this._instance = data;
        }
        return this._instance;
    }
}

export default Configuration.Instance;

That said, there doesn't seem to be any purpose to the Configuration class, just export the data directly:

async function getConfigData(): Promise<ConfigObject> {
    const response = await fetch('env.json', {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    });
    if (!response.ok) {
      throw new Error(response.statusText);
    }
    const data = await response.json();
    return data;
}
const data: ConfigObject = await getConfigData(); // *** Module load waits here

export default data;

Side note: Since objects are mutable by default, any module that imports the configuration data can modify it (for instance, if there's a data.example property, by doing data.example = "some value"). Maybe you want it to be mutable, in which case don't do anything, but if you don't you might use Object.freeze to make everything about the object read-only:

// ...
const data: ConfigObject = await getConfigData();
Object.freeze(data); // *** Freezes the object

export default data;
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda