Programar tu aplicación
Has creado el archivo “index.js” en el directorio raíz de tu proyecto, y este contendrá la lógica del backend de tu aplicación.
Crea una carpeta en el directorio raíz de tu proyecto y nómbrala “public.” Esta carpeta contendrá los archivos para tu lógica de front-end. Crea los siguientes archivos dentro de tu carpeta public (Alien City/public/):
- index.html: El archivo que contiene el código HTML para el front-end de la aplicación.
- main.js: El archivo que contiene el código JavaScript que conecta el front-end y el backend.
Esta es la estructura final de carpetas del proyecto Alien City.

Programarás los archivos index.js, index.html y main.js. También actualizarás el archivo app-config.json.
Copia el código a continuación y pégalo en los archivos correspondientes de tu proyecto usando un IDE y guarda los archivos.
var express = require('express');
var app = express();
var catalyst = require('zcatalyst-sdk-node');
app.use(express.json());
app.use(express.static('public'));
const tableName = 'AlienCity'; // La tabla creada en el Data Store
const columnName = 'CityName'; // La columna creada en la tabla
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);
// Inserta el nombre de la ciudad como una fila en la tabla del Catalyst Data Store
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;
// Inicializando el SDK de Catalyst
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) => {
// Consulta la tabla del Catalyst Data Store
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;
<!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>
function 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();
}
Actualiza el valor de la clave command como “node index.js” en el archivo app-config.json. Este es el comando de inicio que es específico para esta pila de programación y framework.
{
"command": "node index.js",
"buildPath": "/Users/amelia-426/Catalyst/Alien City", // proporciona tu ruta de compilación
"stack": "node18",
"env_variables": {},
"memory": 256,
"scripts": {}
}
Repasemos rápidamente el funcionamiento de la aplicación:
-
Operación GET
- Cuando ingresas el nombre de una ciudad en la aplicación para verificar si hay un registro de encuentros previos con alienígenas, el evento onClick del botón Check en index.html activa la función getAlienEncounter() definida en main.js.
- Esto realiza una llamada Ajax a la ruta URL definida en la función index.js.
- La GET API definida en index.js luego invoca la función getDataFromCatalystDataStore() y pasa la consulta de la solicitud.
- Esta función busca los datos en la tabla Alien City en el Data Store ejecutando una consulta ZCQL.
- Si se encuentra un registro que coincide con el nombre de la ciudad en la tabla, se envía una señal positiva como respuesta. De lo contrario, se envía una señal negativa como respuesta.
- El client luego muestra el mensaje que coincide con la respuesta. También se muestra un GIF que coincide con la respuesta definida en main.js.
-
Operación POST
- Cuando ingresas el nombre de una ciudad en el client para reportar un encuentro con alienígenas, el evento onClick del botón Report en index.html activa la función postAlienEncounter() definida en main.js.
- Esto realiza una llamada Ajax a la ruta URL definida en la función index.js. La POST API definida en index.js luego invoca la función getDataFromCatalystDataStore() y pasa una consulta de solicitud para verificar si ya existe un registro con el mismo nombre de ciudad.
- Esta función busca los datos en la tabla Alien City en el Data Store ejecutando una consulta ZCQL. Si el registro ya existe, se envía una respuesta que permite a la aplicación mostrar un mensaje de que el nombre de la ciudad ya fue agregado.
- Si no hay registros para el nombre de la ciudad, se crea una nueva fila en la tabla Alien City para el nombre de la ciudad ingresado por el usuario. Se muestra un cuadro emergente en el client confirmando la inserción del registro en el Data Store. También se envía un mensaje apropiado a los logs que se puede verificar desde el componente Logs presente en el servicio Catalyst DevOps.
Última actualización 2026-03-20 21:51:56 +0530 IST