0

Each table row has a cell with some "expensive" data loaded on demand; before it is loaded, it shows "?". When that row's button is clicked, the cell is populated.

<table>
  <tbody>

    <!-- rows 1..10  -->

    <tr x-data="{ foo: '?' }">
      <td><span x-text="foo"></span></td>
      <!-- ... -->
      <td><button onclick="foo = await fetchFoo('row-11')">Load</button></td>
    </tr>

    <!-- rows 12... -->

  </tbody>
</table>

<script>
  async function fetchFoo(rowId) {
    let url      = `https://www.example.com/foo/${rowId}`;
    let response = await fetch(url);
    let result   = await response.text();
    return result;
  }
</script>

How do I pass the fetched data from the button to the cell?

UPDATE

Here's a demo showing it doesn't work; I tried various syntaxes:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>

<table>
  <tbody>
    <tr x-data="{ foo: '?' }">
      <td>Hello</td>
      <td><span x-text="foo"></span></td>
      <td><button onclick="foo = await fetchFoo('row-1')">Load</button></td>
    </tr>
    <tr x-data="{ foo: '?' }">
      <td>World</td>
      <td><span x-text="foo"></span></td>
      <td><button onclick="async () => { foo = await fetchFoo('row-2') }">Load</button></td>
    </tr>
    <tr x-data="{ foo: '?' }">
      <td>Hi</td>
      <td><span x-text="foo"></span></td>
      <td><button onclick="fetchFoo('row-3')">Load</button></td>
    </tr>
    <!-- rows 4+... -->
  </tbody>
</table>

<script>
  async function fetchFoo(rowIndex) {
    return new Promise(resolve => setTimeout(() => resolve(rowIndex), 1000));
  }
</script>

1
  • @TUPKAP It does nothing. I added a demo to the question to demonstrate the problem. Commented Jan 20 at 3:03

1 Answer 1

2

You must change the onclick to x-on:click:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>

<table>
  <tbody>
    <tr x-data="{ foo1: '?' }">
      <td>Hello</td>
      <td><span x-text="foo1"></span></td>
      <td><button x-on:click="foo1 = await fetchFoo('row-1')">Load</button></td>
    </tr>
    <!-- rows 4+... -->
  </tbody>
</table>

<script>
  async function fetchFoo(rowIndex) {
    return new Promise(resolve => setTimeout(() => resolve(rowIndex), 1000));
  }
</script>

UPDATE:

by using "onclick" you're using basic js directives, you must use x-on:click to use alpine's directives.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, that worked for me! I removed the await (which I used as I saw it in the docs), but also changed onclick to x-on:click. Any idea why that's necessary?
You can keep the await (even though does not make any difference), with onclick you're using simple js directive but with x-on:click you're using alpine.js that has visibility over x-data (simple js does not). I should have focused on that on my answer, I'll update it
Thanks. On rereading the docs I found the issue - I was missing an "@". One can use x-on:click or @click.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.