mitosis icon indicating copy to clipboard operation
mitosis copied to clipboard

Sveltosis: Treat arrow functions as regular function declarations

Open dritter opened this issue 1 year ago • 2 comments

Hi there!

This is a clumsy approach to treat arrow functions equal to regular function declarations.

I usually write my functions as arrow functions like so (as a matter of personal taste, I find it more readable):

<script>
const myClickHandler = (event) => {
  console.log('do something')
}
</script>

<button on:click={myClickHandler}>Click Me</button>

Before this PR the generated code looked like this:

<script>
  let myClickHandler = null;
</script>

<button
  on:click={(event) => {
    myClickHandler(event);
  }}>Click Me</button
>

So the ArrowFunction was detected as VariableDeclaration, which is not wrong, but the generated code wouldn't work anyway.

Edit: ~With this PR, the generated code looks like this~ (have to check that). It should keep the ArrowFunction as is. I'm running out of time for today :/

This is not perfect, but I created this PR to start the discussion. :)

Caveats

This might have some issues depending how the ArrowFunction was declared. E.g. if destructuring is involved, the code breaks very likely.

Fixes #1182

dritter avatar May 17 '23 16:05 dritter

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
mitosis-fiddle ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 31, 2023 4:33pm

vercel[bot] avatar May 17 '23 16:05 vercel[bot]

Okay.. The current version of fatArrow.svelte as input generates the following svelte file:

<script>
  clickHandler1 = (event) => {
    console.log("do something 1");
  };

  function clickHandler2(event) {
    console.log("do something 2");
  }
</script>

<button
  on:click={(event) => {
    clickHandler1(event);
  }}>Button 1</button
>
<button
  on:click={(event) => {
    clickHandler2(event);
  }}>Button 2</button
>

(note the missing const).

In vue this looks worse:

<template>
  <div>
    <button @click="clickHandler1($event)">Button 1</button>
    <button @click="clickHandler2($event)">Button 2</button>
  </div>
</template>

<script>
import { defineComponent } from "vue";

export default defineComponent({
  name: "fat-arrow",

  methods: {
    clickHandler1: (this.clickHandler1 = (event) => {
      console.log("do something 1");
    }),
    clickHandler2: function clickHandler2(event) {
      console.log("do something 2");
    },
  },
});
</script>

dritter avatar May 31 '23 16:05 dritter