Skip to content

Conversation

@nielslyngsoe
Copy link
Member

@nielslyngsoe nielslyngsoe commented Mar 9, 2025

Summary:

Making context consumption .asPromise() result in a Rejected Promise if the context did not show up within one frame.
See examples below on how to handle Rejected Promises.

This means that the getContext() results in undefined, if the context did not show up or if the host gets disconnected in the meantime.

As well introducing a umbOpenModalmethod to simplify opening a modal, and making the opening of Modals result in a Promise Rejection when closed, see examples below to learn how to handle rejected Promises.

General corrections to respect failing promises and make sure to react properly to such.

How to handle Promise Rejections:

In some cases you need to handle the Rejection; in others, we handle it for you.
To understand how it works you need to get your head around how Async Methods/Promises are handled in general.

In short you need to be aware about if the rejection is taken care of for your Promise Chain.

Let's look at an actual example:

async function methodA() {
    return await methodA();
}

async function methodB() {
    throw new Error('Something is rejecting this promise.')
}

const result = await methodA();

The rejection results in an error in the browser, to prevent the error we need to catch the Rejected Promise, this can be done like this:

async function methodA() {
    return await methodA().catch(() => undefined);
}

async function methodB() {
    throw new Error('Something is rejecting this promise.')
}

const result = await methodA();

In this case the result then becomes undefined, because that is what the given method to catch returns.

What we need to learn is that we do not need to handle the rejection for every async method call, we can choose just to handle this for the start of the Promise Chain. In this way:

async function methodA() {
    return await methodA();
}

async function methodB() {
    throw new Error('Something is rejecting this promise.')
}

const result = await methodA().catch(() => undefined);

Now we both support if methodA and if methodB resulted in a rejection.

To understand why we need to learn this we can look at a few concrete examples:

How to handle Promise Rejections of modal.onSubmit() or the new umbOpenModal() or existing umbConfirmModal()
For v.16, we need to handle the rejection of modal.onSubmit(), this example shows how that can take form:

		const selected = await modalManager
			.open(this._host, UMB_MODAL_APP_AUTH, {
				data: {
					userLoginState,
				},
				modal: {
					key: authModalKey,
					backdropBackground: 'var(--umb-auth-backdrop, rgb(244, 244, 244))',
				},
			})
			.onSubmit()
			.catch(() => undefined);

		if (selected) {
			// Handle the newly selected items...
		} else {
			// The Modal was closed, so we do nothing.
		}

Because we appended .catch(() => undefined); then the returned value will become undefined if the Promise of onSubmit() was rejected.

Another example could look like this:

			const confirm = await umbConfirmModal(this, {
				headline: 'Would you like to continue?'
			}).catch(() => false);
			
			if(confirm) {
				// User wants to proceed
			} else {
				// Either modal was closed, or the user declined.
			}

Because we catch the rejection and return false, then we get the same value when the user declines and then the user just closes the modal.

No need to handle rejections in already handled Promise Chains, like Action Api execute()
An example of a case that is already handled is for the execute method for a Action API. See this example:

	async execute() {
		await umbConfirmModal(this, {
			headline: 'Do you want to delete?'
		});
		this.#repository.delete('1234');
	}

The rejection of execute is handled on our side, meaning you do not need to catch the rejection of umbConfirmModal.
A rejection that is not handled locally results in the method execution stopping, meaning this.#repository.delete('1234'); will not be executed when the Modal gets closed.

@nielslyngsoe nielslyngsoe enabled auto-merge (squash) March 9, 2025 20:50
@nielslyngsoe nielslyngsoe merged commit b9eb988 into v16/dev Mar 14, 2025
21 of 23 checks passed
@nielslyngsoe nielslyngsoe deleted the v16/feature/get-context-resolves-in-undefined-if-not-found branch March 14, 2025 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants