# How to Create Repeatable Button Components, Fetching from a Database

{% hint style="warning" %}
**Note: This page only applies to the Old Rendering Engine** - for the New Rendering engine ask a Savvy Expert for help
{% endhint %}

{% hint style="info" %}
Repeatable components take data from an array of objects and turn it into the same amount of components.
{% endhint %}

### Step 1: Create and Prepare your Button

* Create a button where you want the list of buttons to appear.
* Select the component and scroll to the bottom of the Options tab, open the Advanced dropdown.
* Select the REPEATER KEY. This will be the key of the Computed field that is fetching the data and returning the array of objects. Here are some docs for reference:

{% content-ref url="../logic-how-tos/computed-fields/how-to-bring-data-from-airtable" %}
[how-to-bring-data-from-airtable](https://trysavvy.gitbook.io/savvy/how-tos/logic-how-tos/computed-fields/how-to-bring-data-from-airtable)
{% endcontent-ref %}

{% content-ref url="../logic-how-tos/computed-fields/how-to-bring-data-from-google-sheet" %}
[how-to-bring-data-from-google-sheet](https://trysavvy.gitbook.io/savvy/how-tos/logic-how-tos/computed-fields/how-to-bring-data-from-google-sheet)
{% endcontent-ref %}

{% content-ref url="../logic-how-tos/how-to-ping-an-api" %}
[how-to-ping-an-api](https://trysavvy.gitbook.io/savvy/how-tos/logic-how-tos/how-to-ping-an-api)
{% endcontent-ref %}

{% hint style="info" %}
You can also do this on an Option Selector, but you should select from the `BUTTON REPEATER KEY` dropdown instead of the `REPEATER KEY` dropdown.
{% endhint %}

### Step 2: Transform the Data

{% hint style="info" %}
You can do this in the same Computed Field as the fetch, but it's a good practice to do it on a different one.&#x20;
{% endhint %}

* Map it into an object with a 'key' key, and a 'text' key. Something like this:

```
function result( {
  full_list_key
} ) {
    return full_list_key.map(data =>{
        key: data.id,
        text: data.text
        })
}
```

* Try giving it an HTML structure. For example:

```
function result( {
  full_list_key
} ) {
    return full_list_key.map(data =>{
        key: data.id,
        text: `<div>
            <h1>Name: ${data.name}</h1>
            <h3>Email: ${data.email}</h3>
            <img src=${data.img}>
            </div>`data.text
        })
}
```

### Step 3: Style it

* Add some classes so you can style it with custom selectors

```
function result( {
  full_list_key
} ) {
    return full_list_key.map(data =>{
        key: data.id,
        text: `<div class="repeated_container">
            <h1 class="repeated_name">Name: ${data.name}</h1>
            <h3 class="repeated_email">Email: ${data.email}</h3>
            <img class="repeated_img" src="${data.img}">
            </div>`
        })
}
```

Here's how to style components with custom selectors:

{% content-ref url="../design-how-tos/how-to-use-custom-selectors" %}
[how-to-use-custom-selectors](https://trysavvy.gitbook.io/savvy/how-tos/design-how-tos/how-to-use-custom-selectors)
{% endcontent-ref %}

### What if there's more data that I want to show when a user selects one of the options?

Another computed field can easily solve that. The code would look something like this:

```
function result( {
  full_list_key,
  options_key
} ) {
  return (full_list_key || []).find(option => option.id === options_key)
}
```

This would return the full selected object!
