Using Asynchronous callback from JS Code Block

While writing code inside the JS Code Block, you might have come across the need to run asynchronous code which returns some value and you want to return that value from the JS Code Block. This problem statement can be solved by enclosing the asynchronous code inside a Promise and returning that Promise from the JS Code Block.

This use case takes a look at various asynchronous code blocks that can be promisified and returned from the JS Code Block.

  1. Reading CSV file from URL using papaparse library
  2. Fetching data from Ajax Request asynchronously
  3. Reading Blob URL contents using Ajax and FileReader

Reading CSV file from URL using papaparse library

In this use case, the user will enter the CSV file url in the textfield and click on the button which will trigger the JS Code action responsible for converting the url data to json. The json value will then be set to the tablegrid control.


Upon the button’s click action, add a JS Code Block with the textfield as input parameter to the function, in our case the textfield’s name is fileurl and the input parameter’s name is url.



Code

output = new Promise(function(resolve, reject) {
    Papa.parse(url, {
        download: true,
        header: true,
        complete: function(response) {
            resolve(response.data);
        },
        error: function(err) {
            reject(err);
        }
    });
});

Now create a variable which will store the JS Code’s output, in our case it is csv_data.


Lastly, add a Set Controls Value block which will set the JS Code Block output to the tablegrid control.


Run the app, and you will see something like this.

Fetching data from Ajax Request asynchronously

For this use case, we have taken a JSON Viewer which will load up the API data when the screen opens.


On the screen’s open action, add a JS Code Block and write the code mentioned below. You can change the url passed in the open function.


Code

output = new Promise(function (resolve, reject) {
  const xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE) {
      if (xhr.status == 200) {
        resolve(xhr.responseText);
      }
      else {
        reject("Some error occurred!");
      }
    }
  }
  xhr.open("GET", "https://apigenerator.dronahq.com/api/T19L7LoL/data", true);
  xhr.send();
});

Now create a variable which will store the JS Code’s output, in our case it is api_data.


Lastly, add a Set Controls Value block which will set the JS Code Block output to the jsonviewer control.


Run the app, and you will see something like this.

Reading Blob URL contents using Ajax and FileReader

In this use case, the user will click on the file upload button and select one html file from his/her local system, and once the file is uploaded, JS Code action will be triggered which will convert the uploaded file’s blob url to text content. This text content will then be set onto the Rich Text Viewer Control.


On the fileupload’s value_select action, add a JS Code Block with the fileupload control as input parameter to the function.


Code

if(files.length < 1) output = "No file selected!";
else {
  output = new Promise(function(resolve, reject) {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', files[0], true);
  xhr.responseType = 'blob';
  xhr.onload = function(e) {
    if (this.status == 200) {
      try {
        const reader = new FileReader();
        reader.readAsDataURL(this.response); 
        reader.onloadend = function() {
          const base64data = reader.result.split(',')[1];
          resolve(atob(base64data));
        }
      }
      catch(error) {
        reject(error);
      }
    }
  }
  xhr.send();
  });
}

Now create a variable which will store the JS Code’s output, in our case it is html_data.


Lastly, add a Set Controls Value block which will set the JS Code Block output to the richtextviewer control.


Run the app, and you will see something like this.