Condensing repetitive code with google scripts - javascript

Pretty new to all this but have a simple script to pull API info and put into google sheets. I want to pull the top 20 coins but I'm unsure of how to do it as a ??'function'?? to limit the amount of code required presently especially since only 'XXX' is basically changing. Thanks in advance
var urlBTC='https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1d&limit=2';
var responseBTC = UrlFetchApp.fetch(urlBTC,{'muteHttpExceptions': true});
var jsonBTC = responseBTC.getContentText();
var parseBTC = JSON.parse(jsonBTC);
sheetBTC.getRange(3,3).setValue(parseBTC[0][6]);
var sheetETH = sh.getSheetByName("ETH");
var urlETH='https://api.binance.com/api/v3/klines?symbol=ETHUSDT&interval=1d&limit=2';
var responseETH = UrlFetchApp.fetch(urlETH,{'muteHttpExceptions': true});
var jsonETH = responseETH.getContentText();
var parseETH = JSON.parse(jsonETH);
sheetETH.getRange(3,3).setValue(parseETH[0][6]);
}```

var coins = ['ETHUSDT','BTCUSDT']
function getCoin(){
coins.forEach(coin => {
let url = 'https://api.binance.com/api/v3/klines?symbol='+ coin
+ '&interval=1d&limit=2'
//do the other stuff
})
}
Hope this helps set you off in the right direction.
Basically we store the symbols as an array loop through and create a url for that, in the 'do something' put in your other code for handling the req. watch out for rate limits

Related

Translate Button on website - Saving the users language preference

So with my limited JavaScript skills I have created a simple translate button. When you click the button it changes the text on the webpage you are on to either English or Chinese.
How would I go about making these changes stay when someone goes to different webpages or even refreshes the page? I have tried experimenting with the localStorage technique but to no luck.
Here is my JS code for the translate button:
// onclick behavior
$('.lang').click('touchstart', function() {
var lang = $(this).attr('id'); // obtain language id
// translate all translatable elements
$('.tr').each(function(i) {
$(this).text(aLangKeys[lang][$(this).attr('key')]);
});
});
// preparing language file
var aLangKeys = new Array();
aLangKeys['en'] = new Array();
aLangKeys['ch'] = new Array();
aLangKeys['en']['home'] = 'Home';
aLangKeys['en']['about'] = 'About Us';
aLangKeys['en']['serv'] = 'Services';
aLangKeys['en']['sem'] = 'Search Engine Marketing';
aLangKeys['en']['webdev'] = 'Website Development';
aLangKeys['ch']['home'] = '首页';
aLangKeys['ch']['about'] = '关于我们';
aLangKeys['ch']['serv'] = '服务';
aLangKeys['ch']['sem'] = '谷歌与雅虎推广';
For local storage I have added in this right under the var = aLangKeys = new array.
localStorage.setItem("aLangKeys", aLangKeys);
var someVarName = localStorage.getItem("aLangKeys");
Thanks!
LocalStorage only allows storing strings so you need to use JSON.stringify() and JSON.parse() when getting and setting.
But first you shouldn't be using new Array() for non numeric keys. What you are really doing is making an array like object when you do that
Change to:
var aLangKeys = {
en :{},
ch: {}
};
// .... other definitions
To set
localStorage.setItem("aLangKeys", JSON.stringify(aLangKeys));
To get
var someVarName = JSON.parse(localStorage.getItem("aLangKeys"));

Printing PDF in NetSuite with selection of Multiple Transaction Records

Is there a way to have a selection of many transactions printed into a single PDF document? I only see two options which seem to have significant drawbacks:
1) Load individual records into each of their own nlobjTemplateRenderer objects, and then stitch them all together within tags before rendering to PDF. Has a limit of less than 50 transactions depending on other actions taken when used within a Suitelet.
2) Do a search based upon internals IDs of selected records and pass the search results into a nlobjTemplateRenderer object. This method, based upon existing documentation, does not lead me to believe that it will properly display records with line data as result columns completely within a single document.
It almost seems like my best option is #1, but to split the desired transaction up into groups of 5-10 records and repeatedly calling a Suitelet with the small groups in the hopes of meeting the 45-second timeout limit of nlapiRequestURL before stitching together all of the results and returning the final PDF document. I pretty much see a basic form of that as the following:
// initial called function that will return completed PDF document file
function buildPdfFromRecords() {
var pdfBuilder = [];
var selectedIDs = [];
var chunks = chunkify(selectedIDs, 10);
for (var c = 0; c < chunks.length; c++) {
var param = { id_list : JSON.stringify(chunks[s]) };
var result = nlapiRequestURL(url, param).getBody();
pdfBuilder.push(result);
}
var finalXML = "<pdfset>" + pdfBuilder.join("") + "</pdfset>";
var pdfDoc = nlapiXMLToPDF(finalXML);
}
// function in suitelet called by url to handle individual groups of record internal IDs
// to mitigate scripting governance limits
function handleRecordIdListRequest(request, reponse) {
var idList = JSON.parse(request.getParameter("id_list"));
var templateXML = nlapiLoadRecord("template.txt").getValue();
var pdfBuilder = [];
for (var i = 0; i < idList.length; i++) {
var transRecord = nlapiLoadRecord("recordtype", idList[i]);
var renderer = nlapiCreateTemplateRenderer();
renderer.setTemplate(templateXML);
renderer.addRecord("record", transRecord);
pdfBuilder.push(renderer.renderToString());
}
response.write(pdfBuilder.join(""));
}
If this is really the best way, then so be it, but I'm hoping there's a more elegant solution out there that I'm just not seeing.
There are a number of pieces you can stitch together to get this done.
In the post handler of your Suitelet use the N/task library to schedule a map/reduce task. The task.submit method returns a taskId that you can use to monitor the progress of your job. Once your UI has a taskId it can periodically check to see if the task has completed. When complete you can show the generated .pdf. You could also let the user know that the pdf might take a few minutes to generate and offer to email it to them when done. Here's a snippet that schedules a scheduled script with parameters:
const mrTask = task.create({
taskType:task.TaskType.SCHEDULED_SCRIPT,
scriptId:'customscript_knsi_batch_products',
deploymentId: deploymentId,
params: {
custscript_knsi_batch_operator:user.id,
custscript_knsi_batch_sourcing: sourcingId
}
});
try{
const taskId = mrTask.submit();
context.response.setHeader({name:'content-type', value:'application/json'});
context.response.write(JSON.stringify({
success:true,
message:'queued as task: '+ taskId
}));
}catch(e){
log.error({
title:'triggering '+ sourcingId +' for '+ user.email,
details:(e.message || e.toString()) + (e.getStackTrace ? (' \n \n' + e.getStackTrace().join(' \n')) : '')
});
context.response.setHeader({name:'content-type', value:'application/json'});
context.response.write(JSON.stringify({
success:false,
message:'An error occured scheduling this script\n'+e.message
}));
Use a Map/Reduce script where your map method generates and returns each transaction's pdf file url. You'll only have a single key so that the results of all map stages coalesce into a single reduce.
In the reduce step you can generate open and close pdf files as necessary and put their references into your mapped array of pdfs.
Use the pdfset to bind all your individual pdfs into a single pdf:
function renderSet(opts){
var tpl = ['<?xml version="1.0"?>','<pdfset>'];
opts.files.forEach(function(id, idx){
const partFile = file.load({id:id});
var pdf_fileURL = xml.escape({xmlText:partFile.url});
tpl.push("<pdf src='" + pdf_fileURL + "'/>");
});
tpl.push("</pdfset>");
log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('\n')})});
return render.xmlToPdf({
xmlString: tpl.join('\n')
});
}
Why not use a Map Reduce script to generate the PDF? Does it need to be a Suitelet?

How to get periodId on DashMetrics

In dash.js there is a function getBandwidthForRepresentation() on file DashMetrics.js. It needs two parameters: representationId and periodId. I can use getCurrentRepresentationSwitch() to get representationId. But i don't know how to get periodId? With which function can i get the data?
I tried to see example on dash-reference-client, it is confusing and still have no idea.
Thanks
I know your question is kind of old and you are probably not needing this anymore, but I'll send some code in case someone needs it eventually.
As you stated, getBandwidthForRepresentation() expects 2 parameters: representationId and periodId
How to get representationId:
you need to get metrics: var metrics = player.getMetricsFor('video')
and dashMetrics: var dashMetrics = player.getDashMetrics()
now we get representationId: var representationId = dashMetrics.getCurrentRepresentationSwitch(metrics).to
How to get peropdId:
we get the active stream info: var streamInfo = player.getActiveStream().getStreamInfo()
we use index as periodId: var periodId = streamInfo.index
How to get bandwidth:
we can now get bandwidth: var bandwidth = dashMetrics.getBandwidthForRepresentation(representationId, periodId)
Full Code:
var metrics = player.getMetricsFor('video')
var dashMetrics = player.getDashMetrics()
var representationId = dashMetrics.getCurrentRepresentationSwitch(metrics).to
var streamInfo = player.getActiveStream().getStreamInfo()
var periodId = streamInfo.index
var bandwidth = dashMetrics.getBandwidthForRepresentation(representationId, periodId)
Hope it helps

JSON Data to Javascript Array Undefined

I am trying to get data from a JSON file and use Javascript Code to put it into Google Spreadsheet, I did good with some part of the data but I'm stuck with the other part, where I want to match the User Id and put all the data with it on a same row,
JSON Data:
"m":{"414":{"a":{"0":{"c":38,"p":12812.4},
"4":{"c":35,"p":10559.94},"2":{"c":43,"p":35811.63},
"6":{"c":48,"p":45530}},"d":{"0":{"c":55,"p":5477.06225},
"4":{"c":694,"p":106649.473},"2":{"c":1844,"p":716733.50775000011},
"6":{"c":605,"p":324152.5875}},"i":{"0":{"c":0,"p":0},
"4":{"c":0,"p":0},"2":{"c":0,"p":0},"6":{"c":542,"p":19893.93}}},
"404":{"a":{"0":{"c":15,"p":916.182},"4":{"c":50,"p":12357},
"2":{"c":530,"p":390825.27},"6":{"c":58,"p":4841.55}},
"d":{"0":{"c":10,"p":3145.8},"4":{"c":770,"p":141876.12},
"2":{"c":4854,"p":2173966.6125000003},
"6":{"c":1973,"p":1145077.425}},"i":{"0":{"c":0,"p":0},
"4":{"c":0,"p":0},"2":{"c":0,"p":0},"6":{"c":594,"p":25444.41}}}},
Javascript:
var testUF = [];
var Uid = Object.getOwnPropertyNames(doc1.m);
for (var lp2 = 0; lp2 < Uid.length; lp2++) {
var Ua1 = doc1.m[lp2].a["0"].p;
var Ua2 = doc1.m[lp2].a["4"].p;
var Ua3 = doc1.m[lp2].a["2"].p;
var Ua4 = doc1.m[lp2].a["6"].p;
var Ud1 = doc1.m[lp2].d["0"].p;
var Ud2 = doc1.m[lp2].d["4"].p;
var Ud3 = doc1.m[lp2].d["2"].p;
var Ud4 = doc1.m[lp2].d["6"].p;
var Ui4 = doc1.m[lp2].i["6"].p;
testUF.push([Uid,Ua1,Ua2,Ua3,Ua4,Ud1,Ud2,Ud3,Ud4,Ui4]);}
I am getting the Array on the Uid while Debugging, but all the other Variables don't get the data it stays Undefined. I want all the other variables to match with the Uid's and stay in the same row. I did the JSON parsing and everything.
I am asking for the first time on stackoverflow, please forgive me if I couldn't state everything properly. Thank you for the help. :)
You're not using the array index for Uid properly.
Change:
var Ua1 = doc1.m[lp2].a["0"].p;
To:
var Ua1 = doc1.m[Uid[lp2]].a["0"].p;

Google Script: Format URL in Array.Push

I have a working script that upon form submit, specific rows move from one sheet to another. One of the fields I'm pushing is a url.
On the second sheet, the link is listed and it is hyperlinked, but it's really ugly and I really want to format it so that it shows "Edit" with a hyperlink. I've tried a number of ways, but my knowledge is limited so all I get are errors. I'm hoping someone can point me in the right direction.
Here is my code. I'm very new at this so the script is not at all sophisticated. Any help/suggestions would be appreciated!
function copyAdHoc(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Form Responses 1"));
var data = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
// Grab the Headers from master sheet
var headers = sh.getRange(1,1,1,sh.getLastColumn()).getValues();
var date = headers[0].indexOf('Effective Date');
var name = headers[0].indexOf('Employee Name');
var loc = headers[0].indexOf('Location');
var issue = headers[0].indexOf('Description/Question/Issue');
var add = headers[0].indexOf('Additional Information');
var change = headers[0].indexOf('Is this a Qualifying Life Event?');
var url = headers[0].indexOf('Form URL');
var category = headers[0].indexOf('Primary Category');
var status = headers[0].indexOf('Current Status');
var users = headers[0].indexOf('Users');
// Grab only the relevant columns
for(n = 0; n < data.length; ++n ) { // iterate in the array, row by row
if (data[n][change] !== "Yes" & data[n][category] !== "Employee Relations" & data[n][date] !== "") { // if condition is true copy the whole row to target
var arr = [];
arr.push(data[n][url]);
arr.push(data[n][users]);
arr.push(data[n][date]);
arr.push(data[n][loc]);
arr.push(data[n][name]);
arr.push(data[n][category]);
arr.push(data[n][issue] + ". " + data[n][add]);
arr.push(data[n][status]);
var sh2 = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Ad Hoc")); //second sheet of your spreadsheet
sh2.getRange(sh2.getLastRow()+1,2,1,arr.length).setValues([arr]); // paste the selected values in the 2cond sheet in one batch write
}
}
}
It's a bit messy but the only way I know to achieve what you're trying to do would be to insert a column to the left of the hyperlink with the word Edit right justified and then remove the borders between the two.
From your description I am assuming you want the word "Edit" to be Hyperlinked. To do so, try this:
function getHyperlink(url)
{
return "=HYPERLINK(\""+url+"\","+"\"Edit\""+")";
}
function mainFunct()
{
//Do necessary steps
var tarLink = "https://www.google.com";
var tarRng = tarSheet.getRange(rowNum, colNum).setValue(getHyperlink(tarLink));
//perform other steps
}
EDIT:
Forgot to mention, since you're pushing your values to the array... you can do it in a similar way by either just storing the hyperlink in a variable or directly pushing it to the array like all the other values. Or if you're dealing with a hyperlink that has a static and dynamic part, For example: https://stackoverflow.com/questions/post_id, where post_id keeps changing but most of the URL is static, you can easily handle it by just passing the post_id to the getHyperlink function and getting the required Hyperlink in return. Hope this helps.

Categories