Write javascript array elements to file - javascript

I am trying to have a node js script write some coordinates to a csv file for use in a Newman CLI script. I have the following:
const axios = require('axios');
var move_decimal = require('move-decimal-point');
var sLat = 45.029830;
var sLon = -93.400891;
var eLat = 45.069523;
var eLon = -94.286001;
var arrLatLon = []
axios.get('http://router.project-osrm.org/route/v1/driving/' + sLon + ',' + sLat + ';' + eLon + ',' + eLat + '?steps=true')
.then(function (response) {
for (let i = 0; i < response.data.routes[0].legs.length; i++) {
//console.log(response.data)
for (let ii = 0; ii < response.data.routes[0].legs[i].steps.length; ii++) {
//console.log('leg ' + i + " - step " + ii + ": " + response.data.routes[0].legs[i].steps[ii].maneuver.location[1] + "," + response.data.routes[0].legs[i].steps[ii].maneuver.location[0]);
// Declaring Latitude as 'n' & Longitude as 'nn' for decimal calculations
var n = response.data.routes[0].legs[i].steps[ii].maneuver.location[1]
var nn = response.data.routes[0].legs[i].steps[ii].maneuver.location[0]
// Latitude calculatiuons to make 'lat' values API friendly
var y = move_decimal(n, 6)
var p = Math.trunc(y);
// Longitude calculations to make 'lon' values API friendly
var yy = move_decimal(nn, 6)
var pp = Math.trunc(yy);
arrLatLon.push(p + "," + pp);
}
console.log(arrLatLon)
}
})
I have been looking through and trying numerous different tutorials/code snippets regarding writing the array elements from arrLatLon to an output file on my local machine, but none have been successful. The current code outputs the lat,lon correctly, console.log(arrLatLon) outputs:
[ '45029830,-93400894',
'44982812,-93400740',
'44977444,-93400530',
'44973116,-93410884',
'44971101,-93450400',
'45035514,-93766885',
'45035610,-93766886',
'45081631,-94286752',
'45070849,-94282026' ]
any help would be greatly appreciated. Thanks.

With nodejs you can easily write files using the fs module
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
in your case you can simply do something like
const fs = require('fs');
// I'm converting your array in a string on which every value is
// separated by a new line character
const output = arrLatLon.join("\n");
// write the output at /tmp/test
fs.writeFile("/tmp/test", output, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Let me forward you to this question for more information Writing files in Node.js

Related

Javascript for loop returning same value

I have this JS function using which I'm using to upload files from HTML multi-file uploader to dropbox using Javascript SDK. It's working well. Now I'm trying to add list of file names that are failed to upload(when catch block executes) to a string named "failed", but it's adding the name of the first file for all the failed files. What am I doing wrong here?
function uploadFile() {
var count1=0,count2=0,loop=0, failed='';
const UPLOAD_FILE_SIZE_LIMIT = 150 * 1024 * 1024;
var ACCESS_TOKEN = 'SomeAccessToken';
var dbx = new Dropbox.Dropbox({
accessToken: ACCESS_TOKEN
});
var fileInput = document.getElementById('file-upload');
var formp= document.getElementById('formp');
for (var i = 0; i < fileInput.files.length; i++) {
formp.innerHTML='<p> Uploading ' + fileInput.files.length + ' files </p>' ;
var file = fileInput.files[i];
var filename = fileInput.files[i].name;
if (file.size < UPLOAD_FILE_SIZE_LIMIT) { // File is smaller than 150 Mb - use filesUpload API
dbx.filesUpload({path: '/Test/' + file.name, contents: file})
.then(function(response) {
var results = document.getElementById('results');
var br = document.createElement("br");
results.appendChild(document.createTextNode(file.name + 'File uploaded!'));
results.appendChild(br);
count1=count1+1;
if(count1+count2==fileInput.files.length)
{
formp.innerHTML='<p> Uploaded ' + count1 + ' files. Failed ' + count2 + ' files</p>';
}
console.log(response);
})
.catch(function(error) {
count2=count2+1;
console.error(error);
failed+=file.name;
if(count1+count2==fileInput.files.length)
{
formp.innerHTML='<p> Uploaded ' + count1 + ' files. Failed '+ count2 + ' files</p>';
}
});
}
}
As far as I have seen, I dint find anything wrong in this code. For testing purpose I commented few lines of your code and tested. The files names are properly concatenated to the "failed" string.
<form>
<input type="file" id="formp" multiple="true" accept="*/*" />
</form>
<pre></pre>
$('#formp').change(function (event) {
var count1=0,count2=0,loop=0, failed='';
const UPLOAD_FILE_SIZE_LIMIT = 150 * 1024 * 1024;
var ACCESS_TOKEN = 'SomeAccessToken';
/* var dbx = new Dropbox.Dropbox({
accessToken: ACCESS_TOKEN
}); */
var fileInput = document.getElementById('formp');
var formp= document.getElementById('formp');
for (var i = 0; i < fileInput.files.length; i++) {
formp.innerHTML='<p> Uploading ' + fileInput.files.length + ' files </p>' ;
var file = fileInput.files[i];
var filename = fileInput.files[i].name;
failed+=file.name;
console.log('Failed check', failed);
if (file.size < UPLOAD_FILE_SIZE_LIMIT) { // File is smaller than 150 Mb - use filesUpload API
// dbx.filesUpload({path: '/Test/' + file.name, contents: file})
// .then(function(response) {
// var results = document.getElementById('results');
// var br = document.createElement("br");
// results.appendChild(document.createTextNode(file.name + 'File uploaded!'));
// results.appendChild(br);
// count1=count1+1;
// if(count1+count2==fileInput.files.length)
// {
// formp.innerHTML='<p> Uploaded ' + count1 + ' files. Failed ' + count2 + ' files</p>';
// }
// console.log(response);
// })
// .catch(function(error) {
// count2=count2+1;
// console.error(error);
// failed+=file.name;
// if(count1+count2==fileInput.files.length)
// {
// formp.innerHTML='<p> Uploaded ' + count1 + ' files. Failed '+ count2 + ' files</p>';
// }
// });
}
}
});
Try the above code in jsFiddle.
There might be a chance that the first file name might be cached in file variable and might be displaying the same variable name for each and every loop again and again. So emptying the "file" variable at the end of the each loop might fix the issue.

Sending message to Telegram from Google Sheet via Google Scripts

I'm trying to send a telegram message to myself, every morning, with a different quote that I have listed in a Google Sheet. I wrote some code that adds messages to the list, but I can't seem to generate a random row from the list to send daily.
var token = "TOKEN";
var telegramAPI = "https://api.telegram.org/bot" + token;
var webAppAPI = "https://script.google.com/macros/s/GOOGLE_WEB_APP_ADDRESS";
var ssId = "SPREADSHEET_ID";
function getMe() {
var url = telegramAPI + "/getMe";
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function setWebhook() {
var url = telegramAPI + "/setWebhook?url=" + webAppAPI;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function sendText(id,text) {
var url = telegramAPI + "/sendMessage?chat_id=" + id + "&text=" + text;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function doGet(e) {
return HtmlService.createHtmlOutput("Test Data" + JSON.stringify(e,null,4));
}
function doPost(e) {
Logger.log(e);
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var what = data.message.text.split("-")[0]
var who = data.message.text.split("-")[1]
var id = data.message.chat.id;
var name = data.message.chat.first_name;
var response = "Hi " + name + ", this quote has been added to your database: " + text;
sendText(id,response);
SpreadsheetApp.openById(ssId).getSheets()[1].appendRow([new Date(),id,name,text,response,what,who]);
All of this works fine. I added a query that pulls them over to my Quote sheet from my Telegram Feed sheet, that I'll put here to help someone:
=IFERROR(QUERY('Telegram Feed'!$G$1:$G$98,"",-1),"Error")
Now that I'm pulling in quotes, I want to generate a random one from the list and schedule it to send to myself on a daily basis. I've included what I've tried below, but I can't seem to figure out what I'm doing wrong.
The randomizer is partially working, but seems to be grabbing all of the content, which I need to refactor to say something along the lines of:
message = f"{quote} + ' - ' + {author}"
Randomizer:
function randomizer() {
var ssa = SpreadsheetApp.openById(ssId);
var ss = ssa.getSheetByName('Quotes');
var range = ss.getRange(1,1,ss.getLastRow(), 2);
var data = range.getValues();
for(var i = 0; i < data.length; i++)
{
var j = Math.floor(Math.random()*(data[i].length));
var element = data[i][j];
ss.getRange(i+1, 6).setValue(element);
Logger.log(element);
}
}
Up until this point, it mostly works (even though I need to figure out how to fix the randomizer function as mentioned above. It's when I try to send a random message from the script to Telegram that I run into problems.
function sendQuote(what,who) {
var data = randomizer();
var dataJSON = JSON.parse(data.postData.contents);
var url = telegramAPI + "/sendMessage?chat_id=" + 'CHAT_ID_NUM' + "&text=" + what + " - " who;
}
I'm getting nothing back. Anyone know what I'm doing wrong?
EDIT:
I followed the suggestions from Дмитро-Булах & carlesgg97, and I refactored a bunch of my randomize code to give me a quote and author. For some reason, I'm now getting the error "TypeError: Cannot read property "postData" from undefined.: from the line that reads var dataJSON = JSON.parse(data.postData.contents);
Does anyone know why this is happening?
I'll close the issue within 24hrs regardless. Thanks for the help everybody!
function sendQuote(quote,author) {
var data = randomize();
var dataJSON = JSON.parse(data.postData.contents);
var encodedText = encodeURIComponent(quote + " - " + author);
var url = telegramAPI + "/sendMessage?chat_id=" + 'CHAT_ID' + "&text=" + encodedText;
UrlFetchApp.fetch(url);
}
function randomize() {
var sss = SpreadsheetApp.openById(ssId);
var ss = sss.getSheetByName('Quotes');
var length = ss.getLastRow();
var overshoot = 97 //monitor for changes as list size increases
var true_length = length-overshoot;
var line = (Math.random() * ((true_length - 2) + 1)) + 2;
var quote_cell = ss.getRange(line,2);
var quote = quote_cell.getValue();
var author_cell = ss.getRange(line,1);
var author = author_cell.getValue();
Logger.log(quote + " - " + author);
}
Seems like you may be having two different problems:
You are not encoding the text as URL-safe. To safely append data (in this case the text URL Query string parameter) to your URL, you should use encodeURIComponent().
You don't seem to actually be sending the request. Did you miss the UrlFetchApp.fetch() call?
See below an example that fixes both issues:
function sendQuote(what,who) {
var data = randomizer();
var dataJSON = JSON.parse(data.postData.contents);
var encodedText = encodeURIComponent(what + " - " + who);
var url = telegramAPI + "/sendMessage?chat_id=" + 'CHAT_ID_NUM' + "&text=" + encodedText;
UrlFetchApp.fetch(url);
}

I need my code to get the values before the commas but it only grabs one of them - Javascript

I am fairly new to the Javascript language.
I am trying to make a clicker game (not so hard). The game is working but I am trying to make a save method for the game.
Instead of cookies I decided to have the game make its own code where the user can copy and paste it the next time they get on the game.
So the save method works but when I try to have the game load the code it doesn't quite do it right.
Instead of grabbing the values before the commas it grabs the letters of the word I use as a checker.
Is there a way I can fix this?
Here's my code:
var shovel = 0;
var miner = 0;
var loaders = 0;
var drill = 0;
var tnt = 0;
var minecart = 0;
var bulldozer = 0;
var trucks = 0;
var manager = 0;
var cost1 = 10;
var cost2 = 200;
var cost3 = 350;
var cost4 = 500;
var cost5 = 600;
var cost6 = 800;
var cost7 = 2500;
var cost8 = 6000;
var cost9 = 100000;
var cash = 0;
var cashRate = 1000;
//-- SAVE GAME --
function save() {
var save = "";
var data = cash + "," + cashRate + "," + shovel + "," + miner + "," + loaders + "," + drill + "," + tnt + "," + minecart + "," + bulldozer + "," + trucks + "," + manager + "," + cost1 + "," + cost2 + "," + cost3 + "," + cost4 + "," + cost5 + "," + cost6 + "," + cost7 + "," + cost8 + "," + cost9;
save += "CoalMinerGame=" + data;
var finalSave = encode(save);//Encoding/Decoding is done using the Base64 Code
prompt("Keep this somewhere you'll remember!", finalSave);
}
function load() {
var code = prompt("Paste the save code below!", "");
if (code != "") {
var load = decode(code);
if (load.includes("CoalMinerGame=")) {
load.split("CoalMinerGame=");
//load[0] = blank
cash = load[1];
cashRate = load[2];
shovel = load[3];
miner = load[4];
loaders = load[5];
drill = load[6];
tnt = load[7];
minecart = load[8];
bulldozer = load[9];
trucks = load[10];
manager = load[11];
cost1 = load[12];
cost2 = load[13];
cost3 = load[14];
cost4 = load[15];
cost5 = load[16];
cost6 = load[17];
cost7 = load[18];
cost8 = load[19];
cost9 = load[20];
updateWorkers();
alert("Save Successfully Loaded!");
} else {
alert("Not a valid save code!");
}
} else {
alert("You must enter a save code to get your game back!");
}
}
Save
Load
I see two mistakes :
The load.split() function does not modify load but returns an array instead, an array that you should store in another variable.
You should also split once again the resulting string on commas to separate your different values.
Hope it helps!
Oh man, this code is giving me a pain :).
What about use some native functions for whole objects so you dont have to manually serialize it and deserialize it?
This code
const myObject = {
some: 'fields',
even: {
nested: 'fields',
},
};
const stringified = JSON.stringify(myObject);
console.log(stringified);
const unstringified = JSON.parse(stringified);
console.log(unstringified);
Is having this output
{"some":"fields","even":{"nested":"fields"}}
{ some: 'fields', even: { nested: 'fields' } }
You can also use base64 steps to code and decode
The JSON.stringify take JS object and create pure string which contains JSON inside.
Then when you want to take JSON and create object from it, you can just JSON.Parse, which expects string.
I echo the sentiment to use JSON. My example below might require some refactoring in the game code but would be cleaner. To access the variable cash you would just use gameData.cash where you currently are using the cash var.
var gameData = {
cash: 0,
cashRate:0,
shovel:0,
miner:0,
loaders:0,
drill:0,
tnt:0,
minecart:0,
bulldozer:0,
trucks:0,
manager:0,
cost1:10,
cost2:200,
cost3:350,
cost4:500,
cost5:600,
cost6:800,
cost7:2500,
cost8:6000,
cost9:100000
}
function save(){
var dataToSave = CoalMinerGame: {
cash: cash,
cashRate:cashRate,
shovel:shovel,
miner:miner,
loaders:loaders,
drill:drill,
tnt:tnt,
minecart:minecart,
bulldozer:bulldozer,
trucks:trucks,
manager:manager,
cost1:cost1,
cost2:cost2,
cost3:cost3,
cost4:cost4,
cost5:cost5,
cost6:cost6,
cost7:cost7,
cost8:cost8,
cost9:cost9
}
var finalSave = JSON.Stringify(dataToSave)
finalSave = encode(finalSave)
prompt("Keep this somwhere you'll remember!", finalSave)
}
function load(){
var code = prompt("Paste the save code below!", "")
var load = decode(code)
if (code != ""){
gameData = load;
updateWorkers();
alert("Save Successfully loaded!")
} else {
alert("You must enter a save code to get your game back!")
}
}

Export array of objects into Excel using Javascript

I'm writing a client side method, that creates an array of objects.I open an existing excel to write the values from the array. I get the values using getProperty and store in a variable.
When I try to write those in the excel, I get "event handler failed with message";" ".
Code:
var getItemtoExcel = document.thisItem.newItem("ToExcel", "get");
getItemtoExcel = getItemtoExcel.apply();
var arrToExcel = Array();
for (var j = 0; j < getItemtoExcel.getItemCount(); j++) {
var gotItemForExcel = getItemtoExcel.getItemByIndex(j);
arrToExcel.push(gotItemForExcel);
}
var Excel = new ActiveXObject("Excel.Application");
Excel.Visible = true;
Excel.Workbooks.Open("C:\\test.xls");
var offset = 0;
var row = 2;
for (var c = 0; c < arrToExcel.length; c++) {
var createExcel = arrToExcel[c];
var Number = createExcel.getProperty("nb");
var Type = createExcel.getProperty("type");
var Code = createExcel.getProperty("code");
var State = createExcel.getProperty("state");
Excel.Worksheets("sheet11").Range("A" & row + 1 + offset).Value = Number;
Excel.Worksheets("sheet11").Range("B" & row + 1 + offset).Value = Type;
Excel.Worksheets("sheet11").Range("C" & row + 1 + offset).Value = Code;
Excel.Worksheets("sheet11").Range("D" & row + 1 + offset).Value = State;
row = row + 1;
}
offset = offset + 1;
return this;
document.thisItem.newItem() is from ARASPLM. Its the standard used to call an ItemType(Item) in ARAS
If you have an opportunity to use SheetJS, it's pretty straightforward
Firstly, Install xlsx package npm install --save xlsx
const XLSX = require('xlsx')
// array of objects to save in Excel
let binary_univers = [{'name': 'Hi','value':1},{'name':'Bye','value':0}]
let binaryWS = XLSX.utils.json_to_sheet(binary_univers);
// Create a new Workbook
var wb = XLSX.utils.book_new()
// Name your sheet
XLSX.utils.book_append_sheet(wb, binaryWS, 'Binary values')
// export your excel
XLSX.writeFile(wb, 'Binaire.xlsx');
i think using this you can get what you want but you need to pass the your Object's value with this that i have mentioned here as (Your Data(Object))
window.open('data:application/vnd.ms-excel,' + **(Your Data(Object))**);
here i'm providing simple code for get data into excel format with jquery
SAMPLE DEMO
Thanks for all your suggestions on this question.
I have done with exporting the array into a .csv file successfully.
Here's the code, for others who will need.
var getItemtoExcel=this.newItem("MyForm", "get");
getItemtoExcel=getItemtoExcel.apply();
var arrToExcel = Array();
for (var j=0; j<getItemtoExcel.getItemCount(); j++)
{
var gotItemForExcel=getItemtoExcel.getItemByIndex(j);
arrToExcel.push(gotItemForExcel);
}
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("C:\\REPORT.csv", true);
var title="Report";
s.WriteLine(title);
var header="Number" + ";" + "Type" + ";" + "Code" + ";" + "Created On" + ";" + "State" + '\n' ;
s.WriteLine(header);
for (var c=0; c<arrToExcel.length; c++){
var createExcel = arrToExcel[c];
var Number =createExcel.getProperty("nb");
var Type=createExcel.getProperty("type");
if(Type===undefined){Type="";}
var Code=createExcel.getProperty("code");
if(Code===undefined){Code="";}
var Date=createExcel.getProperty("created_on");
var State=createExcel.getProperty("created_by_id/#keyed_name");
var value=Number + ";" + Type + ";" + Code + ";" + Date + ";" + State;
s.WriteLine(value);
}
s.Close();
alert("Report Saved as C:\\REPORT.csv");
return this;

accessing a specific column in a csv file using javascript

My problem is simple. I would like to know if there is a way to access a specific column from a csv file which is in MS Excel format. There are about 40 fields or columns in the file. I want to access only 3 of these. Please guide me.
Thanks in advance
This is as far as I got. Can we count the number of columns in the file?
$(document).on("click","#bucket_list a",function(evt){
// console.log("ID :: ",evt.target.id);
var bucketID = evt.target.id;
evt.preventDefault();
// alert("Event Fired");
counter = 0;
//lists the bucket objects
s3Client.listObjects(params = {Bucket: bucketID}, function(err, data){
if (err) {
document.getElementById('status').innerHTML = 'Could not load objects from ' + bucketID;
} else {
//document.getElementById('status').innerHTML = 'Loaded ' + data.Contents.length + ' items from ' + bucketID;
var listStart = document.createElement("ul");
document.getElementById('status').appendChild(listStart);
for(var i=0; i<data.Contents.length;i++){
fileKey = data.Contents[i].Key;
if(fileKey.search(str) != -1) {
//var listItems = document.createElement("li");
//listItems.innerHTML = data.Contents[i].Key;
//listStart.appendChild(listItems);
fileList[i] = data.Contents[i].Key;
//alert(fileList[i]);
counter = counter + 1;
}
}
if(counter == 0){
alert("This bucket has no CSV files. Please try another bucket!");
}
// else{
// for(var i = 0; i<fileList.length;i++){
// alert("File: " + fileList[i]);
// }
// }
}
//to read the contents of the files into textviews
var file = fileList[0];
//console.log("Loading:: ", file);
s3Client.getObject(params={Bucket: bucketID, Key: file},function(err,data){
if(err != null){ alert("Failed to load object " + err); }
else{
//alert("Loaded " + data.ContentLength + " bytes");
var allDataLines = data.split(/\r\n|\n/);
var headers = allDataLines[0].split(',');
}
});
});
});
I am unable to figure out how to get only the second column.
Yes. You have to parse the csv file to get the values for a particular column.Refer the following post on how to read a CSV file in Javascript.
[How to read data From *.CSV file using javascript?
To give you a head start the logic is simple . You just have to split based on "," and do a if statement.

Categories

Resources