# Using AlpineJS Template to load data from fetch

This is a follow-up to this [post of mine](https://anjane.sh/3CjKTeI) where I show how to retrieve data from a public google spreadsheet via their JSON output and show it in the webpage by setting the HTML to a DOM element via **innerHTML**. I think doing something like `document.getElementById("razorui-faq").innerHTML = details;` is going to be considered bad practice shortly. Just like using `document.write()` is frowned upon.

With Reactive libraries and frameworks like React, Angular, Vue, Svelte etc being the standard for using **templates** in DOM replacement methodologies, it may not be suitable to use a whole `npm install` for smaller, micro-websites that are used for marketing purposes or using in an existing WordPress page.

There's a faster solution - [AlpineJS](https://alpinejs.dev/) - it's *reactive* and has a smaller footprint and can be included in your webpage like you insert a jQuery CDN. Right now, all you got to do is to include [https://unpkg.com/alpinejs@3.10.5/dist/cdn.min.js](https://unpkg.com/alpinejs@3.10.5/dist/cdn.min.js)

```xml
<script src="https://unpkg.com/alpinejs@3.10.5/dist/cdn.min.js" defer></script>
```

This - we use [x-init](https://alpinejs.dev/directives/init) to fetch the data using await. Even the AlpineJS docs show it as `x-init="posts = await (await fetch('/posts')).json()"` as an example.

```xml
<div x-data="{ faqs: [] }" x-init="faqs = await fetchFAQ().then((data) => data )">
    <template x-for="faq in faqs">
        <details>
            <summary x-text="faq[0]"></summary>
            <p x-text="faq[1]"></p>
        </details>
        
    </template>
</div>
```

Get the content from the JSON as usual :

```javascript
function getFAQ(json)
{    
    let faqList = [];
    let detail, summary;

    json.table.rows.forEach((row, i) =>
    {
        if (i == 0) return; // The first row is the header        

        try { detail = row.c[0].f ? row.c[0].f : row.c[0].v }
        catch(e){ detail = '' }

        try { summary = row.c[1].f ? row.c[1].f : row.c[1].v }
        catch(e){ summary = '' }

        faqList.push([detail, summary]);
    });

    return faqList;
}
```

The most <mark>important part</mark>: Using Promise by returning an `await new Promise`.

```javascript
let fetchFAQ = async () =>
{
    return await new Promise((resolve, reject) =>
    {
        fetch(url)
        .then((response) => response.text())
        .then((data) =>
        {
            let json_string = data.substring(47).slice(0, -2);
            let details = getFAQ(JSON.parse(json_string));
            resolve(details);
        });
    });
}
```

Demo : [https://anjanesh.s3.amazonaws.com/demo/fetch-alpine.html](https://anjanesh.s3.amazonaws.com/demo/fetch-alpine.html)
