Hello I am needing some assistance with a current project I am working on. The goal is to be able to interact with SQL from the UI and display the returned data in a table.
I am using node V9.8.0, express 4.16.3 and mssql 4.1.0.
I am able to connect and fetch data and display it on the UI but I do not think my set up is best practice.
My main road block was figuring out how to send information to the server to than query SQL and redirect the user back to the UI with the table displayed with the expected data.
Front end set up, form and ajax. I know that the action in the form should match the URL for ajax but to get this to work I have two post routes on the sever side. The form submits to the first post route and writes the req.body to a file. The ajax post URL reads the file and than connects to SQL and knows what data to fetch based on the user's input and predefined query strings that can take in parameters.
<form id="myForm" action="/qa-hub/tools/wss_qa_tool/sql/data" method="POST">
<div class="row">
<div class="col-md">
<div class="form-group">
<select type="text" id="slct1" class="form-control" placeholder=" SQL query search..."
name="query" list="query">
<option value="">Query select...</option>
<option value="vacant_units">vacant_units</option>
<option value="cancelable_contracts">cancelable_contracts</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md">
<div class="form-group">
<input type="text" id="slct2" style="display: none;" class="form-control" placeholder="Entity #" name="location" />
</div>
</div>
</div>
<div class="row">
<div class="col-md">
<div class="form-group">
<input type="text" id="slct3" style="display: none;" class="form-control" placeholder="Unit #" name="unit" />
</div>
</div>
</div>
<button value="submit" id="submitBtn" class="btn btn-secondary" style="width: 25%; font-size: 14pt">Submit</button>
</form>
<script>
$.ajax({
type: "POST",
url: "/qa-hub/tools/wss_qa_tool/api/data",
dataType: "json"
}).then(addData)
function addData(data) {
// console.log(Object.keys(data.recordset[0]));
Object.keys(data.recordset[0]).forEach(function(column) {
$("#theadRow").append("<th>" + column + "</th>");
});
let master = "";
for(var i = 0; i < data.recordset.length; i++) {
for( var key in data.recordset[i]) {
var current = "<td>" + data.recordset[i][key] + "</td>";
master = master + current;
}
$("#tBody").append("<tr>" + master + "</tr>");
master = "";
}
$('#myTable').DataTable()
}
</script>
This is my set up on the server side. So this will take in the req.body from the form and write it to a file, than redirect the user back.
router.post("/sql/data", (req, res) => {
let query = req.body.query;
let sent_params = queries[query].params;
let sentArr = sent_params.map( x => req.body.hasOwnProperty(x));
// console.log(sentArr);
if(sentArr.includes(false) ) {
console.log("Missing parameter");
res.redirect("/qa-hub/tools/wss_qa_tool");
} else {
let tempObj = {};
for(var i = 0; i < sent_params.length; i++) {
tempObj[sent_params[i]] = req.body[sent_params[i]];
}
tempObj["query"] = query;
let sentObj = tempObj;
let userId = req.user.id;
fs.writeFile(`./temp/${userId}.json`, JSON.stringify(sentObj), (error) => {
if(error) console.log(error);
res.redirect("back");
});
}
});
This is where the magic happens. This post route will than read the file and pass in the information to saved SQL queries that can take in parameters and than sends the information back to the UI.
router.post("/api/data", (req, res, next) => {
let userId = req.user.id;
fs.readFile(`./temp/${userId}.json`, "utf-8", (err, info) => {
if(info === undefined || info === "" || Object.keys(JSON.parse(info)).length === 0 ) {
console.log("No data was found.");
} else {
let data = JSON.parse(info);
let query = data.query;
let location = data.location;
let unit = data.unit;
let selected_query = queries[query].arguments([location, unit]);
var config = {
user: 'xxxx',
password: 'xxxx',
server: 'xxxx',
database: 'xxxx'
};
sql.connect(config, function (err) {
if (err) console.log("Error at the config.");
console.log("Connected!");
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query( selected_query, function (err, queryData) {
if (err) console.log("There was an error")
// console.log(queryData);
res.send(JSON.stringify(queryData));
sql.close();
console.log("SQL connection closed.")
fs.unlink(`./temp/${userId}.json`, (err) => {
if(err) console.log(err);
console.log("File was deleted successfully!");
});
});
});
}
});
});
To me this seems like a hackish set up but I needed to produce results sooner than later. What I could not figure out or find was how can I produce the same set up with maybe one post route? I could not wrap my head around how to send information to the server, SQL query to fetch data and than redirect the data and user back to the same page. Wondering what the best practice would be for this type of set up? Or possibly any insightful reading to help guide me? Any assistance is appreciated.