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

Async setup possible? #24

Open
khrise opened this issue Jul 2, 2024 · 14 comments
Open

Async setup possible? #24

khrise opened this issue Jul 2, 2024 · 14 comments

Comments

@khrise
Copy link

khrise commented Jul 2, 2024

In my original app, I have an async setup. Among other async stuff, a configuration is fetched from a remote server.

loadConfig().then(() => {
  const app = createApp(App);
  app
   .use(...)
   .use(...)
   .mount('#app')
});

Is there a way to accomplish this with vue-web-component-wrapper? Basically, I'd like to be able to make "createApp" wait for an arbitrary (configurable) promise.
Thanks!

@EranGrin
Copy link
Owner

EranGrin commented Jul 2, 2024

Hi @khrise,
Interesting use case, I would suggest to try use the
createWebComponent
in the
loadConfig().then(() => {

maybe something like this

loadConfig().then(() => {
createWebComponent({
  rootComponent: app,
  elementName: 'my-web-component',
  plugins: pluginsWrapper,
  cssFrameworkStyles: style,
  VueDefineCustomElement,
  h,
  createApp,
  getCurrentInstance,
})
});

@tbl0605
Copy link

tbl0605 commented Jul 7, 2024

Hi @EranGrin,
I have a similar question, but concerning vue-router.
My original code is:

const app = createApp(App);

app.use(router);
...

router.isReady().then(() => {
  app.mount('#app');
});

I don't know how to add the router.isReady()... code to the pluginsWrapper object.

The problem that this piece of code solves is described here: Vue Router 4: Route Params Not Available on Created/Setup
Also described here: All navigations are now always asynchronous

Thank you!

@EranGrin
Copy link
Owner

EranGrin commented Jul 8, 2024

Hi @tbl0605,

Could you please provide more details about your use case? It appears to be an edge case that the current plugin configuration does not support. Understanding your specific requirements better will help me assess the feasibility of incorporating this feature. Alternatively, you are welcome to contribute by opening a pull request for this feature.

Thanks

@tbl0605
Copy link

tbl0605 commented Jul 8, 2024

Hi @EranGrin,
thank you for your fast answer! :)

Could you please provide more details about your use case?

I have a Vue application (that I would like to convert to a web component) that contains <router-links> with query parameters.
The users like to open each link in separate navigator tabs (by right-clicking on them and doing "Open the link in a new tab"), so they are able to use different pages of the application "at same time".

Without the router.isReady() hack, I loose the query informations at the startup of the new application instance in the new tab.
It's really like the problem described here: Vue Router 4: Route Params Not Available on Created/Setup

router.isReady() is also needed to solve another kind of "page refresh" problem explained here.

Alternatively, you are welcome to contribute by opening a pull request for this feature.

Frankly, I have no idea how to fix this in your code :/ Ideally there should be some asynchronous callback somewhere so I could do await router.isReady() inside it, but can this really be implemented on your side to delay the web component mounting?

@EranGrin
Copy link
Owner

I was working on the async solution, but I noticed that for the query param it is not needed, meaning it seems to work without any changes. Could you please check?

@tbl0605
Copy link

tbl0605 commented Jul 14, 2024

H @EranGrin,
from my few tests lately, you're right it seems router.isReady() is not needed.
I'm a little surprised though.
I hope I'm not wrong in my assumptions ^^

@EranGrin
Copy link
Owner

EranGrin commented Jul 15, 2024

Great, I'm still planning to introduce the asnyc feature but I think that for your use case this isn't needed

@EranGrin
Copy link
Owner

@khrise Is the asnyc feature still interesting to you? Would you be able to test it?

@khrise
Copy link
Author

khrise commented Jul 15, 2024

@khrise Is the asnyc feature still interesting to you? Would you be able to test it?

Oh yes, and yes.
Sorry, I've been busy in other projects the last few days.
I tried your suggestion from your first answer above, but it didn't seem to do the trick. (Although I don't exactly understand why not).

EDIT: No, it does work, apparently. I had another call outside the promise lambda :/

@EranGrin
Copy link
Owner

@khrise if I understand you correctly, this solution does work, and we can close this ticket, right?

loadConfig().then(() => {
createWebComponent({

@khrise
Copy link
Author

khrise commented Jul 18, 2024

Yes, we can close this.
I think it's not the most intuitive way to solve this, because to me, this appears like "load the config, then register the web component(s)", while what I actually want is "register the web component(s), and when bootstrapping one of them, load the config before firing up the app". (Does that make sense?)
In fact, I think it's two different use cases. For my use case, your proposed solution is fine. (I guess, I'm still exploring.)
Thanks!

@EranGrin
Copy link
Owner

I have worked on a solution that might give better support for async initialization

main...feature/init-promise

which let one pass a promise to the plugin

createWebComponent({
  rootComponent: app,
  elementName: 'my-web-component',
  plugins: pluginsWrapper,
  cssFrameworkStyles: style,
  VueDefineCustomElement,
  h,
  createApp,
  getCurrentInstance,
  asyncInitialization: () => new Promise((res) => setTimeout(() => res("p1"), 1000))
}) 

but I am still not quite sure regarding this solution and the related use-cases

@khrise
Copy link
Author

khrise commented Jul 18, 2024

I have worked on a solution that might give better support for async initialization

main...feature/init-promise

which let one pass a promise to the plugin

createWebComponent({
  rootComponent: app,
  elementName: 'my-web-component',
  plugins: pluginsWrapper,
  cssFrameworkStyles: style,
  VueDefineCustomElement,
  h,
  createApp,
  getCurrentInstance,
  asyncInitialization: () => new Promise((res) => setTimeout(() => res("p1"), 1000))
}) 

but I am still not quite sure regarding this solution and the related use-cases

That's pretty much what I had in mind in the first place.

@Pretagonist
Copy link

I'm also interested in async setup. My use case is that I might have multiple components on the same page but each component has different props and I need to use the props to get some configs from a server before i spin up the App.vue.

So optimally I'd be able to get the props, do some async requests, and feed these results into the plugins install method before the app starts.

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

No branches or pull requests

4 participants