Is there a way to add properties or component data to looped objects with Alpine.js?

1.4k Views Asked by At

Essentially I'm receiving JSON from the server and would like to add properties to the objects I'm looping or the x-data of the component, is this possible with alpine.js?

The data is something that will be requested on an interval and looks something like:

let teams = [
    { id: 1, name: 'Person 1'},
    { id: 2, name: 'Person 2'},
    ...
];

What I'd like to do is add a new property favourite to the looped team object, with default set to false or add it as component data. I plan to use this property to filter the list later on. At the moment I have:

<template x-for="team in teams" :key="team.id">
    <tr>
        <td x-text="team.name"></td>
        <td>
            <input type="checkbox" x-model="favourite">
        </td>
    </tr>
</template>

I have tried a few things to get this working, such as using:

x-data="{ team: team, favourite: false }"

On both the tr and template tag as well as without passing the team object to the x-data directive. It seems like there is a clash between the x-for and x-data directives as this throws an error: Uncaught ReferenceError: team is not defined

I have also tried using x-init alongside the x-data directive to no avail.

At this stage I'm wondering if I'll have to switch to another JS library to get this working (recommendations welcome if necessary) or if my approach is fundamentally wrong.

Any help/pointers would be much appreciated.

1

There are 1 best solutions below

2
Hugo On BEST ANSWER

In principle what you should be doing is adding the "favourite" field before it gets to the x-for.

For example if you're loading teams using fetch you could do:

<div
  x-data="{ teams: [] }"
  x-init="setInterval(() => {
    fetch('/teams-url').then(res => res.json()).then(teamsData => {
      teams = teamsData.map(team => ({ favourite: false, ...team }));
    });
  }, 1000);"
>

I also noticed that your example is using v-model and v-text, which should be x-model and x-text respectively.