Roots Discourse

[SAGE 10] JS - cannot call async functions

Hey all,

I’ve got a variable I want to populate with a fetch(). For this I would need an async function. But I’m unable to create one with Sage 10. How to create an async function with sage 10?

Background
In app.js I try to replicate the code from this documentation

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  const result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}

asyncCall();

The terminal gives me no errors in running it in development. But when loading the page I get this error:

app.js?ce4c:18 Uncaught TypeError: Cannot read property 'mark' of undefined
    at _asyncCall (app.js?ce4c:18)
    at asyncCall (app.js?ce4c:18)
    at eval (app.js?ce4c:25)
    at Module../resources/scripts/app.js (app.js?id=e093a415a262fd676e7b:18)
    at __webpack_require__ ((index):820)
    at __webpack_exec__ (app.js?id=e093a415a262fd676e7b:166)
    at app.js?id=e093a415a262fd676e7b:167
    at Function.__webpack_require__.O ((index):856)
    at app.js?id=e093a415a262fd676e7b:168
    at webpackJsonpCallback ((index):943)

What part am I doing wrong? The fetch works top-level, but then I would need an endless .then()

Is this the only JS in your project? The error says it’s trying to read a property called mark off of something that’s undefined, and there doesn’t immediately seem to be anything in your posted code that might include that.

After your reply I’ve cleared app.js, customizer.js and editor.js. And the error still persisted. So, the answer would be, yes, it’s the only js code.

@oxyc. thanks for the reply. But I can’t figure out on my own what the next step should be. I see you reffer to a bug in devDependencie "@tinypixelco/laravel-mix-wp-blocks": "1.0.0", But I already have version 1.1.0 installed. This would patch the problem you referred to, right?

I’ve created a clean Sage 10 install and added the async test to app.js. This resulted in the same error. Can I safely say that the error is not due to my own theme? :slight_smile:

Sorry, yes it’s not very obvious in that thread actually. laravel-mix-wp-blocks mentions it in the readme, you need to disable regenerators when you use mix.block():

mix.block('resources/assets/scripts/blocks.js', 'scripts', {
  disableRegenerator: true,
})
3 Likes

@oxyc, oh sweet. That works! In the Sage theme that would translate in webpack.mix.js to:

  .blocks('resources/scripts/editor.js', 'scripts',{
    disableRegenerator: true,
  })

original:

.blocks('resources/scripts/editor.js', 'scripts') // line 30

Thanks!

1 Like

Hi guys, thanks for this fix!

However, I noticed if you have a lot of blocks defined like me, the only way to use an async function in ONE of your scripts (app.js for example), is to add the

disableRegenerator: true

option to ALL blocks, so this:

mix
	.js('resources/assets/scripts/app.js', 'scripts')
	.js('resources/assets/scripts/customizer.js', 'scripts')
	.blocks('resources/assets/scripts/editor.js', 'scripts')
	.blocks('resources/assets/scripts/blocks/banner/banner.editor.js', 'scripts')
	.blocks('resources/assets/scripts/blocks/card/card.editor.js', 'scripts')
	.blocks('resources/assets/scripts/blocks/card-carousel/card-carousel.js', 'scripts')
	.blocks('resources/assets/scripts/blocks/card-carousel/card-carousel.editor.js', 'scripts')
	// ... 20 more
	.autoload({jquery: ['$', 'window.jQuery']})
	.extract();

becomes:

mix
	.js('resources/assets/scripts/app.js', 'scripts', {
		disableRegenerator: true
	})
	.js('resources/assets/scripts/customizer.js', 'scripts', {
		disableRegenerator: true
	})
	.blocks('resources/assets/scripts/editor.js', 'scripts', {
		disableRegenerator: true
	})
	.blocks('resources/assets/scripts/blocks/banner/banner.editor.js', 'scripts', {
		disableRegenerator: true
	})
	.blocks('resources/assets/scripts/blocks/card/card.editor.js', 'scripts', {
		disableRegenerator: true
	})
	.blocks('resources/assets/scripts/blocks/card-carousel/card-carousel.js', 'scripts', {
		disableRegenerator: true
	})
	.blocks('resources/assets/scripts/blocks/card-carousel/card-carousel.editor.js', 'scripts', {
		disableRegenerator: true
	})
	// ... 20 more
	.autoload({jquery: ['$', 'window.jQuery']})
	.extract();

That just feels wrong…
Isn’t there an easier way of setting this globally?

Thanks!