1

I have a Singleton-Class FooService that is loaded via an import-map. I'd like to (a)wait for it and use it in various async functions like so:

declare global {
  interface Window {
    System: System.Module
  }
}

const module = window.System.import('@internal/foo-service')
const fooService = module.FooService

async function func1() {
  await fooService.doBar()
  .
  .
}

async function func2() {
  await fooService.doBar2()
  .
  .
}

But I could only get it to work like this:

declare global {
  interface Window {
    System: System.Module
  }
}

async function getfooService() {
  const module = await window.System.import('@internal/foo-service')
  return module.FooService
}

function func1() {
  getfooService().then(fooService => fooService .doBar())
  .
  .
}

function func2() {
  getfooService().then(fooService => fooService.doBar2())
  .
  .
}

How can I achieve this without loading it anew every time I want to use it?

leonheess
  • 16,068
  • 14
  • 77
  • 112

2 Answers2

4

Your first guess was nearly fine. Notice that the module returned by import is a promise, so you need to use it as

const fooService = window.System.import('@internal/foo-service').then(module =>
  module.FooService
);

async function func1() {
  (await fooService).doBar();
//^                ^
  …
}

async function func2() {
  (await fooService).doBar2();
//^                ^
  …
}

Btw I would recommend to avoid using a FooService "module object" (or worse, class) and instead just export named functions, so that you can drop the .then(module => module.FooService).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Works perfectly but now Jest is tripping up with `Cannot read property 'import' of undefined` which it didn't before – leonheess Jan 05 '21 at 14:08
  • @leonheess I don't think there's a `window.System` in Jest. You should probably [ask a new question](https://stackoverflow.com/questions/ask) about that, though – Bergi Jan 05 '21 at 15:23
  • I created one [here](https://stackoverflow.com/questions/65609648/jest-cannot-read-property-import-of-undefined) – leonheess Jan 07 '21 at 09:28
0

you could try to wrap it in IIFE, like this:


declare global {
  interface Window {
    System: System.Module
  }
}

// Wrap rest of the code in IIFE
(async () => {
  const module = await window.System.import("@internal/foo-service");

  // Use await keyword if FooService/doBar/doBar2 are async
  const fooService = await module.FooService;
  const doBar = await fooService;
  const doBar2 = await fooService;

  async function func1() {
    doBar();
  }

  async function func2() {
    doBar2();
  }
})();
PeterDanis
  • 8,210
  • 2
  • 13
  • 23