Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Promises in Spacebars.call and Spacebars.dot. #413

Merged
merged 1 commit into from
May 12, 2023

Conversation

radekmie
Copy link
Collaborator

@radekmie radekmie commented May 5, 2023

While #412 adds a way to unwrap Promises in templates, here we'll focus on their usability. Currently, accessing a Promise results in undefined as they have very few accessible properties (most importantly, the resolved value is not there).

In this pull request, I made Spacebars.call and Spacebars.dot helpers aware of Promises. The former resolves all of the arguments before calling the function, while the latter wraps property accesses in Promises.

For details, please refer to the newly added tests.

(Fun fact: there are 0 deleted lines in this pull request.)


Once this and #412 will be merged, the "await unrolling" proposed before would not be needed. Consider the example from #409 (comment):

{{#if await someFunc ((await calcParamA) (await someOtherparamB)) (await calcParamB (await someOtherparamC) (someOtherparamD)) }}
    (...)
{{/if}}

This will have to unwrap the Promise, but the entire computation will be simple:

{{#let result=(someFunc (calcParamA someOtherparamB) (calcParamB someOtherparamC someOtherparamD))}}
  {{#if result}}
    (...)
  {{/if}}
{{/let}}

Of course, it'll be possible to use the @pending, @rejected, and @resolved helpers to check the progress of calculating result as well.

@radekmie radekmie added this to the Blaze 3.0 milestone May 5, 2023
@radekmie radekmie self-assigned this May 5, 2023
@DanielDornhardt
Copy link

{{#if await something.or.other }}
    (...)
{{/if}}

aaahhhh... noice...

Couldn't we then not just implement await or something similar as a regular old global template helper then? 😀

Something like this:

Template.registerHelper('await', (value) => {
    const ourValue = new ReactiveVar()
    if (value instanceof Promise) {
        value.then((error, result) => {
            if(result) {
                ourValue.set(result)
            }
        })
    } 
    return ourValue.get()
})

... there's always the problem of the re-running of the autorun above then re-triggering the entire call which then would lead to re-triggering the call with a fresh promise which would then lead to... not the result which we want 😃

-> But as a general idea it might be feasible and I'll toy with it when I'll have a bit of time. Or maybe @radekmie you know exactly how something like this could / should be implemented & do it in a heartbeat, which i'd be 100% onboard with :)

Thank you for the PR & hear you later!

@radekmie
Copy link
Collaborator Author

I wouldn't think of await at all for now, as it's unclear what should happen for the pending/rejected states - #let makes it obvious. I started a discussion whether #if and other blocks should handle it on Slack - we can discuss it there.

@radekmie radekmie changed the base branch from master to release-2.7 May 12, 2023 07:14
@radekmie radekmie removed this from the Blaze 3.0 milestone May 12, 2023
@Grubba27 Grubba27 merged commit eb8db10 into release-2.7 May 12, 2023
@radekmie radekmie deleted the async-call-and-dot branch May 12, 2023 13:34
radekmie added a commit that referenced this pull request May 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants