Make Ajax call to Express server to retrieve dictionary - javascript

I have a dictionary on my server that is set up by Express. I pushed the dictionary, chunks, to the server using the app.get() function and set the url to /search.
Here is that code:
app.get('/search', function (req, res) {
var queryString = req.query.query
console.log(queryString)
var results = Object.keys(index).reduce(function(a, b) {
if (b.toLowerCase() === queryString.toLowerCase()) {
return a.concat(index[b]);
} else {
console.log("error")
}
return a;
}, []);
******
var num_chunks = Math.round(results.length/12)
var chunks = []
for (var i=0; i<num_chunks; i++) {
var j = 12*i
var sliced = results.slice(j, j+12)
chunks.push({
key: Math.floor((Math.random() * 100000000000000000000) + 1),
value: sliced
})
}
******
res.header("Content-Type",'application/json');
res.json(results);
});
Now on the client side of my website, I want to retrieve chunks and interact with the contents of it. Could anyone tell me how I would implement an Ajax/jQuery call to get the dictionary and then reference it in my client side code?
Here is what my ajax function looks like right now, but it is missing the key elements:
$.ajax({
url: '/search',
data: _needs to be filled in_,
success: _needs to be filled in_,
dataType: "json"
});
Any help would be immensely appreciated. Thanks so much in advance.
Cheers, Theo

Related

Sending data from NodeJS to the client by using Ajax calls

I increase a value at the server by running an Ajax call and want to update my UI after doing this
function increaseHitpoints(){
$.ajax({
type: 'GET',
url: 'http://localhost:8888/incHp/2312'
}).done(function (data) {
$("#txtHitpoints").html(data);
});
}
In my app.js I read a JSON file, manipulate the value, write it back to the file and return it to the client
app.get('/incHp/:id', function (req, res) {
var database = './database.json';
fs.readFile(database, 'utf8', function (err, data) { // read the data
var json = JSON.parse(data);
var users = json.users;
var hitpoints;
users.find(u => {
if (u.id === Number(req.params.id)) { // get the user by id
u.hitpoints++;
hitpoints = u.hitpoints;
}
});
json = JSON.stringify(json);
fs.writeFile(database, json, (err) => { // update the JSON file
// -> missing part here <-
});
});
});
what do I have to pass into the missing part if I want to return the new value? The new value would be hitpoints
I tried res.send(hitpoints); but it seems this function wants to return a status code, not a value.
If you send a numerical value, it will be observed as an HTTP response code
https://expressjs.com/en/api.html#res
But you can send your hitpoints as a string res.send(hitpoints.toString())or as json res.send({hits: hitpoints});
Depends on what format you want your response to be. I prefer using JSON. So in JSON case you would do this:
fs.writeFile(database, json, (err) => {
res.status(200).json({yourKey: yourValue});
});
Then you can access the JSON object in your frontend:
$("#txtHitpoints").html(data.yourKey);

Get all files in directory json

I want get all files json in my directory for search into it.
$('#get-data').click(function () {
var showData = $('#show-data');
$.getJSON('/data/**all files json**', function (data) {
console.log(data);
var items = data.items.map(function (item) {
return item.key + ': ' + item.value;
});
showData.empty();
if (items.length) {
var content = '<li>' + items.join('</li><li>') + '</li>';
var list = $('<ul />').html(content);
showData.append(list);
}
});
showData.html(data);
});
Do you think its possible or i need use other method ?
Thx
You cannot make a wildcard AJAX request that will return all the possible JSON files on your server. You need to know in advance the exact endpoint that you will be sending your request to. Otherwise it would be a security vulnerability if all clients could know in advance what files are available on the server.
So one possible strategy here would be to have some /describe endpoint on your server which will return a list of all available JSON files. Then the client will first make an AJAX request to this endpoint and then for each returned endpoint in the list it will make a separate AJAX request:
$.getJSON('/data/discover', function (data) {
// suppose that data looks like this:
// ["/data/a.json", "/data/b.json", "/data/c.json"]
for (var i := 0; i < data.length; i++) {
// send an AJAX request to each individual JSON file
// available on the server as returned by the discover endpoint
$.getJSON(data[i], function (result) {
...
});
}
});
Basically you can't request for multiple files by one request.
However the scenario is perfect fit for async.parallel:
var async = require('async');
app.get('/json', function(req, res) {
var work = {
file01: async.apply(fs.readFile, __dirname + '/file01.json'),
file02: async.apply(fs.readFile, __dirname + '/file02.json')
};
async.parallel(work, function (error, results) {
if (error) {
res.status(500).send(error);
return;
}
//might need string->Object here
results['file01'] = JSON.parse(results['file01']);
results['file02'] = JSON.parse(results['file02']);
res.send(results);
});
});

How do I protect jQuery.get url?

Hi i just want to protect my jQuery.get url (data.php) if any chance to make jQuery.get in class or any else?
my code here here
jQuery.get('data.php', null, function(data) {
var lines = [];
traffic = [];
try {
// split the data return into lines and parse them
data = data.split(/\n/g);
jQuery.each(data, function(i, line) {
line = line.split(/\t/);
date = Date.parse(line[0] +' UTC');
traffic.push([
date,
parseInt(line[1].replace(',', ''), 10)
]);
});
} catch (e) { }
/// options.series[0].data = traffic;
//$res = traffic;
});
and i want to protect the url of data.php
ps: data.php is my side trafic from sql snd im using for highcharts so the the call for hightcharts is
series: [{
name: 'Stats',
data: traffic
Thanks in advance anyone!

Clean way to make Subsequent AJAX Calls to API based on Data

So I have a conceptual question regarding the cleanest way to make subsequent AJAX calls to an API based on the returned data.
A quick example:
A function, which encompasses the call would look like this:
function makeCall(headers, min, max) {
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON'
});
}
makeCall(headers, 0, 20);
The beg / end index (min/max), determine the amount of data I'll get back in the array. The API will only return a maximum of 20 items in the array, but it will also return me a COUNT of how many items total exist in that array. An example of the data returned is below:
{
count = 133;
result = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];
}
So my next call would be:
makeCall(headers, 20, 40);
and so on so forth, until I got all 133 items from the array.
The question is...what is the cleanest way to continue to make subsequent calls until I've gotten and stored all 133 items from the array? Given that the count could be any number, it's hard to imagine how I can do this. I was thinking of nesting more ajax calls in a "success" function, but it's not scalable if I get back a number like 300.
Does anyone have any advice on how to proceed?
Thanks in advance!
EDIT:
So based on the advice in the comment, I've attemped to make the call recursive--but it doesn't seem to function as intended:
var theData = [];
var minCounter=0;
var maxCounter= minCounter + 20;
function makeCall(headers, min, max) {
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON',
success: function (data) {
theData.push(data.result);
newMin = minCounter + 20;
if (data.count >= theData.length ) {
makeCall(headers, newMin, maxCounter);
}
}
});
}
makeCall(headers, minCounter, maxCounter);
How do properly increment the variable as well as set the flag?
SECOND EDIT:
The method below works using the second comment's suggestion, but there are some issues here as well...
function doAjax(headers, min, dObject) {
var max = min + 20;
$.ajax({
headers: headers,
url: "https://coolapi.com/data?begIndex" + min + "&endIndex=" + max + "&begTimestamp=1404198000000&endTimestamp=1409554800000",
type: "GET",
dataType: 'JSON',
success: function (data) {
results.push(data);
window.count = data.count;
dObject.resolve();
}
});
}
// array that will contain all deferred objects
var deferreds = [];
// array that will contain all results
var results = [];
// make the ajax calls
for (var i = 20; i < 133 ; i+= 20) {
var dObject = new $.Deferred();
deferreds.push(dObject);
doAjax(headers, i, dObject);
}
// check if all ajax calls have finished
$.when.apply($, deferreds).done(function() {
console.log(results);
});
var dObject = new $.Deferred();
doAjax(headers,0, dObject);
First, the data doesn't push to the array in order. There doesn't seem anyway to fix this. Also strangely enough, in the for loop--I have to set the number for it to actually work. Trying to store it in a variable doesn't seem to work as well...Suggestions here?
Here's a working implementation based around the code you started with. Code is commented to help you understand what is happening:
// Change these constants to suit your purposes.
var API_URL = 'https://coolapi.com/data';
var HEADERS = {};
var API_RESULTS_PER_REQUEST = 20;
var MAX_API_CALLS = 20;
// Count API calls to trigger MAX_API_CALLS safety lock.
var apiCalls = 0;
// Function we'll call to get all our data (see bottom).
function collectApiData(begTimestamp, endTimestamp) {
var dataReady = jQuery.Deferred();
var params = {
'begTimestamp': begTimestamp,
'endTimestamp': endTimestamp
};
var datasetsCollected = requestDatasets(params);
jQuery.when(datasetsCollected).then(function(data) {
dataReady.resolve(data);
});
return dataReady;
}
// Makes individual AJAX call to API
function callApi(params, headers) {
var $request = jQuery.ajax({
url: API_URL,
headers: headers,
data: params,
type: 'GET',
dataType: 'JSON'
});
return $request;
}
// Recursive function that makes API calls until data is collected, there is an
// error, or MAX_API_CALLS limit is hit.
function requestDatasets(params, resultsReady, resultsFetched) {
resultsReady = ( resultsReady !== undefined ) ? resultsReady : jQuery.Deferred();
resultsFetched = ( resultsFetched !== undefined ) ? resultsFetched : [];
// Trigger safety to avoid API abuse
if ( apiCalls >= MAX_API_CALLS ) {
console.error('Exceeded max API calls:', MAX_API_CALLS);
resultsReady.resolve(resultsFetched);
}
// Set index data
params.begIndex = resultsFetched.length;
params.endIndex = resultsFetched.length + API_RESULTS_PER_REQUEST;
// Request dataset from API
var apiRequest = callApi(params, HEADERS);
apiCalls += 1;
// Callback once API request has completed and data is ready
jQuery.when(apiRequest).done(function(data) {
var apiResultCount = data.count;
resultsFetched = resultsFetched.concat(data.result);
console.debug('Fetched', resultsFetched.length, 'of', apiResultCount, 'API results');
if ( apiResultCount > resultsFetched.length ) {
console.debug('Making another API call');
requestDatasets(params, resultsReady, resultsFetched);
}
else {
console.debug('Results all fetched!');
resultsReady.resolve(resultsFetched);
}
});
jQuery.when(apiRequest).fail(function(data) {
console.error('API error: returning current results.');
resultsReady.resolve(resultsFetched);
});
return resultsReady;
}
// Run script
var dataReady = collectApiData('1404198000000', '1409554800000');
jQuery.when(dataReady).then(function(data) {
console.log(data);
});
Here's a working fiddle that mocks the API using httpbin.org:
http://jsfiddle.net/klenwell/mfhLxun2/

Javascript/Ajax success request delete record from websql

I use the following code to query my websql database to see if there are any records.
If records are found then I use an ajax request to submit these to an asp page which in turn pushes the form information on to a sql server.
So far everything is good however I now want to delete each of the records from the WebSql database only when the ajax request returns a success.
I can't for the life of me get my head around javascript functions and scope correctly when they are nested this big (i've only been writing js/jquery now for a couple of weeks).
I know I need to capture the ID which I have set as a variable vID an then execute another sql statement to delete the record, nested within the success criteria of my ajax call. I cant get vID to reference correctly and then I do not know how to set up the call to execute the sql again based on this.
function Web_SQL_Storage_Open_And_Check() {
if (window.openDatabase) {
var db = openDatabase("ER_Nonconformance", "1.0", "Non-conformance Report DB", 4 * 1024 * 1024); //creates our database if it does not exist at 4mb size
var db2 = db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS tbllog (ID INTEGER PRIMARY KEY ASC AUTOINCREMENT, DteOccur datetime, Pdetected nvarchar(50), DeptRaisedBy int, DeptResp int, NCDescrip nvarchar(255), NCCause nvarchar(255), NCImmediateAct nvarchar(255), NCLocation nvarchar(100), PNumOrRef nvarchar(30), EventCat int, ReportedEmailAddy nvarchar(100), Location_Category int)");
tx.executeSql("SELECT * FROM tbllog", [], function(tx, result) {
if (result.rows.length > 0) {
alert("we need to submit")
for (var i = 0; i < result.rows.length; i++) {
//Submit values to the asp page using the below loop
var vID = (result.rows.item(i)['ID'])
var vPdetected = result.rows.item(i)['Pdetected']
var vDteOccur = result.rows.item(i)['DteOccur']
var vDeptRaisedBy = result.rows.item(i)['DeptRaisedBy']
var vDeptResp = result.rows.item(i)['DeptResp']
var vNCDescrip = result.rows.item(i)['NCDescrip']
var vNCCause = result.rows.item(i)['NCCause']
var vNCImmediateAct = result.rows.item(i)['NCImmediateAct']
var vNCLocation = result.rows.item(i)['NCLocation']
var vPNumOrRef = result.rows.item(i)['PNumOrRef']
var vEventCat = result.rows.item(i)['EventCat']
var vReportedEmailAddy = result.rows.item(i)['ReportedEmailAddy']
var vLocation_Category = result.rows.item(i)['Location_Category']
var request = $.ajax({
url: "untitled.asp",
type: "post",
data: {
DteOccur: vDteOccur,
Pdetected: vPdetected,
DeptRaisedBy: vDeptRaisedBy,
DeptResp: vDeptResp,
NCDescrip: vNCDescrip,
NCCause: vNCCause,
NCImmediateAct: vNCImmediateAct,
NCLocation: vNCLocation,
PNumOrRef: vPNumOrRef,
EventCat: vEventCat,
ReportedEmailAddy: vReportedEmailAddy,
Location_Category: vLocation_Category
},
dataType: "html"
}
);
request.done(function() { alert("done"); })
request.fail(function() { alert("error"); })
request.always(function() { alert("complete"); });
}
}
else {
//no records found so do nothing
alert("do nothing")
} //end of if statement
}, function(tx, error) {
alert("error retrieving")
})
//tx.executeSql();
});
}
}
Define var vID outside function, not inside and that gives you the correct reference.

Categories