DB Write-Back Part 2: Tableau Debug Mode & Debugger Command Line

Debugging is an essential part of writing any program. Tableau Desktop has a debug mode to enable us to understand what is happening with our extension code. To debug a Tableau extension, the first step is to start Tableau Desktop (first close it if you still have it open from Part 1) in debug mode. It is practical to create a desktop shortcut with this target (if you are using Windows):

“C:\Program Files\Tableau\Tableau 2019.2\bin\tableau.exe” –remote-debugging-port=8696

Obviously, you should replace my path with the path to your current version of Tableau desktop. You can also replace the port (8696) with any other unused port number on your machine.

Now, use your new shortcut to open Tableau Desktop in debug mode. Open the Superstore sample and the overview dashboard again, then open the extension from part 1. Now, open Chrome (or Chromium if you’re not yet using at least Tableau 2019.1, details here) and browse to http://localhost:8696.

Click on the inspectable page you see to start the debugger. Click into the “Console” tab. Any errors that have been raised from your extension will show up here. This console is also interactive. Type

console.log(“Hi!”)

… and the debugger will respond with an enthusiastic greeting. Now let’s try to explore the tableau API. To get a list of the worksheets in this dashboard, type:

tableau.extensions.dashboardContent.dashboard.worksheets

… and the response will be “tableau is not defined”. Woops. We haven’t yet created and initialized a reference to the Tableau Extensions library in our extension web app, so our web app can not yet use the Tableau Extensions API. Tableau doesn’t know what we’re talking about.

Let’s fix that.

Environment Setup

Example Code

The example code for this whole series of articles is posted to github at https://github.com/tabblogs/TableauDBWBExtensionsStN. Feel free to pull that whole thing down to your machine or just look there occasionally for clarity.

Code Editing

You will need an editor. I use Microsoft Visual Studio Code and recommend it. You can add extensions to customize and enhance your experience. You can open a terminal window to run your web server right there in the editor. Great stuff.

Setup Steps

In order to further explore Tableau extensions, you will need to set up a developer environment on your machine.

  • Either create a new directory on your machine, or use the directory you created for part 1. I put mine (on Windows) in …/documents/dev/extensions/.
  • Open a command prompt (terminal) in the new directory.
  • Install NodeJS and NPM. (Windows, Mac, Linux).
  • To verify your installation, type node -v and then npm -v at the command prompt. Node and npm should respond with their respective versions.
  • Install the express JavaScript library: type npm install express at the command prompt.

Create a file called app.js in the same directory. Paste the following JavaScript into app.js:

const express = require("express");
const app = express();
const port = 3000;

app.use(express.static('.'));

//start the server
app.listen(port, function() {
    console.log("Our server is running on " + port);
});

Express ” is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. ” We are using it now to configure a simple web server for our local use, and we will use Express in future articles to route requests within our web app.

Node.js is a Javascript run-time environment built on Chrome’s V8 Javascript engine. This article is a great introduction, and throws in some Express intro content as well.

The code in app.js creates an instance of Express, then configures a static route at the root directory of our project (the app.use… line). This means that it will serve anything that we ask for in a browser in the directory structure under our project root directory. The app.listen line starts our web server listening on the port we specified.

  • Start the web server by typing “node app.js” at the command prompt. It should respond with “Our server is running on 3000”
  • If you would like to test your configuration, copy part1.html into the root directory (or in a part1 directory if you would like). Browse to http://localhost:3000/part1.html, and you should see the web page from part 1.
  • Create a directory under the project root directory called part2.
  • Create a file in the part2 directory called part2.html.
<!— Part2.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Tableau API library -->
    <script src="../lib/tableau-extensions-1.latest.js" defer></script>
    
    <!-- jQuery -->                                                    
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

    <!-- reference our Javascript functions -->
    <script src="/part2/Part2.js" defer></script>  
        
    <title>Extension Quark</title>
  </head>
  <body>
    <p>Referencing the Tableau Extension JavaScript library.</p>
  </body>
</html>

The Part2.html file includes a reference to the Tableau extensions JavaScript library (the first script src=… line). The two periods in ../lib.. indicate that the directory is under the root directory. Download the Tableau Extension library files from https://github.com/tableau/extensions-api/tree/master/lib and place them in a new directory called lib under your root directory. (I have had better luck downloading the whole 337Mb zip file and pulling the libraries from there than downloading them individually.)

The “defer” attribute in the script source tag specifies that the script is executed when the page has finished parsing. Without that attribute, our script will run before the objects it needs to refer to are ready in the html document object model (DOM), and nothing will happen. Frustrating.

Our latest html file also contains a reference to jQuery, “jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers.” Part2.html also contains a reference to part2.js, our first JavaScript file.

Create part2.js in the part2 directory. Part2.js contains just a few lines of code:

tableau.extensions.initializeAsync().then(
  () => {
    $('body').append('<p>Extension library initialized!</p>');
  }
);

Okay, buckle up. The first line initializes the Tableau Extensions API. We need to do that before we can interact with it in the debugger console or anywhere else. It calls the initializeAsync function on the extensions API to load and initialize. The “then” function uses the JavaScript Promises API to enable our code to wait until the Extension library is initialized, then perform an action. Everything we do in JavaScript having to do with extensions will happen within the set of curly braces {} after this “then” function. Also, any Extension API function with a name ending in “Async” must be called with a “then” function. The ()=> is a JavaScript shortcut for function(). The line of code with the {} calls the jQuery function (the $ is an abbreviation for jQuery) to get access to the ‘body’ element of our html page and append an html text paragraph announcing our success.

In order to use part2.html, change your trex file to point to part2.html rather than part1.html.

<source-location>
  <url>http://localhost:3000/part2/part2.html</url>
</source-location>

Here’s a tip to avoid some frustration. Anytime you make a change in a trex file, you need to close and reopen the extension in Tableau Desktop. If you find yourself making changes to your code that aren’t appearing in your extension, you might have changed your trex file and forgotten to close and reopen the extension. In cases where you’ve made code changes, but haven’t needed to change your trex, simply select “reload” from the “more options” down arrow in the controls of your extension window.

Choose reload to check on changes in code within your extension. If you have changed the manifest file (.trex), you will have to close (with the X) and reopen the extension.

Interacting with the Tableau Debug Console

Now, reload the tablogs_writeback.trex extension. Back in Chrome, you’ll need to re-open localhost:8696 because the extension we were debugging was closed.

Let’s ask the API how many worksheets are in the dashboard. Go back to the console at localhost:8696 in your browser and type:

tableau.extensions.dashboardContent.dashboard.worksheets.length

The Tableau extension API will reply (if you’re on the SuperStore Overview dashboard) with “4” because there are four worksheets in that dashboard.

Let’s find out the name of the first worksheet. Type:

tableau.extensions.dashboardContent.dashboard.worksheets[0].name

The Tableau extension API will reply (if you’re on the SuperStore Overview dashboard) with “Sale Map”.

Let’s find out how many individual objects Tableau counts in the dashboard. In the console, type:

tableau.extensions.dashboardContent.dashboard.objects.length

The Tableau extension API will reply (if you’re on the SuperStore Overview dashboard) with “16”.

What size is this dashboard? In the console, type:

tableau.extensions.dashboardContent.dashboard.size

What size is the “Sale Map” worksheet? In the console, type:

tableau.extensions.dashboardContent.dashboard.worksheets[0].size

This is just a peak into the information the Tableau extensions API can provide. Of course it also provides a set of functions (documented here) that enable us to manipulate the objects in the Tableau dashboard.

In part 3 we’ll start looking at the JavaScript that will make our extension a web app.

Author: Larry Clark

Larry has been a Tableau employee since October of 2018. Prior to Tableau, Larry was a BI consultant for Catapult Systems. Prior to Catapult, Larry was in DB/BI technical sales for Microsoft for >20 years.

Leave a Reply

Your email address will not be published. Required fields are marked *