Retrieve data from file on local machine - javascript

I have an html file with just a table, containing 5 cells in a single row, displaying 5 NFL teams.
The td's ids are "Team0" to "Team4" (left to right).
My purpose is to move a double clicked team to the last position in the right (to the cell wich id is "Team4").
In every td I have a call to Rearrange_Teams(iPosition).
iPosition is the number in the td id (Team3 calls Rearrange_Teams(3).
The following code works fine, but I'd like to change the function Load_Teams(), in order to load the teams from a file in my desktop (where my html file is saved):
<script>
Array.prototype.Rearrange = function(from,to){
this.splice(to,0,this.splice(from,1)[0]);
return this;
};
var aTeams = [];
Load_Teams();
List_Teams();
function Load_Teams() {
aTeams [0] = "PANTHERS";
aTeams [1] = "CARDINALS";
aTeams [2] = "BENGALS";
aTeams [3] = "BRONCOS";
aTeams [4] = "PATRIOTS";
}
function List_Teams() {
document.getElementById("Team0").innerHTML = aTeams [0];
document.getElementById("Team1").innerHTML = aTeams [1];
document.getElementById("Team2").innerHTML = aTeams [2];
document.getElementById("Team3").innerHTML = aTeams [3];
document.getElementById("Team4").innerHTML = aTeams [4];
}
function Rearrange_Teams(iPosition_Clicked) {
aTeams.Rearrange(iPosition_Clicked,4);
List_Teams();
}
</script>
Both the html page and the data file (JSON? txt?) are supposed to be saved in my computer (desktop or user directory, whatever...).
I just can't find an answer to help me with this... well, at least I can't understand the changes I'd have to make in the codes I've seen around...
The idea is to save the changes in the list, so I have to load the previous configuration and save the actual ones...
It's not possible to set up a local webserver, as I was suggested before, cause the intention is to use this page at my work and the users don't have administrator privileges (myself included).
We currently use an Excel worksheet with VBA, to get the job done, but I want to change it to the browser.
EDITED AFTER REPLY:
I've tried:
function Load_Teams() {
var actual_JSON;
loadJSON("My_File_with_Data.json", function(response) {
actual_JSON = JSON.parse(response);
});
alert(actual_JSON);
}
function loadJSON(filename, callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', filename, true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
};
xobj.send(null);
}
But nothing happened...
The alert(actual_JSON) shows nothing (just a blank pop up, with an "ok").
And I have no idea how I should pass the content of actual_JSON (does it really have any???) to aTeams.
The file My_File_with_Data.json looks like this:
{"jTeams": ["PANTHERS","CARDINALS", "BENGALS", "BRONCOS", "PATRIOTS"]}
NEW APPROACH:
var aTeam = [];
readTextFile();
List_Teams();
function readTextFile(){
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "Teams.txt", true);
rawFile.onreadystatechange = function (){
if(rawFile.readyState === 4){
var allText = rawFile.responseText;
aTeam = allText.split("/");
alert(aTeam[4]);
}
}
rawFile.send();
}
function List_Teams() {
document.getElementById("Team0").innerHTML = aTeam[0];
document.getElementById("Team1").innerHTML = aTeam[1];
document.getElementById("Team2").innerHTML = aTeam[2];
document.getElementById("Team3").innerHTML = aTeam[3];
document.getElementById("Team4").innerHTML = aTeam[4];
}
The file Teams.txt looks like:
PANTHERS/CARDINALS/BENGALS/BRONCOS/PATRIOTS
When readTextFile() runs, the alert(aTeam[4]) displays PATRIOTS.
But List_Teams() fills my table with undefined.
How come??? Seems to be a matter of scope, but aTeam is a global!...

A slightly modified version of code from this blog post, here is a function you can use to load JSON:
function loadJSON(filename, callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', filename, true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
to use this function, you need a callback:
var actual_JSON;
loadJSON("localhost:8000/my-file", function(response) {
// Parse JSON string into object
actual_JSON = JSON.parse(response);
});
alert(actual_JSON);
replace /my-file with a path to your file.
You also need a server at the location, which you can set up quickly like this

Related

I want to store data samples from an excel sheet into an array in javascript

I am using sheetJS in order to manipulate excel sheets. My goal is to extract the value of a cell and store it in an array as raw data for later statistical analysis and graphing.
Here is what the function looks like:
function getSheetData()
{
let rawData = [];
/* set up XMLHttpRequest */
var url = "test.xlsx";
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.send();
oReq.onload = function (e) {
var arraybuffer = oReq.response;
/* convert data to binary string */
var data = new Uint8Array(arraybuffer);
var arr = new Array();
for (var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
var bstr = arr.join("");
/* Call XLSX */
var workbook = XLSX.read(bstr, {
type: "binary"
});
/* DO SOMETHING WITH workbook HERE */
var sheet_name_list = workbook.SheetNames;
// var worksheet;
sheet_name_list.forEach(function(y) { /* iterate through sheets */
var worksheet = workbook.Sheets[y];
for (z in worksheet) {
/* all keys that do not begin with "!" correspond to cell addresses */
if(z[0] === '!') continue;
// console.log(z + " = " + JSON.stringify(worksheet[z].v));
rawData.push(worksheet[z].v);
}
});
/* Get worksheet */
// console.log(XLSX.utils.sheet_to_json(worksheet, {
// raw: true
// }));
console.log("raw data = " + rawData);
}
// console.log(rawData);
return rawData;
}
The console.log defined as 'raw data' shows all the numbers in one array just how I need it. However, the array named "rawData" returns as undefined by the end of the function.
I am calling the function here:
window.onload = function()
{
const data = getSheetData();
const BenfordTable = calculateBenford(data);
printAsTable(BenfordTable);
printAsGraph(BenfordTable);
}
I get data as an empty array
I have included a picture of the browser window
screenshot of console results in google chrome
data is an empty array because getSheetData() is an asynchronous function - that is to say, you are making an XMLHttpRequest call from within it. If you put console logs within your onload handler and right before your return statement, you will see that the latter runs first. The issue is that when your function returns, the call to the server will not have yet returned.
There are a few different ways of writing asynchronous code, but I think you should start off by passing a callback function to getSheetData() which will be called from within your onload handler. This callback function will be what handles rawData.
Here's roughly how you might do this. I have omitted some of the existing code for brevity, but obviously you will need it.
function getSheetData(callback)
{
let rawData = [];
// ...other code
oReq.onload = function (e) {
var arraybuffer = oReq.response;
// ...other code
callback(rawData); // <-- add this
}
// no need to return anything!
// return rawData;
}
window.onload = function()
{
getSheetData(function (data) {
const BenfordTable = calculateBenford(data);
printAsTable(BenfordTable);
printAsGraph(BenfordTable);
});
}
There are other things you could use to write such code, such as Promises, but that's probably something else to look into. We're also not doing any error handling here, which is also an important concept. The main takeaway here is that you are only handling the rawData once the call to the server has completed.

Javascript: load JSON dynamically (depending on number of files)

I want to load multiple .json files to an array, but I don't know the exact amount of files.
E.g.:
(in: .../example-folder)
abc.json
xyz.json
uvw.json
array.length == 3
(in .../example_folder)
abc.json
xyz.json
array.length == 2
How could I do that in javascript?
Thanks in advance!
Kind regards,
Soxxes
Edit:
Normally I am doing it this way:
function loadJSON(url, callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType('application/json');
xobj.open('GET', url, true);
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == '200') {
callback(xobj.responseText);
}
};
xobj.send(null);
}
loadJSON("../example_folder/abc.json", function(res){
data_parsed = JSON.parse(res);
data_stringified = JSON.stringify(data_parsed, null, 4);
abc = data_stringified;
});
You can create an API to return a number of JSON files or a list of them. If you don't want to create that API, just put expected response to a specific JSON file.
// api.json
{
"files": [ "abc.json", "xyz.json" ]
}

How to Load CSV to array with object names

I want to be able to store the the data in my CSV files so I can read it easier and serve it to a webpage.
The CSV is in the following format, probname1:"meat1", probename2:"meat2".......
If I paste the data in manual like https://www.w3schools.com/js/tryit.asp?filename=tryjs_array_object
it works,
I also tried setting up my array dirrentely and using MGot90's method from Read CSV headers using Javascript
But I can only ever call 1 full value of each object e.g settings[0], and not call the object by its name e.g settings["ProbeName1"]
I want the following to beable to output meat1 with the following in the CSV file.
updatevalues.csv = probname1:"meat1", probename2:"meat2"
loadData();
function loadData() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
parseCSV(this.responseText);
}
};
xmlhttp.open("GET", "js/updatevalues.csv", true);
xmlhttp.send();
}
function parseCSV(string) {
var allTextLines = string;
var settings = [];
var settings = allTextLines.split(",");
document.getElementById("demo1").innerHTML = settings["ProbeName1"];
}`
currently I can only get id=demo1 to output ProbeName1:"meat1" using settings[0].
If I use settings["ProbeName1"] it will display undefined.
This function will convert your csv into a JSON object:
function parseCSV(str) {
var allTextLines = str;
var settings = [];
var settings = allTextLines.split(",");
var results = {};
var name, val, idx;
for (var i = 0; i < settings.length; i++) {
idx = settings[i].indexOf(':');
name = settings[i].substring(0, idx);
val = settings[i].substring(idx+2, settings[i].length-1);
results[name] = val;
}
return results;
}
Working in fiddle: https://jsfiddle.net/p3t7Lv28/
That code strips the quotes off the values by using idx+2, length-1
Why you need that i dont know but may be you can use SheetJS tool.Its for showing the excel on the web.

How to extract single element line by line and store in an array in Javascript?

I've got a text file 'mytext.txt' with IPs and some text seperate by commas in different lines -
24.16.153.165:51413,abc
67.185.72.127:51413,xyz
69.247.183.46:63303,pqr
130.56.220.16:6881,def
I want to store the IPs in an array in JavaScript to plot them on a map. I found a way to do this by using a static array -
var map = new google.maps.Map(document.getElementById('map'), googleMap);
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(infowindow, "closeclick", function() {
map.fitBounds(latlngbound);
map.panToBounds(latlngbound)
})
var ipArray = ["70.177.167.189", "123.135.107.115", "123.135.107.115", "123.135.107.115", "123.135.107.115", "122.182.6.19", "24.19.187.145", "24.19.187.145", "27.251.20.130", "27.251.20.130"];
ipArray.forEach((ip) => {
addIPMarker(ip);
})
} catch(e){
//handle error
}
Can someone tell me how to do it after extracting the IPs from the text file? It should be a fairly simple logic, but I'm not very familiar with JavaScript. Thanks!
This function works if you have a file on the server or another url.
function loadDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = this.responseText;
var data = myObj.split(/\n/g);
var data_ip = [];
for(item in data)
{
var ip = data[item].split(/,/g);
data_ip.push(ip[0]);
}
console.log(data_ip);
}
};
xmlhttp.open("GET", "file.txt", true);
xmlhttp.send();
}
And this was work with a locally stored file.
function readTextFile(file)
{
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var myObj = rawFile.responseText;
var data = myObj.split(/\n/g);
var data_ip = [];
for(item in data)
{
var ip = data[item].split(/,/g);
data_ip.push(ip[0]);
}
console.log(data_ip);
}
}
}
rawFile.send(null);
}
readTextFile("file:///C:/your/path/to/file.txt");
To read a file in from your system you need to use the fs (file system) module provided by Node. You won't need to do any npm install.
JavaScript file:
const fs = require('fs');
const mapData = fs.readFileSync(//path to file here);
// do things with the data like your ip mapping, etc...
I have used the fs.readFileSync() function in the example but you will want to read the documentation and see what works best for your application.
Documentation:
https://nodejs.org/api/fs.html

AJAX, pass additional variable to callback and store XMLHTTLRequest.response to variable

I am trying to read a local file on the server with a standard function loadDoc(url, cfunc), then
1) search for a particular string in the file (getLine());
2) if possible, store that line to a variable.
For point 1 I pass a string to the callback.
2) Getting the response is problematic because XMLHTTPRequest is asynchronous. At this moment the error is:
"ReferenceError: xhttp is not defined"
function main(){
var url="data.txt"
var str="1,0,"; //just an example
var myCallBackWithVar = function(){
getLine(str);
};
loadDoc(url, myCallBackWithVar);
//Can I get the line here somehow?
}
function loadDoc(url, cfunc) {
var xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
cfunc(xhttp);
}
}
xhttp.overrideMimeType('text/plain');
xhttp.open("GET", url, true);
xhttp.send();
}
//Find string with the desired data in txt file
function getLine(str) {
var data=xhttp.responseText;
//Find the line from the txt file
var start=data.indexOf(str);
var end=data.indexOf(";",start);
var line=data.substring(start,end);
return line;
}
data.txt is something like this:
some data here
0,0,9;
1,0,10;
1,1,11;
I have already tried to pass the XMLHTTPRequest objetct getLine(xhttp,str). How to solve points 1 and 2? I'd rather keep it jQuery free for the moment. Thanks
Can I get the line here somehow?
I don't think that's a good idea. You can't be sure that your app will work correctly. XHR is a async function and you should use async architecture.
Here the example how this functionality can be done.
var text; // define global variable
var str = "1,0,"; //just an example
function main(){
var url = "data.txt";
var cb = function (data){
text = getLine(data);
// you can use text var here
// or in anyewhere in your code
}
loadDoc(url, cb);
}
function loadDoc(url, cb) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
cb(xhr.responseText);
}
}
xhr.overrideMimeType('text/plain');
xhr.open("GET", url, true);
xhr.send();
}
//Find string with the desired data in txt file
function getLine(data) {
if(data) {
//Find the line from the txt file
var start = data.indexOf(str);
var end = data.indexOf(";", start);
var line = data.substring(start, end);
return line;
}
}
On complete, you don't need to pass the whole xhttp variable through too the callback function. When you do this:
function getLine(str) {
var data=xhttp.responseText;
xhttp is already out of scope. To fix this, the parameter name would also have to be xhttp.
A better way would be to do :
cfunc(xhttp.responseText);
and then
var data=str
This way, you are passing only what you need as an argument.

Categories

Resources