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

Function passed as prop gets undefined #12110

Closed
1 task
temple opened this issue Oct 3, 2024 · 3 comments
Closed
1 task

Function passed as prop gets undefined #12110

temple opened this issue Oct 3, 2024 · 3 comments
Labels
needs triage Issue needs to be triaged

Comments

@temple
Copy link

temple commented Oct 3, 2024

Astro Info

Astro                    v4.15.9
Node                     v20.17.0
System                   Linux (x64)
Package Manager          pnpm
Output                   server
Adapter                  @astrojs/node
Integrations             @astrojs/tailwind

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

If I define a component props this way:

# button.astro
- - - 
interface props{
    text: string;
    id: string;
    onClick(): any;
}
const {text, id, onClick} = Astro.props;
- - - 
<button id={id} type="submit">{text}</button>
<script define:vars={{id, onClick}}>
    console.log('Logging id and on click:', id, onClick);
</script>

And put this component in a page the following way:

# my-page.astro
- - -
import Button from '@components/Button.astro';
const buttonId = 'my-button';
const buttonClick = function(){};
- - -
<!doctype html>
<html lang="en">
<body>
<Button id={buttonId} onClick={buttonClick} />
</body>
</html>

In browser I got logged:

Logging id and on click: my-button undefined

What's the expected result?

I expected to be able to pass function as component props somehow and get it reflected in the client side, so they don't appear as undefined

Link to Minimal Reproducible Example

https://stackblitz.com/github-n4np37

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label Oct 3, 2024
@ascorbic
Copy link
Contributor

ascorbic commented Oct 3, 2024

Hi. I'm afraid this isn't possible. Anything passed to define:vars is serialised with JSON.stringify, which won't work with functions. You'll need to find another way. Without seeing more of your usage it's not possible for me to suggest, but maybe having a slot would work. See the docs here: https://docs.astro.build/en/reference/container-reference/#adding-a-renderer-manually

@ascorbic ascorbic closed this as completed Oct 3, 2024
@temple
Copy link
Author

temple commented Oct 3, 2024

Thank you @ascorbic .
Is it there a way to render the function inside a <script/> tag (once refused the idea of passing-through define:vars) ?

My approach is to render the buttonClick function code as part of the inline javascript.

Can therefore this new approximation be possible?

# button.astro
- - - 
interface props{
    text: string;
    id: string;
    onClick(): any;
}
const {text, id, onClick} = Astro.props;
const onClickAsText = onClick.toString();
- - - 
<button id={id} type="submit">{text}</button>
<script define:vars={{id}}>
    const onClick = new Function(`${onClickAsText}`);
    console.log('Logging id and on click:', id, onClick);
</script>

@temple
Copy link
Author

temple commented Oct 3, 2024

Well, this comment is just for providing a workaround for those interested in the approach of the issue's subject:

# components/button.astro
- - - 
interface props{
    text: string;
    id: string;
    onClick(): any;
}
const {text, id, onClick} = Astro.props;
const onClickText = onClick.toString();
const onClickFunction = onClickText.slice(onClickText.indexOf("{") + 1, onClickText.lastIndexOf("}"));
- - - 
<button id={id} type="submit">{text}</button>
<script define:vars={{id, onClickFunction}}>
    const onClick = new Function('evt',onClickFunction);
    console.log('Logging id and on click:', id, onClick);
    button.addEventListener('click',onClick);
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage Issue needs to be triaged
Projects
None yet
Development

No branches or pull requests

2 participants