Splitting url parameter node.js? - node.js

I am having the following url parameter
sample value actual value contains so many parameters
var data = "browserName=MSIE&cookies=Rgn=%7CCode%3DMUMBAI%7Ctext%3DMumbai%7C; NREUM=s=1376355292394&r=220970&p=2080092;cs_uuid=209712058942163; cs_si=209712058942163.1&javascriptEnabled=true";
Following function is used to get the particular parameter
//Generic Function to get particular parameter
getParameterValue : function(data, parameter) {
var value = null;
if (data.length > 0) {
var paramArray = data.split("&");
for ( var i = 0; len = paramArray.length, i < len; i++) {
var param = paramArray[i];
var splitter = parameter + "=";
if (param.indexOf(splitter) > -1) {
value = param.substring(param.indexOf(splitter)
+ splitter.length, param.length);
break;
}
}
}
return value;
}
Example
getParameterValue(data, "browserName");
output is MSIE //correct
Problem is
getParameterValue(data, "cookies");
Output is
Rgn=%7CCode%3DMUMBAI%7Ctext%3DMumbai%7C; NREUM=s=1376355292394
But required output is
Rgn=%7CCode%3DMUMBAI%7Ctext%3DMumbai%7C; NREUM=s=1376355292394&r=220970&p=2080092;cs_uuid=209712058942163; cs_si=209712058942163.1
To Know :
1.URL parameter is encoded(clientside) while sending to node server and decoded.
2.NREUM is not encoded, So getParameterValue method splits upto 1376355292394.
Any help to improve getParameterValue function.
Ready to explain more.

Well, getParameterValue() does seem to be parsing data correctly, but data is not encoded properly to distinguish between delimiters and value characters.
The value of cookies, for example:
cookies=Rgn=%7CCode%3DMUMBAI%7Ctext%3DMumbai%7C; NREUM=s=1376355292394&r=220970&p=2080092;cs_uuid=209712058942163; cs_si=209712058942163.1
Should itself be encoded (on top of any encoding used for the cookie values themselves).
cookies=Rgn%3D%257CCode%253DMUMBAI%257Ctext%253DMumbai%257C%3B%20NREUM%3Ds%3D1376355292394%26r%3D220970%26p%3D2080092%3Bcs_uuid%3D209712058942163%3B%20cs_si%3D209712058942163.1
And, it's rather late to try to "fix" this server-side because of the ambiguity. It'll need to be encoded client-side, which can be done with encodeURIComponent().
'cookies=' + encodeURIComponent(cookies)
If you happen to be using jQuery, you can use jQuery.param() to help ensure proper encoding.
var data = {
browserName: 'MSIE',
cookies: document.cookie,
javascriptEnabled: true
};
data = $.param(data); // browserName=MSIE&cookies=Rgn%3D%257CCode...
Or, you can use a light-weight recreation, at least for the "traditional" format.
function urlParam(params) {
var res = [];
for (var name in params) {
res.push(encodeURIComponent(name) + '=' + encodeURIComponent(params[name]));
}
return res.join('&');
}
var data = urlParam(data);
Example: http://jsfiddle.net/GQpTB/
Also, are you aware that Node.js has querystring.parse()?
// with: var qs = require('querystring');
var query = qs.parse(data);
console.log(query.cookies); // ...

Related

NodeJS debugging coderbyte Task

node.js debugging json data in the javascript file, you have a program that performs a get request on the route https://coderbyte.com/api/challenges/json/age-counting which contains a data key and the value is a string which contains items in the format: key=string, age=integer. your goal is to print out the key id's between indices 10 and 15 in string format (e.g. q3kg6,mgqpf,tg2vm,...). the program provided already parses the data and loops through each item, but you need to figure out how to fix it so that it correctly populates keyarray with only key id's.
here is code given by coderbyte.
const https = require('https');
https.get('https://coderbyte.com/api/challenges/json/age-counting', (resp) => {
let content = '';
// push data character by character to "content" variable
resp.on('data', (c) => content += c);
// when finished reading all data, parse it for what we need now
resp.on('end', () => {
let jsonContent = JSON.parse(content);
let jsonContentArray = jsonContent.data.split(',');
let keyArray = [];
for (let i = 0; i < jsonContentArray.length; i++) {
let keySplit = jsonContentArray[i].trim().split('=');
keyArray.push(keySplit[1]);
}
console.log(keyArray.toString());
});
});
const https = require('https');
https.get('https://coderbyte.com/api/challenges/json/age-counting', (resp) => {
let content = '';
// push data character by character to "content" variable
resp.on('data', (c) => content += c);
// when finished reading all data, parse it for what we need now
resp.on('end', () => {
let jsonContent = JSON.parse(content);
let jsonContentArray = jsonContent.data.split(',');
let keyArray = [];
console.log(jsonContentArray.length);
// Traversing over the json content array and checking only for keys while ignoring the age.
for (let i = 0; i < jsonContentArray.length; i+=2) {
// extracting only the keys by triming the white space and splitting the data by "=" and taking the first character from the array.
let key = jsonContentArray[i].trim().split('=')[1];
// Now pushing only the 10*2 for getting the keys and ignoring the age. If you look into the json you get a better understanding.
// Here is an eg of json considered.
// data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47, key=0Sr4C, age=68, key=CGEqo, age=76, key=IxKVQ, age=79, key=eD221, age=29, key=XZbHV, age=32, key=k1SN5, age=88, .....etc
if (i>=20 && i< 30) {
keyArray.push(key);
}
}
console.log(keyArray);
});
});

Parsing JSON from Wikipedia API throws an error, but only a quarter of the time

I'm trying to get the summary of a random article using the Wikipedia API, but for some reason when parsing the JSON, I run into this error about a quarter of the time:
Unexpected token < in JSON at position 0. Why is this happening? I've pasted the link into my browser manually multiple times and haven't seen anything wrong with the JSON string.
const articleCount = 10;
const fetch = require('sync-fetch');
function article()
{
return fetch('https://en.wikipedia.org/api/rest_v1/page/random/summary').json().extract;
}
var source = '';
for(let i = 0; i < articleCount; i++)
{
source += article() + ' ';
console.log(parseInt(i/articleCount * 100) + '%');
}
console.log(source);
I've switched out the .json() method with JSON.parse(string), but it has the same problem.

cant get variable value in node js

I tried to make the function async but when I print the attacks it prints out {} without anything in it but when I print the values right after adding them in attacks I can print them why is it like that? how can I use the value?
var fs = require('fs');
var http = require('http');
var attacks = {};
var phase_name;
var directory = 'cti-master\\enterprise-attack\\attack-pattern\\';
// getting all files names.
async function getData(directory){
fs.readdir(directory, (err, files) => {
if(err) { return;}
var fileNum = 0;
// opening all the files and sorting the data in them.
while (fileNum < files.length - 1)
{
fs.readFile(directory + files[fileNum], 'utf8', (err, data) =>
{
// parsing the data from json.
var fileData = JSON.parse(data);
// sometimes there is no phase name.
if(fileData['objects'][0]['kill_chain_phases'] == undefined){phase_name = undefined;}
else{phase_name = fileData['objects'][0]['kill_chain_phases'][0]['phase_name'];}
// sorting data by name to make it easier later.
attacks[fileData['objects'][0]['name']] = {
id: fileData['objects'][0]['id'],
type: fileData['objects'][0]['type'],
description: fileData['objects'][0]['description'],
x_mitre_platforms: fileData['objects'][0]['x_mitre_platforms'],
x_mitre_detection: fileData['objects'][0]['x_mitre_detection'],
phase_name: phase_name};
});
fileNum += 1;
};
});
var keys = Object.keys(attacks);
console.log(attacks);
}
getData(directory);
The reason for the empty log here because the node does not wait to finish while loop Hence you are getting empty log. Basically, you can improve this code by using the async-await method.
But if you are stick with this code, I am just suggesting this logic.
Just bring your log inside an if condition block. which have condition "print only if expected file count reached"
for example.
if(fileNum === files.length) {
var keys = Object.keys(attacks);
console.log(attacks);
}
So now log print only when this condition is satisfied which means after completion of while loop

Using knex SELECT query results for another SELECT query

I am trying to run a PostgreSQL query with Knex and then use the results to run another query.
exports.buildBuoyFeaturesJSON = function (conditionA, conditionB) {
var query = null;
var selectedFields = knex.select
(
knex.raw('t_record.id AS id'),
...
knex.raw('t_record.latitude AS latitude'),
knex.raw('t_record.longitude AS longitude')
)
.from('t_record')
.then(function (response) {
var geometry_array = [];
var rows = response.rows;
var keys = [];
for (var key = 0; key <= rows.length - 1; key++) {
var geometry =
{
"id" : rows[key].id,
"type" : "Feature",
"geometry" : rows[key].geometry,
"properties" : {
...
"sensors" : []
}
};
keys.push(rows[key].id);
geometry_array.push(geometry);
}
getMeasurementsAndSensors(keys, geometry_array);
});
};
The latter function uses some of the results from the previous function. Due to asynchronous nature of Knex, I need to call the second function from inside the first function's .then() statement:
function getMeasurementsAndSensors (keys, geometry_array) {
var query = knex
.select
(
't_record_id',
'i_sensor_id',
'description',
'i_measurement_id',
't_sensor_name',
't_measurement_name',
'value',
'units'
)
.from('i_record')
...
.whereRaw('i_record.t_record_id IN (' + keys + ')')
.orderByRaw('t_record_id, i_sensor_id ASC')
.then(function (response) {
var rows = response.rows;
var t_record_id = 0;
var i_sensor_id = 0;
var record_counter = -1;
var sensor_counter = -1;
for (var records = 0; records <= rows.length -1; records++) {
if (t_record_id !== rows[records].t_record_id) {
t_record_id = rows[records].t_record_id;
record_counter++;
sensor_counter = -1;
}
if (i_sensor_id !== rows[records].i_sensor_id) {
i_sensor_id = rows[records].i_sensor_id;
geometry_array[record_counter].properties.sensors[++sensor_counter] =
{
'i_sensor_id' : rows[records].i_sensor_id,
't_sensor_name' : rows[records].t_sensor_name,
'description' : rows[records].description,
'measurements' : []
};
}
geometry_array[record_counter].properties.sensors[sensor_counter].measurements.push
({
'i_measurement_id': rows[records].i_measurement_id,
'measurement_name': rows[records].t_measurement_name,
'value': rows[records].value,
'units': rows[records].units
});
}
//wrapping features with metadata.
var feature_collection = GEOGRAPHY_METADATA;
feature_collection.features = geometry_array;
JSONToFile(feature_collection, 'buoy_features');
});
}
Currently I save end result to a JSON file because I couldn't get Promises to work. JSON is later used to power a small OpenLayers application, hence the JSON-ification after getting results.
I am quite sure that getting the data from a database, saving it to file, then accessing it from another process and using it for OpenLayers is a very redundant way to do it, but so far, it is the only one that works.
I know there are a lot of ways to make these functions work better, but I am new to promises and don't know how to work with them outside of most basic functions. Any suggestions how to make this code better are welcome.
All you appear to be missing is a bunch of returns.
Here are skeletonized versions of the two functions, including the necessary returns :
exports.buildBuoyFeaturesJSON = function(conditionA, conditionB) {
return knex.select (...)
^^^^^^
.from(...)
.then(function(response) {
// synchronous stuff
// synchronous stuff
return getMeasurementsAndSensors(keys, geometry_array);
^^^^^^
}).then(function(geometry_array) {
var feature_collection = GEOGRAPHY_METADATA;
feature_collection.features = geometry_array;
return feature_collection;
^^^^^^
});
};
function getMeasurementsAndSensors(keys, geometry_array) {
return knex.select(...)
^^^^^^
.from(...)
...
.whereRaw(...)
.orderByRaw(...)
.then(function(response) {
// heaps of synchronous stuff
// heaps of synchronous stuff
// heaps of synchronous stuff
return geometry_array;
^^^^^^^^^^^^^^^^^^^^^
});
}
I moved the feature_collection collection part into buildBuoyFeaturesJSON() on the basis that it seems to sit there more logically. If not, then it would be very simple to move it back into getMeasurementsAndSensors().
I have not tried to fix the additional issue highlighted by #vitaly-t.

Why is my for-loop only counting to one object in the JSON-response?

I'm trying to make a map with map-annotations which are being generated from a REST-JSON response. I've succeeded with making one, the JSON response contains two objects. Why are only one printed out?
I'm using RestSharp and Xamarin.iOS.
Here's a Gist-clone of the original respones
The function that grabs the data to later-on make map-annotations on our map:
Action getAllMarkers = () => {
var client = new RestClient("http://www.example.com/");
var request = new RestRequest(String.Format("api/?function=searchByName&key=&name=Sundsvall"));
client.ExecuteAsync (request, response => {
JsonValue data = JsonValue.Parse(response.Content);
for (var i = 0; i < data.Count; i++){
Double lat = data["result"][i]["lat"];
Double lng = data["result"][i]["lng"];
String name = data["result"][i]["title"];
String adress = data["result"][i]["adress"];
var store = new BasicMapAnnotation (new CLLocationCoordinate2D(lat, lng), name, adress);
Console.WriteLine(response.Content);
InvokeOnMainThread ( () => {
// manipulate UI controls
map.AddAnnotation(store);
});
}
});
};
getAllMarkers();
data.Count is 1, because there is one top level "result" node in your json. Use data["result"].Count instead.
your result is main array in which rest of the data is so use:data["result"].Count instead of data.Count

Resources