Do I Need To Know JavaScript If I Use Articulate Storyline For eLearning?
The other day I had the pleasure to chat with Devlin Peck about pushing the boundaries of Articulate Storyline by using JavaScript [1]. The discussion was meant for beginners. Nothing too technical. Through the conversation, we explored reasons why someone would benefit from learning JavaScript along with Storyline. I've received a ton of comments and questions about the topic and a pattern emerged.
Whether you use JavaScript or not in eLearning (not only with Storyline), there are some fundamentals you need first. This is a two-piece article for those who are new to the technology side of eLearning.
Is This Article For Me?
This article covers the fundamentals you need to know before you jump into JavaScript or even just basic troubleshooting your published eLearning courses. You can quickly decide if this article is for you. If you know the answer to these questions in the context of eLearning, you are too advanced for this article:
- What's the difference between http, https, SSL, and TSL?
- How do HTML, CSS, and JavaScript work together to produce the web page you see?
- How do you use the browser's Console to check if all files are downloaded correctly?
- How do you check for errors and warnings in troubleshooting a published course?
- What's the Storyline Player? And how does it communicate with JavaScript?
- How to get and set Storyline variables from inside a web browser?
Troubleshooting In The Browser
You published a course, and when you try to view it, it's blank. No error message. Nothing. Just blank. It's not working. What do you do?
To troubleshoot this problem you need to open up the hood and peep into one of the most common applications in the world: your internet browser. When you type a URL in the browser, you expect to see the particular site's web page instantly (or if you have a slower connection after some lag). Did you know that what you see is NOT a page on that particular site?
Let me explain:
- You type in a URL, let's say https://www.rabbitoreg.com, which is my blog.
- If your browser is connected to the internet, the first thing it will attempt is to find out the "IP address" that belongs to www.rabbitoreg.com. There are servers on the internet that just do that. It's like finding the address of your friend based on their name (assuming it's unique). Why do we need URL addresses and behind-the-scenes IP addresses? They are practical because you can keep a URL such as www.rabbitoreg.com and change the actual servers without disruption for your users. For example, you can move from Hostgator to Bluehost. Your audience will never notice. At the same time, it would be hard to remember and marker a bunch of numbers as URLs.
- Once the IP address is found, then your browser "pings" the webserver that owns this IP address. It's like relaying the message that someone wants to see this particular page on that server.
- The server then checks if this page exists at all. If it does, it checks if anyone has access to it or whether it is restricted to certain users. If it is public, then it starts serving bytes to the browser. It's like "Hey, here's all the info, go and put it together."
- The browser then receives these "packets" of info and interprets what's in them. (The reason why the browser and the server can understand each other is that they agreed on what language they use, what protocol they communicate through, and the port or channel they're on. Here's more info if you're into this stuff [2].)
- Once the browser receives the initial packets and puts them together (this is your HTML page) locally, it starts interpreting the HTML page. The page may tell the browser to fetch more files, such as JavaScript files, graphics, CSS files for colors and layout, external data, etc.
- Once all files are loaded, the browser also executes JavaScript code found on the page.
- When all is said and done, you see the page in your browser.
- All this communication between your local browser and the web server on the internet can be wide open. Literally, anyone can listen to what you're doing if the communication is not encrypted. Sometimes it doesn't matter. However, when you're talking to your bank, you may not want the world to see that. This is why "secure" communication is important. Secure communication means that all the information is encrypted between the browser and the webserver. It can only happen on https protocol (rather than http). There's a lot more to learn about this such as SSL/TLS [3].
A couple of fundamental points here: HOW the page looks depends on your browser because the server just sends the information but the "rendering" and interpretation happen locally in your browser. That's why it is a nightmare sometimes for eLearning developers to test something in Chrome, Firefox, Opera, Safari, IE (rest in peace), Edge, etc. Not to mention that each of these browsers may have different versions running on different operating systems.
Browser Troubleshooting: Now What?
Great story, but what do I do with all this?
Good question. This whole "handshake" and info exchange happens so fast in today's world that often a page appears instantly. However, all browsers provide you a way to monitor and debug issues, they're just hidden from amateurs.
In Chrome you can open the developer window through a shortcut Ctrl+Shift+I (or ... More →Developer Tools). This is going to be your friend! Even if you never use JavaScript, mastering the developer window can solve you a bunch of headaches.
HTML, CSS, And JavaScript In The Browser
In the context of web pages, you may hear three terms a lot: HTML, CSS, and JavaScript. To simplify, think of HTML as the content to be shown. It is a markup language you can see if you right-click on any page and select View page source. CSS determines how the page looks: the layout, colors, styles, etc. It is usually in a separate file the page loads. Nowadays, you can do really fancy things such as animations with pure CSS without any JavaScript [4]. And finally, JavaScript, which can manipulate the page, provide interactions, hide and reveal elements, calculate values, handle forms, etc. Since JavaScript has been used for a long time and often, there are frameworks (Vue, Angular, React, etc.) created for specific use cases [5]. A framework is like a bunch of pre-built components so you don't start from scratch.
Vanilla JavaScript
Out of the box, without using any additional frameworks, all browsers understand JavaScript. This is the plain version of JavaScript, what we often refer to as vanilla JavaScript. The examples in the article are all vanilla JavaScript.
Elements, Console, And Network Tabs In Chrome
Let's start with the Network tab. The Network tab shows all the files and bits of information the browser is sending or receiving. We call this Network traffic. Stay on this Network tab and refresh the page (F5). You'll see in real-time how fast files are downloading.
One of the most important pieces of information on this page is the status of each item. This is the second column, after the name of the file. The thing is your browser may ask the webserver for thousands of individual items. For each item, the server acknowledges the ask with a status number. The code 200 means everything is okay.
(Did you know that Google has an app for Chrome called OK 200? The reason it's called OK 200 is that 200 is the code web servers send if the request is served without any issue.)
Other well-known numbers:
- 404 - Unkown
This happens when the browser requests an item that does not exist on the webserver. - 401 - Forbidden
In this case, the browser made a valid request but the webserver refuses to serve the information. This could be because the user is not logged in or logged in but does not have the permissions to see the item. - 500 - Internal Server Error
That's bad. I mean really bad because it means an "unknown reason" caused the problem on the server. Browsers can't fix that.
For anything else, check out this list [4].
So, back to the original question: no error, only a blank page. What do you do? You open the developer window, go to the Network tab, and refresh the page. You may see problems with certain files (usually red) with an error code. Those might be the culprit.
The Console Tab
The Console tab is your buddy for all troubleshooting beyond the initial Network tab. Even if all files are loaded fine, you can have tons of issues with them. In fact, the Console tab is where you're going to spend most of your detective work. For starters, the Console tab displays errors and warnings for your web page. Some of these are non-vital, others can break the whole page.
Tip: If you work with clients and they report "it's not working" sort of errors (which is basically useless information for you), ask them to do the same. Open their developer window, open the tab and take a screenshot of what they see. This is a much better starting point for troubleshooting than "it's not working"
The Common Culprit: Embedded Objects In Storyline
One question I often get is about embedded web objects not showing up in Storyline. When you publish your course, Storyline tries to show your embedded object (which would be a site) in an iframe. An iframe is like a browser in the browser. It looks like part of the web page but actually, it is completely independent like a window in a window.
The Console the first thing I tell people to look at. You may see in the Console that the site "refused to show" in an iframe. It is a red error in the Console. For example, if you try to embed Google as a web object so people can search, it would refuse to show. (You can't do anything about it unless the webserver itself specifically allows you to embed in the site.) The same thing happens if your published course is on an HTTP site and you're trying to load another site from an https page.
The Console Speaks JavaScript
The other practical use of the Console is that it speaks JavaScript. That means you don't need any fancy site somewhere to test out simple commands. You can do it right in the Console.
If you type in alert("Hello World!") and hit enter, a popup message shows up. If you want to display this message in the Console itself: console.log("Hello World!"), this would show the same message in the Console. Well, that's kind of useless. Agreed. "Hello Worlds" are mostly just the first steps when learning a new programming language. But it will be a lifesaver for Storyline and the communication with its Player.
What Is The Storyline Player?
It is important to understand how Storyline courses operate in a browser when published. Storyline uses what they call the Player inside the browser. The Player is responsible for knowing what to show and when, handling variables, watching triggers, etc. This Player also "hides" Storyline variables from outside. The only way to read or write Storyline variables is through the Player. It's kind of the gatekeeper for any change inside your published course.
What that means is that JavaScript, the language that the browser natively understands, is not inside the Player. It is outside of the Player only available for the browser. Storyline variables are inside the Player. To access Storyline variables, JavaScript needs help. Luckily, the Player is willing to play the "messenger" between the outside world and the inside Storyline variables.
To display the value of a Storyline variable in the Console try this command (assuming you have a Storyline variable called variablename):
console.log(GetPlayer().GetVar("variablename"))
Let's break this JavaScript code apart:
console.log("message") you learned before just displays whatever is in the brackets.
GetPlayer() is a function that Storyline owns. A function is like a frequently executed program that does a specific thing. In this case, it returns the player for us to communicate with Storyline. You will not be able to use this function unless it is a Storyline published project you're viewing in the browser. GetPlayer() returns an object that allows you to set and get variables by their names. Now that you have the Player's attention, it lets you set or get variables.
The "." (dot) in GetPlayer().GetVar("variablename") is a standard notation to access the GetVar() function inside GetPlayer(). You can't just type GetVar("variablename") in the Console. It would not be recognized because it is only valid inside the Player.
To set a Storyline variable, you use:
GetPlayer().SetVar("variablename","value")
With SetVar(), you need to tell Storyline what variable you're setting to what value. Depending on the type of the variable, this command may look different:
GetPlayer().SetVar("Age", 21)
GetPlayer().SetVar("Name","Zsolt")
GetPlayer().SetVar("Very Smart", false)
Does That Mean ANYONE Can Change Storyline Variables From Their Browser?
Yes, you can change your Storyline variables from within the Console. And yes, ANYONE can do that. As long as users know the name of the variable, they can set it right from their browser. So, next time you name your variables you may want to be more sophisticated than using Score, for example.
Tip: There is no way to list all the variables that Player has, so users must know the name of the variable. But yes, JavaScript can manipulate your course. This gets even worse, though! If you're using SCORM users may simply send a couple of lines of code from the Console and your LMS marks the course complete with a 100% score. (It does not work with all courses but yes, that's how vulnerable a simple pass/fail can be.)
Last word on GetPlayer(): Since often the code we use has several lines, it is cumbersome to type GetPlayer() every single time. It also makes the code less readable. That is why you often see in JavaScript that we assign the GetPlayer() to a JavaScript variable first and then use the variable from there:
let player = GetPlayer();
console.log(player.GetVar("Age"))
-> 21
player.SetVar("Age",100)
console.log(player.GetVar("Age"))
-> 100
JavaScript And Storyline Variables
The "player" in this case is a JavaScript variable. We could name it foo, or junglegym as long as you consistently use it afterward. JavaScript variables are NOT the same as Storyline variables. Remember, the Player keeps everything inside, isolated from the world. JavaScript variables are like Storyline variables but there are more types than just number, text, and boolean. We'll cover variables in the second part of this article series.
Tip: Pay attention to lower and upper case letters in your variable naming convention. Variable names are case-sensitive in JavaScript. If your Storyline variable is called Age but you issue a command for player.SetVar("age", 21) it won't work because "age" and "Age" are two different variables in JavaScript even if Storyline variables are NOT case-sensitive. In JavaScript, you can have two different variables such as age and Age at the same time. Storyline won't let you create Age if there's already an age variable as it is not case-sensitive.
Advanced Player actions
Now that you know how to get and set variables, here's a final challenge for you. Assuming that you have an "Age" variable in Storyline, what will be the Console outputs after running this code? And why?
let player = GetPlayer();
player.SetVar("Age", 21);
console.log ( player.SetVar("Age", player.GetVar("Age") + 1) );
let age = player.GetVar("Age");
console.log ( age );
The answer is coming in part 2 of this article series.
Conclusion
Troubleshooting any HTML published course should start with the developer window. Check the errors in the Console, check the Network red lines (other than OK 200). A single error can break the whole course. Another advantage of using the Console is that it clear the cache for your page (if set properly). Often problems linger because the browser is using cached data.
Use the Console to interact with variables inside Storyline. This is useful when you're doing quality assurance, for example, and you need to unlock certain things without going through the activity. You can just flip whatever variable Storyline is watching as a trigger to unlock a slide or activity.
Finally, you can use Storyline's JavaScript trigger to send messages to the Console. This is a lifesaver when you have complex logic and lots of variables in Storyline. You can add JavaScript triggers in the flow of your design to keep you updated in the Console on how things are working. If you're planning to learn more about JavaScript, check out these recommended courses [6].
Final Tip: When to use alert() versus consol.log()? Alert suspends all activities in the browser and displays a popup message. Console.log writes the message into the console but never interrupts your code. Which one to use when? The only time I suggest using alert() is when you want to STOP everything. This is useful, for example, when variables change so quickly that by the time you see the results in the Console, it's too late. You can add step-by-step alert() commands to see how they're changing. Note that you can have only one alert popup at a time.
This article is Part 1 of a two-part series. Read Part 2 here.
References:
[1] Going Beyond Storyline with JavaScript ft. Zsolt Olah
[2] TCP/IP Ports and Sockets Explained
[3] What is SSL, TLS? And how this encryption protocol works
[4] 150+ Amazing Examples of CSS Animation & Effects
[5] Comparison of JavaScript-based web frameworks
[6] Top 10 JavaScript Courses, Tutorials, & Certifications Online in 2021