Code Your Application
You have created the “index.js” file in your project’s root directory, and this will contain the backend logic of your application.
Create a folder in your project’s root directory and name it “public.” This folder will contain the files for your front-end logic. Create the following files inside your public folder (Alien City/public/):
- index.html: The file that contains the HTML code for the front-end of the application.
- main.js: The file that contains the JavaScript code that connects the front-end and backend.
This is the final folder structure of the Alien City project.
You will be coding the index.js, index.html, and main.js files. You will also be updating the app-config.json file.
Copy the code below and paste it into the respective files of your project using an IDE and save the files.
index.jscopyvar express = require('express'); var app = express(); var catalyst = require('zcatalyst-sdk-node'); app.use(express.json()); app.use(express.static('public')); const tableName = 'Alien City'; // The table created in the Data Store const columnName = 'CityName'; // The column created in the table app.post('/alien', (req, res) => { var cityJson = req.body; console.log(req.body) var catalystApp = catalyst.initialize(req); getDataFromCatalystDataStore(catalystApp, cityJson.city_name).then(cityDetails => { if (cityDetails.length == 0) { console.log("Alien alert!"); var rowData = {} rowData[columnName] = cityJson.city_name; var rowArr = []; rowArr.push(rowData); // Inserts the city name as a row in the Catalyst Data Store table catalystApp.datastore().table(tableName).insertRows(rowArr).then(cityInsertResp => { res.send({ "message": "Thanks for reporting!" }); }).catch(err => { console.log(err); sendErrorResponse(res); }) } else { res.send({ "message": "Looks like you are not the first person to encounter aliens in this city! Someone has already reported an alien encounter here!" }); } }).catch(err => { console.log(err); sendErrorResponse(res); }) }); app.get('/alien', (req, res) => { var city = req.query.city_name; // Initializing Catalyst SDK var catalystApp = catalyst.initialize(req); getDataFromCatalystDataStore(catalystApp, city).then(cityDetails => { if (cityDetails.length == 0) { res.send({ "message": "Hurray! No alien encounters in this city yet!", "signal": "negative" }); } else { res.send({ "message": "Uh oh! Looks like there are aliens in this city!", "signal": "positive" }); } }).catch(err => { console.log(err); sendErrorResponse(res); }) }); function getDataFromCatalystDataStore(catalystApp, cityName) { return new Promise((resolve, reject) => { // Queries the Catalyst Data Store table catalystApp.zcql().executeZCQLQuery("Select * from " + tableName + " where " + columnName + "='" + cityName + "'").then(queryResponse => { resolve(queryResponse); }).catch(err => { reject(err); }) }); } function sendErrorResponse(res) { res.status(500); res.send({ "error": "Internal server error occurred. Please try again in some time." }); } app.listen(process.env.X_ZOHO_CATALYST_LISTEN_PORT || 9000, () => { }) module.exports = app;
index.htmlcopy<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AlientCityAppClient</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="main.css" /> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"> </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"> </script> <script src="main.js"> </script> </head> <body> <br> <br> <center> <h1>ALIEN CITY</h1> </center> <div class="container"> <ul class="nav nav-tabs" id="myTab" role="tablist"> <li class="nav-item"> <a class="nav-link active" id="check-tab" data-toggle="tab" href="#check" role="tab" aria-controls="check" aria-selected="true">Check My City</a> </li> <li class="nav-item"> <a class="nav-link" id="report-tab" data-toggle="tab" href="#report" role="tab" aria-controls="report" aria-selected="false">Report Alien Encounter</a> </li> </ul> <div class="tab-content" id="myTabContent"> <div class="tab-pane fade show active" id="check" role="tabpanel" aria-labelledby="check-tab"> <br> <br> <form> <div class="form-group"> <label for="city-get-input"> <b>Check if your city has aliens:</b> </label> <input type="text" class="form-control" id="city-get-input" aria-describedby="checkCity" placeholder="Enter City Name"> </div> <button type="submit" class="btn btn-primary" onclick="getAlienEncounter();return false;">Check</button> </form> <br> <br> <div id="result-container"> <div id="result-text"> </div> <br> <div id="result-image"> </div> </div> <div id="loader" style="display: none;"> <div class="spinner-border" role="status"> <span class="sr-only">Loading...</span> </div> </div> </div> <div class="tab-pane fade" id="report" role="tabpanel" aria-labelledby="report-tab"> <br> <br> <form> <div class="form-group"> <div class="city-post-input"> <label for="exampleInputEmail1"> <b>Enter the name of the city where you encountered an alien:</b> </label> <input type="text" class="form-control" id="city-post-input" aria-describedby="cityPost" placeholder="Enter City Name"> </div> </div> <button type="submit" class="btn btn-primary" onclick="postAlienEncounter();return false;">Report</button> </form> </div> </div> </div> </body> </html>
main.jscopyfunction postAlienEncounter() { debugger; var city = $("#city-post-input").val(); $.ajax({ url: "/alien", type: "post", contentType: "application/json", data: JSON.stringify({ "city_name": city }), success: function (data) { alert(data.message); }, error: function (error) { alert(error.message); } }); } function getAlienEncounter() { showLoader(); var positive = "https://media.giphy.com/media/Y1GYiLui9NHcxVKhdo/giphy.gif"; var negative = "https://media.giphy.com/media/fsPcMdeXPxSP6zKxCA/giphy.gif"; var city = $("#city-get-input").val(); $.ajax({ url: "/alien?city_name=" + city, type: "get", success: function (data) { console.log(data); $("#result-text").text(""); $("#result-text").text(data.message); var imagesrc = negative; if (data.signal == 'positive') { imagesrc = positive; } $("#result-image").html(""); $("#result-image").html("<img src='" + imagesrc + "' />"); hideLoader(); }, error: function (error) { alert(error.message); } }); } function showLoader() { $("#result-container").hide(); $("#loader").show(); } function hideLoader() { $("#loader").hide(); $("#result-container").show(); }
Update the value of the key command as “node index.js” in the app-config.json file. This is the startup command that is specific for this programming stack and framework.
app-config.jsoncopy{ "command": "node index.js", "buildPath": "/Users/amelia-426/Catalyst/Alien City", // provide your build path "stack": "node18", "env_variables": {}, "memory": 256, "scripts": {} }
Let’s quickly go through the working of the application:
GET Operation
- When you enter a city name in the application to check for a record of previous alien encounters, the onClick event for the Check button in index.html triggers the getAlienEncounter() function defined in main.js.
- This fires an Ajax call to the URL route defined in the index.js function.
- The GET API defined in index.js then invokes the getDataFromCatalystDataStore() function and passes the request query.
- This function searches for the data in the Alien City table in the Data Store by executing a ZCQL query.
- If a record matching the city name is found in the table, a positive signal is sent as the response. Otherwise, a negative signal is sent as the response.
- The client then displays the message that matches the response. A GIF matching the response defined in main.js is also displayed.
POST Operation
- When you enter a city name in the client to report an alien encounter, the onClick event for the Report button in index.html triggers the postAlienEncounter() function defined in main.js.
- This fires an Ajax call to the URL route defined in the index.js function. The POST API defined in index.js then invokes the getDataFromCatalystDataStore() function and passes a request query to check if a record with the same city name already exists.
- This function searches for the data in the Alien City table in the Data Store by executing a ZCQL query. If the record already exists, a response is sent, which enables the application to display a message the city name is already added.
- If there are no records for the city name, a new row is created in the Alien City table for the city name entered by the user. A pop-up box is displayed in the client confirming the insertion of the record in the Data Store. An appropriate message is also pushed to the logs which can be checked from the Logs component present in the Catalyst DevOps service.
Last Updated 2024-02-22 23:26:30 +0530 +0530