DEV Community

Jbee - codehooks.io
Jbee - codehooks.io

Posted on • Updated on

Connecting Alpine.js to a Database REST API: A Simple Guide

In this simple guide, we'll create a dynamic web application using Alpine.js. We'll build a frontend with Alpine.js, a lightweight JavaScript/HTML framework, and show how to integrate it with a complete REST API database backend. For quick design this example uses DaisyUI and Tailwind CSS.

Setup the Alpine.js project files

Create a new a sub directory (e.g. app) to hold the Alpine.js files.



mkdir app


Enter fullscreen mode Exit fullscreen mode

In the app directory, create two new files for the app source code.



cd app
touch index.js script.js


Enter fullscreen mode Exit fullscreen mode

The Alpine.js app

The app (located in the app/index.html file) shows an imaginary search page for football players.

The working application is shown in the screen shot below (running locally from the file system).

Image description

You can also test out a live version of the Alpine.js app here.

This example app demonstrates two important features in Alpine.js:

  1. Loading external data into a global datamodel using Alpine store
  2. Changing the application state by calling a method on the global datamodel when an input area changes using Alpine events

The app/index.html code is shown below, notice the event listeners calling a method on the global datamodel, and how the <table> is created by iterating on the rows in the global datamodel. Make sure to copy the source code below info your local files to test.



<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/daisyui@3.9.4/dist/full.css" rel="stylesheet" type="text/css" />
    <script src="https://cdn.tailwindcss.com"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
    <script src="script.js"></script>
</head>

<body class="p-4">
    <h1 class="text-2xl pb-4" x-data="{ message: 'Alpine.js: Get data from a REST API' }" x-text="message"></h1>
    <div x-data>
        <input @keyup.enter="$store.coho.getData()" x-model="$store.coho.search" placeholder="Search for player ..."
            class="input input-bordered input-sm">
        <button @click="$store.coho.getData()" class="btn btn-primary btn-sm">Search</button>
    </div>
    <div class="overflow-x-auto">
        <table class="table">
            <thead>
                <th>Player</th>
                <th>Squad</th>
                <th>Nation</th>
                <th>Index</th>
            </thead>
            <tbody x-data>
                <template x-for="(player, index) in $store.coho.players">
                    <tr>
                        <td x-text="player.Player"></td>
                        <td x-text="player.Squad"></td>
                        <td x-text="player.Nation"></td>
                        <td x-text="index"></td>
                    </tr>
                </template>
            </tbody>
        </table>
        <div x-data>
            <span x-show="$store.coho.loading" class="loading loading-dots loading-sm"></span>
        </div>
    </div>

</body>
</html>


Enter fullscreen mode Exit fullscreen mode

The application global state (let's call it coho) is an Alpine store and it's implemented in the app/script.js file shown below.



// replace this with your project url, use CLI command 'coho info' to find yours
const MY_CODEHOOKS_URL = "/football";
// replace this with your own read-only key, use CLI command 'coho add-token' to create a new one
const MY_API_KEY = "0b49638f-56c3-48e9-8725-7f3c20f25316";

document.addEventListener('alpine:init', () => {
    Alpine.store('coho', {
        loading: false,
        search: '',
        players: [],
        async getData() {
            this.loading = true
            this.players = await getDataFromAPI(this.search)
            this.loading = false
        }
    })
})
// Fetch data from Codehooks REST API
async function getDataFromAPI(search) {
    var myHeaders = new Headers();
    myHeaders.append("x-apikey", MY_API_KEY); // read-only token
    myHeaders.append("Content-Type", "application/json");

    var requestOptions = {
        method: 'GET',
        headers: myHeaders,
        redirect: 'follow'
    };
    var query = "{}";
    console.log('getData', search)
    if (search.length > 0) {
        query = JSON.stringify({"Player": {$regex: search, $options: "gi"}})
    }
    var hints = JSON.stringify({sort: {Squad: 1, Nation: 1}, $fields: {"Player": 1, "Nation": 1, "Squad": 1}})
    var URL = `${MY_CODEHOOKS_URL}?q=${query}&h=${hints}`;
    console.log(URL)
    const response = await fetch(URL, requestOptions)
    return response.json()
}


Enter fullscreen mode Exit fullscreen mode

Open the app/index.html file in your web browser to test the Alpine.js web app locally.

Database REST API

This backend database was create by importing data from this Kaggle dataset. The dataset is a CSV file 2021-2022-Football-Player-Stats.csv with 2921 players.

I created a database static-i4rq in Codehooks and imported the data with the CLI like the example shown below:



coho import -f ~/Downloads/2021-2022-Football-Player-Stats.csv -c football --separator ';' --encoding 'latin1'


Enter fullscreen mode Exit fullscreen mode

The Database REST API is automatically created 🔥

Source code at Github here.

Happy coding!

Top comments (1)

Collapse
 
bd_perez profile image
Bruno Pérez

Truth is the fetch part is not that simple comparing to Alpine.JS minimalist syntax on DOM manipulation.

Some combine it with htmx to connect to a server. I wonder what can be the best approach for that point.