Concatenate results of multiple API calls - Javascript - javascript

My apologies as I am very new to javascript and inexperienced so my code is very rudimentary, and I'll do the best I can at explaining myself.
I'm making a call to an API to get a blob which I then convert to base64. I can then pass this base64 string to a seperate script within the .map array - so this makes multiple calls to my script. But what I want to do is to concatenate the base64 strings into one string and pass a single call the my script.
I understand that this is asynchronous and I probably need some callbacks but im unsure how to do this in my case. Essentially I would like to make the 'base64data_1' variable within the reader.onloadend function available outside of the .map array, but the reader.onloadend function is the last action performed.
function getPhoto() {
const root = 'https://public-api.konectech.com/PROD/api/';
var acc = document.getElementById("accID").value;
var photoId1 = document.getElementById("photoID1").value;
var photoId2 = document.getElementById("photoID2").value;
var photoId3 = document.getElementById("photoID3").value;
var root1 = (root + acc + "/attachment/id/overlay/")
let uri = [root1 + photoId1,root1 + photoId2,root1 + photoId3];
let filenames = [photoId1,photoId2,photoId3];
var base64Array = [];
let base64 = uri.map (function (url) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader("accept", "image/jpg");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("x-api-key", "xxxxxxxx");
xhr.responseType = "blob";
xhr.send();
xhr.onload = function (data, filename, mime) {
var filename = (url.slice(url.lastIndexOf('/') + 1) );
const blob = new Blob([this.response], {type: mime || 'application/octet-stream'});
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
const base64data_1 = (base64data.slice(base64data.lastIndexOf(',') + 1) );
//console.log([base64data_1]);
base64Array = base64data_1;
console.log([base64Array]);
return [base64Array];
};
}
});
//console.log([base64Array]);
}
I was hoping that if i could get access pass the 'base64data_1' variable as an array I could then use promise.all and .join get the desired result similar to below:
function getPhoto() {
var array =['test_1','test_2','test_3','test_4','test_5'];
var items = [];
let newArray = array.map (function (array_1) {
items = array_1 + '_appended';
console.log(items);
return [items];
})
console.log(newArray);
Promise.all(newArray)
.then( function (arrayOfValues) {
console.log(arrayOfValues.join(",")); // returns test_1_appended,test_2_appended,test_3_appended,test_4_appended,test_5_appended
})
}

Related

How fetch data from Django REST in JavaScript

Im totaly new in Javascript so help me figure out
I have simple Rest with data:
[
{
"id": 1,
"content": "Hello Tweet"
}
]
Im trying to get this info in my <script>
<script>
const tweetsElement = document.getElementById('tweets')
const xhr = new XMLHttpRequest();
const method = 'GET'
const url = '/tweets'
const responseType ='json'
xhr.responseType = responseType
xhr.open(method,url)
xhr.onload = function(){
const serverResponse = xhr.response
const listedItems = serverResponse.response
console.log(listedItems)
var finalTweetStr = ""
var i;
for(i=0;i<listedItems.length;i++){
console.log(i)
console.log(listedItems[i])
var currentItem = "<div class='mb-4'><h1>"+listedItems[i].id + "</h1>"+"<p>"+ listedItems[i].content+"</p></div>"
finalTweetStr += currentItem
}
tweetsElement.innerHTML = finalTweetStr;
}
xhr.send();
</script>
But it doesnt work , where is the problem?
Your main issue appears to be here:
const serverResponse = xhr.response
const listedItems = serverResponse.response
Change it to:
const listedItems = xhr.response
and you can remove the redundant serverResponse variable.

How to perform sha256 hash using sjcl.hash.sha256.hash on a file content?

I am trying to perform SHA256 hash on a file content using javascript.
I get the file using the following function
var fileReader = new FileReader();
var fileByteArray = [];
fileReader.onload = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
fileHash = generateHashOfFileContent(array);
console.log('fileHash1: ' + fileHash);
}
}
fileReader.readAsArrayBuffer(this.files[0]);
And the hash function is
function generateHashOfFileContent(fileData){
var bitArray = sjcl.hash.sha256.hash(fileData);
var digest_sha256 = sjcl.codec.hex.fromBits(bitArray);
console.log("Sha256 "+digest_sha256);
return digest_sha256;
}
But it produce wrong hash data when I select a binary file
I can only produce actual hash using a text file and change the fileReader.readAsArrayBuffer(this.files[0]); -------> fileReader.readAsText(this.files[0]);
Can someone help me to figure out the problem
You should convert your TypedArray to bitArray:
var fileReader = new FileReader();
var fileByteArray = [];
fileReader.onload = function(evt) {
if (evt.target.readyState == FileReader.DONE) {
var arrayBuffer = evt.target.result,
array = new Uint8Array(arrayBuffer);
let bitArray = sjcl.codec.bytes.toBits(array)
fileHash = generateHashOfFileContent(bitArray);
console.log('fileHash1: ' + fileHash);
}
}
fileReader.readAsArrayBuffer(this.files[0]);
See https://github.com/bitwiseshiftleft/sjcl/wiki/Codecs

How to write a callback for FileReader?

I'm trying to upload multiple attachments.
First I'm getting attachments from user interface, then I'm converting them into JSON , then I need to make a server call.
In this I'm using FileReader.
//showing ajax loader
component.set("v.showLoadingSpinner", true);
//getting attached files
var files = component.find("fileId").get("v.files");
var details = {}; //JS Object need to send server
details.files = [];
for (var i = 0; i < files.length; i++)
{
(function(file) {
var name = file.name;
var reader = new FileReader();
reader.fName = files[i]['name'];
reader.fType = files[i]['type'];
reader.i = i;
reader.onload = function(e) {
var fileContents = reader.result;
var base64 = 'base64,';
var dataStart = fileContents.indexOf(base64) + base64.length;
fileContents = fileContents.substring(dataStart);
var startPosition = 0;
var endPosition = Math.min(fileContents.length, startPosition + 750000);
var getchunk = fileContents.substring(startPosition, endPosition);
var fDetails = {};
fDetails.fileName = reader.fName;
fDetails.base64Data = encodeURIComponent(getchunk);
fDetails.contentType = reader.fType;
details.files.push(fDetails);
}
reader.readAsDataURL(file);
})(files[i]);
// I want to make a server call here with data in "details" object.
console.log(details);
But I'm not getting data in above console log.
Please help me to achieve this.
You can use promises :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://davidwalsh.name/promises
https://developers.google.com/web/fundamentals/primers/promises
Also jQuery provide $.when() function :
https://api.jquery.com/jquery.when/
And with promisejs you can do something like this :
function readJSON(filename){
return new Promise(function (fulfill, reject){
readFile(filename, 'utf8').done(function (res){
try {
fulfill(JSON.parse(res));
} catch (ex) {
reject(ex);
}
}, reject);
});
}

Protractor - How do I pass a string value from a previous function to an async script?

The issue I'm having is that I have a dynamic API call whose url changes everytime. So In order to get the proper URL I have to get the text on the page and parse it so it only the first part of the text, then concatenate that to the first part of the URL. When I try to pass the string to the async script it keeps coming up as undefined. How can I get the string into the async script?
Specifically get the string to this line of code:
xhr.open("GET", APIcall, true);
var ID = element(by.css(".sometext")).getText().then(function(getFirstPartOfText) {
//console.log(ID);
var thing = getFirstPartOfText
var thing2 = getFirstPartOfText.toString().split(" ");
var thing3 = thing2[0];
var API = "https://someAPIcall/read/";
APIcall = API + thing3;
return APIcall;
}).then(function(APIcall){
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send('');
}).then(function(str) {
console.log(str);
//var whatINeed = JSON.parse(str);
var ID = element(by.css(".sometext")).getText().then(function(getFirstPartOfText) {
// this is synchronous, so there's no need to chain it using .then()
var thing = getFirstPartOfText
var thing2 = getFirstPartOfText.toString().split(" ");
var thing3 = thing2[0];
var API = "https://someAPIcall/read/";
APIcall = API + thing3;
return APIcall;
});
call_something(ID); // ID should be set at this point.
function call_something (APIcall) {
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send('');
}).then(function(str) {
console.log(str);
}
}
There are multiple things going on here, first of all the callback in call_something is not required, you are still within webdriver's promise manager. So all you need to do is return the data for the next call chain. Also quote in xhr.send(''); inside the method are not required. All you need to do is call send() and JSON parse the response and return, the next then block should have the JSON result. If you are getting pure HTML, then make sure the URL is correct.
function call_something (APIcall) {
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
return JSON.parse(xhr.responseText);
}
};
xhr.send();
}).then(function(str) {
console.log(str);
}
}
I was missing an extra parameter mentioned here
The first argument is a function which will be called
The second+ arguments will be passed as arguments to the function in the first argument.
var ID = element(by.css(".sometext")).getText().then(function(getFirstPartOfText) {
//console.log(ID);
var thing = getFirstPartOfText
var thing2 = getFirstPartOfText.toString().split(" ");
var thing3 = thing2[0];
var API = "https://someAPIcall/read/";
APIcall = API + thing3;
return APIcall;
}).then(function(APIcall){
console.log(APIcall);
browser.executeAsyncScript(function(ApiCall) {
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open("GET", APIcall, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send('');
}, APIcall).then(function(str) {
console.log(str);
//var whatINeed = JSON.parse(str);

How to read excel file in angularjs?

I have tried to read excel file to follow the following tutorial.
http://code.psjinx.com/xlsx.js/
But I have failed to read excel file for undefine situation in the following highlighted line.... I have tried it in IE11.
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {
type: 'binary'
});
obj.sheets = XLSXReader.utils.parseWorkbook(workbook, readCells, toJSON);
handler(obj);
}
**reader.readAsBinaryString(file)**;
The following answer describe, if you are going to load xlsx file from server. For uploading there is another code.
OPTION 1: This is a procedure, which works in Alasql library:
See files: 15utility.js and 84from.js for example
readBinaryFile(filename,true,function(a){
var workbook = X.read(data,{type:'binary'});
// do what you need with parsed xlsx
});
// Read Binary reading procedure
// path - path to the file
// asy - true - async / false - sync
var readBinaryFile = utils.loadBinaryFile = function(path, asy, success, error) {
if(typeof exports == 'object') {
// For Node.js
var fs = require('fs');
var data = fs.readFileSync(path);
var arr = new Array();
for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
success(arr.join(""));
} else {
// For browser
var xhr = new XMLHttpRequest();
xhr.open("GET", path, asy); // Async
xhr.responseType = "arraybuffer";
xhr.onload = function() {
var data = new Uint8Array(xhr.response);
var arr = new Array();
for(var i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
success(arr.join(""));
};
xhr.send();
};
};
OPTION 2: you can use Alasql library itself, which, probably, can be easier option.
alasql('SELECT * FROM XLSX("myfile.xlsx",{headers:true,sheetid:"Sheet2",range:"A1:D100"})',
[],function(data) {
console.log(res);
});
See the example here (simple Excel reading demo) or here (d3.js demo from Excel).

Categories