settingsAccountsettings
Menusettings

Q: Fisher Game App with Kinvey

+2 votes

Create an application at kinvey.com. Create a collection biggestCatches (angler, weight, species, location, bait, captureTime) to hold information about the largest fish caught.

  • angler - string representing the name of the person who caught the fish
  • weight - floating point number representing the weight of the fish in kilograms
  • species - string representing the name of the fish species
  • location - string representing the location where the fish was caught
  • bait - string representing the bait used to catch the fish
  • captureTime - integer number representing the time needed to catch the fish in minutes

HTML Template

You are given an HTML template to test your code, your task is to attach handlers to the [Load], [Update], [Delete] and [Add] buttons, which make the appropriate GET, PUT, DELETE and POST requests respectively.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Biggest Catch</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script src="catch.js"></script>
    <style>
        h1 { text-align: center; }
        input { display: block; }
        div { border: 1px solid black; padding: 5px; display: inline-table; width: 24%; }
        div#aside { margin-top: 8px; width: 15%; border: 2px solid grey; }
        div#catches{ width:auto; }
        button { display: inline-table; margin: 5% 0 5% 5%; width: 39%; }
        button.add { width: 90%; }
        button.load { width: 90%; padding: 10px; }
        button.load { vertical-align: top; }
        fieldset { display: inline-table; vertical-align: top; }
        fieldset#main { width: 70%; }
    </style>
</head>
<body>
<h1>Biggest Catches</h1>
<fieldset id="main">
    <legend>Catches</legend>
    <div id="catches">
        <div class="catch" data-id="<id-goes-here>">
            <label>Angler</label>
            <input type="text" class="angler" value="Paulo Amorim"/>
            <label>Weight</label>
            <input type="number" class="weight" value="636"/>
            <label>Species</label>
            <input type="text" class="species" value="Atlantic Blue Marlin"/>
            <label>Location</label>
            <input type="text" class="location" value="Vitória, Brazil"/>
            <label>Bait</label>
            <input type="text" class="bait" value="trolled pink"/>
            <label>Capture Time</label>
            <input type="number" class="captureTime" value="80"/>
            <button class="update">Update</button>
            <button class="delete">Delete</button>
        </div>
    </div>
</fieldset>
<div id="aside">
    <button class="load">Load</button>
    <fieldset id="addForm">
        <legend>Add Catch</legend>
        <label>Angler</label>
        <input type="text" class="angler"/>
        <label>Weight</label>
        <input type="number" class="weight"/>
        <label>Species</label>
        <input type="text" class="species"/>
        <label>Location</label>
        <input type="text" class="location"/>
        <label>Bait</label>
        <input type="text" class="bait"/>
        <label>Capture Time</label>
        <input type="number" class="captureTime"/>
        <button class="add">Add</button>
    </fieldset>
</div>
<script>attachEvents()</script>
</body>
</html>

You are given an example catch in the template to show you where and how you should insert the catches.

Notice that the div containing the catch has an attribute data-id that should store the _id of the entry given by Kinvey.

Kinvey will automatically create the following REST services to access your data:

  • List All Catches
    • Endpoint: https://baas.kinvey.com/appdata/[:appId]/biggestCatches
    • Method: GET
    • Headers:
      • Basic Authorization with user credentials
    • Returns (JSON)
  • Create a New Catch
    • Endpoint: https://baas.kinvey.com/appdata/[:appId]/biggestCatches
    • Method: POST
    • Headers:
      • Basic Authorization with user credentials
      • Content-type: application/json
    • Request body (JSON): {"angler":"…", "weight":…, "species":"…", "location":"…", "bait":"…", "captureTime":…}
  • Update a Catch
    • Endpoint: https://baas.kinvey.com/appdata/[:appId]/biggestCatches/[:catchId]
    • Method: PUT
    • Headers:
      • Basic Authorization with user credentials
      • Content-type: application/json
    • Request body (JSON): {"angler":"…", "weight":…, "species":"…", "location":"…", "bait":"…", "captureTime":…}
  • Delete a Catch
    • Endpoint: https://baas.kinvey.com/appdata/[:appId]/biggestCatches/[:catchId]
    • Method: DELETE
    • Headers:
      • Basic Authorization with user credentials
      • Content-type: application/json

Pressing the [Load] button should list all catches, pressing a catch's [Update] button should send a PUT requests updating that catch in kinvey.com. Pressing a catch's [Delete] button should delete the catch both from kinvey and from the page. Pressing the [Add] button should submit a new catch with the values of the inputs in the Add fieldset.

Screenshots:

fisher game with kinvey database

asked in JavaScript category by user icabe

1 Answer

+1 vote

>> HERE YOU CAN VIEW AND TEST THE PROJECT ONLINE << (on GitHub io)


My solution is (HTML file):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://code.jquery.com/jquery-3.2.1.js"></script>
    <script src="catch.js"></script>
    <style>
        h1 {
            text-align: center;
        }

        input {
            display: block;
        }

        div {
            border: 1px solid black;
            padding: 5px;
            display: inline-table;
            width: 24%;
        }

        div#aside {
            margin-top: 8px;
            width: 15%;
            border: 2px solid grey;
        }

        div#catches {
            width: auto;
        }

        button {
            display: inline-table;
            margin: 5% 0 5% 5%;
            width: 39%;
        }

        button.add {
            width: 90%;
        }

        button.load {
            width: 90%;
            padding: 10px;
        }

        button.load {
            vertical-align: top;
        }

        fieldset {
            display: inline-table;
            vertical-align: top;
        }

        fieldset#main {
            width: 70%;
        }
    </style>

</head>
<body>
<h1>Biggest Catches</h1>
<fieldset id="main">
    <legend>Catches</legend>
    <div id="catches">
        <div class="catch" data-id="<id-goes-here>">
            <label>Angler</label>
            <input type="text" class="angler" value="Paulo Amorim"/>
            <label>Weight</label>
            <input type="number" class="weight" value="636"/>
            <label>Species</label>
            <input type="text" class="species" value="Atlantic Blue Marlin"/>
            <label>Location</label>
            <input type="text" class="location" value="Vitória, Brazil"/>
            <label>Bait</label>
            <input type="text" class="bait" value="trolled pink"/>
            <label>Capture Time</label>
            <input type="number" class="captureTime" value="80"/>
            <button class="update">Update</button>
            <button class="delete">Delete</button>
        </div>
    </div>
</fieldset>
<div id="aside">
    <button class="load">Load</button>
    <fieldset id="addForm">
        <legend>Add Catch</legend>
        <label>Angler</label>
        <input type="text" class="angler"/>
        <label>Weight</label>
        <input type="number" class="weight"/>
        <label>Species</label>
        <input type="text" class="species"/>
        <label>Location</label>
        <input type="text" class="location"/>
        <label>Bait</label>
        <input type="text" class="bait"/>
        <label>Capture Time</label>
        <input type="number" class="captureTime"/>
        <button class="add">Add</button>
    </fieldset>
</div>
<script>attachEvents()</script>
</body>
</html>

catch.js file (line#7) with the function attachEvents() inside:

function attachEvents() {
    const baseUrl = "https://baas.kinvey.com/appdata/yourKinveyAppID";
    const kinveyUsername = "alex";
    const kinveyPassword = "alex";
    const base64auth = btoa(kinveyUsername + ":" + kinveyPassword);
    const authHeader = {
        "Authorization": "Basic " + base64auth,
        "Content-type": "application/json"
    };

    $('.load').click(loadAllCatches);
    $('.add').click(createCatch);

    function request(method, endpoint, data) {
        return $.ajax({
            method: method,
            url: baseUrl + endpoint,
            headers: authHeader,
            data: JSON.stringify(data)
        })
    }

    //AJAX request GET to load all catches
    function loadAllCatches() {
        request("GET", "/biggestCatches")
            .then(displayAllCatches)
            .catch(handleError)
    }

    //display the catches in the HTML
    function displayAllCatches(data) {
        let catches = $('#catches');
        catches.empty();
        for (let el of data) {
            catches.append($(`<div class="catch" data-id="${el._id}">`)
                .append($('<label>')
                    .text("Angler"))
                .append($(`<input type="text" class="angler" value="${el['angler']}"/>`))
                .append($('<label>')
                    .text("Weight"))
                .append($(`<input type="number" class="weight" value="${el['weight']}"/>`))
                .append($('<label>')
                    .text("Species"))
                .append($(`<input type="text" class="species" value="${el['species']}"/>`))
                .append($('<label>')
                    .text("Location"))
                .append($(`<input type="text" class="location" value="${el['location']}"/>`))
                .append($('<label>')
                    .text("Bait"))
                .append($(`<input type="text" class="bait" value="${el['bait']}"/>`))
                .append($('<label>')
                    .text("Capture Time"))
                .append($(`<input type="number" class="captureTime" value="${el['captureTime']}"/>`))
                .append($(`<button class="update">Update</button>`).click(updateCatch))
                .append($(`<button class="delete">Delete</button>`).click(deleteCatch)))
        }
    }

    //AJAX request PUT to update the catch
    function updateCatch() {
        let catchEl = $(this).parent();
        let dataObj = createDataJson(catchEl);

        request("PUT", `/biggestCatches/${catchEl.attr("data-id")}`, dataObj)
            .then(loadAllCatches)
            .catch(handleError);
    }

    //AJAX request DELETE to delete the catch
    function deleteCatch() {
        let catchID = $(this).parent().attr("data-id");

        request("DELETE", `/biggestCatches/${catchID}`)
            .then(loadAllCatches)
            .catch(handleError);
    }

    function createDataJson(catchEl) {
        return {
            angler: catchEl.find(".angler").val(),
            weight: +catchEl.find(".weight").val(),//the plus sign + is for casting to number
            species: catchEl.find(".species").val(),
            location: catchEl.find(".location").val(),
            bait: catchEl.find(".bait").val(),
            captureTime: +catchEl.find(".captureTime").val()//the plus sign + is for casting to number
        }
    }

    //AJAX request POST to create new catch
    function createCatch() {
        let catchEl = $('#addForm');
        let dataObj = createDataJson(catchEl);
        request("POST", "/biggestCatches", dataObj)
            .then(loadAllCatches)
            .catch(handleError);
    }

    function handleError(err) {
        alert(`ERROR: ${err.statusText}`)
    }
}
answered by user eiorgert
...