Search code examples
javascriptvaadinweb-component

Javascript: Checking if multiple custom elements are defined via Promises


Hopefully this has not been asked before - I've had a hard time figuring out how to word the question.

I'm playing around with Vaadin's date and time pickers - an example dealing with date ranges is shown here https://vaadin.com/components/vaadin-date-picker/html-examples In that example, customElements.whenDefined('vaadin-date-picker')... is being used to ensure the elements exist.

I'm interested in combining the date picker with the time picker, essentially making a date/time range picker. Therefore, I would need to check that both vaadin-date-picker and vaadin-time-picker exist.

What is the 'correct' way or best practice to handle this combined check?

My first guess was:

customElements.whenDefined('vaadin-date-picker').whenDefined('vaadin-time-picker').then...

But there are no examples showing this approach - as far as I can tell - so I suspect it either is not correct, or simply an uncommon problem. I think a working solution would be

customElements.whenDefined('vaadin-date-picker').then(function() { 
  customElements.whenDefined('vaadin-time-picker').then(function() {
    // insert code here...
  });
});

but this seems quite inelegant.


Solution

  • One option would be to use Promise.all to create one promise out of the two original ones:

    Promise.all([
        customElements.whenDefined('vaadin-date-picker'),
        customElements.whenDefined('vaadin-time-picker')
      ]).then(function() {
      // Do something
    });
    

    Another alternative that is in a way even more elegant is to do everything in an async function. Then you can await each promise separately before continuing.

    (async () => {
      await customElements.whenDefined('vaadin-date-picker');
      await customElements.whenDefined('vaadin-time-picker');
      // Do something
    })();
    

    If you're already inside a function that doesn't have to return anything immediately, then you can just mark that function as async instead of doing a dummy lambda wrapper like in my example.