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

feat: add dynamic props #283

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

yaameen
Copy link

@yaameen yaameen commented Nov 14, 2022

It lets you pass dynamic props to the loaded component. It adheres to the routing cycle and renders components only after the props are resolved. It raises propsFailed event for each prop when the prop fails to resolve.

Follows how you would pass dynamic props to your component.

'/foo': wrap({
    component: Foo,
    props: {
        staticProp: 'this is static',
        dynamicProp: async () => Promise.resolve(`this is dynamic - ${new Date}`),
        anotherProps: () => `Just works!`
    }
 }),

Copy link
Owner

@ItalyPaleAle ItalyPaleAle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thans for this contribution :) I definitely see the value in this, although I do have some feedback on the implementation, if you can please take a look!

test/app/src/routes.js Show resolved Hide resolved
test/app/src/routes.js Show resolved Hide resolved
Router.svelte Outdated Show resolved Hide resolved
Router.svelte Outdated Show resolved Hide resolved
Router.svelte Show resolved Hide resolved
Router.svelte Outdated Show resolved Hide resolved
Router.svelte Outdated Show resolved Hide resolved
Router.svelte Outdated Show resolved Hide resolved
prop resolution moved below as adviced and made async
fixed the formatting
@yaameen
Copy link
Author

yaameen commented Nov 14, 2022

Following is an example that uses await.

'/foo': wrap({
    component: Foo,
    props: {
        staticProp: 'this is static',
        dynamicProp: async () => Promise.resolve(`this is dynamic - ${new Date}`),
        anotherProps: () => `Just works!`,
        delayed: async () => await fetch(`https://api.chucknorris.io/jokes/random`).then(i => i.json()).then(i => i.value),
    }
 }),

@yaameen
Copy link
Author

yaameen commented Nov 20, 2022

@ItalyPaleAle any updates?

@ItalyPaleAle
Copy link
Owner

ItalyPaleAle commented Nov 20, 2022

@yaameen Apologies for the delay, had a crazy week :)

I have reviewed the PR once again and pushed a small commit to your branch to fix some formatting.

There are however 2 things that make me nervous about merging this and I'd like to ask if you could please do more testing (incl. perhaps writing unit tests) in that regards:

  1. props (current line) used to be set outside of the if (componentObj != obj) block, which means that pushing a new route with the same component, but different props, would have worked (the props would have been updated, but the component would not have been re-mounted). You moved that into the if (componentObj != obj) block, and I'm worried this may be a breaking change. Is there a reason why the block setting props needs to be within the if?
  2. Another thing that's concerning to me is that before the props object was always assigned synchronously. Now, it's always assigned asynchronously: even when props are static, they are wrapped inside a Promise.resolve. This means that they're always executed in the next tick, and I'm not sure what kind of consequences this could bring.

Removes promise.resolve while resolving user provide props
It now determines functions, promises and otherwise and resolves the prop
@yaameen
Copy link
Author

yaameen commented Nov 25, 2022

@yaameen Apologies for the delay, had a crazy week :)

I have reviewed the PR once again and pushed a small commit to your branch to fix some formatting.

There are however 2 things that make me nervous about merging this and I'd like to ask if you could please do more testing (incl. perhaps writing unit tests) in that regards:

  1. props (current line) used to be set outside of the if (componentObj != obj) block, which means that pushing a new route with the same component, but different props, would have worked (the props would have been updated, but the component would not have been re-mounted). You moved that into the if (componentObj != obj) block, and I'm worried this may be a breaking change. Is there a reason why the block setting props needs to be within the if?

Actually it was a mistake putting the prop resolution with in the if block. Also speaking of retaining the component I am failing to produce any occasion where the component is the same but it is not re-mounted when path changes (wild card routes are an exception here). Refer to the following repl.

https://svelte.dev/repl/0d1885829adf467faa5cd432d766a43a?version=3.53.1

Also in the following snippet where obj is a promise

if (componentObj != obj) {

like so
args.asyncComponent = () => Promise.resolve(args.component)

I was wondering is that the reason the component is always re-mounted? Or am I missing something here?

  1. Another thing that's concerning to me is that before the props object was always assigned synchronously. Now, it's always assigned asynchronously: even when props are static, they are wrapped inside a Promise.resolve. This means that they're always executed in the next tick, and I'm not sure what kind of consequences this could bring.

Than you for the feedback, I have simplified the prop resolution where function callback are involved only where required.

@yaameen
Copy link
Author

yaameen commented Jan 2, 2023

Any update @ItalyPaleAle on this?

@jh12z jh12z mentioned this pull request Jul 21, 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.

2 participants