HTML5 Zone is brought to you in partnership with:

Raymond Camden is a developer evangelist for Adobe. His work focuses on web standards, mobile development and Cold Fusion. He's a published author and presents at conferences and user groups on a variety of topics. He is the happily married proud father of three kids and is somewhat of a Star Wars nut. Raymond can be reached via his blog at www.raymondcamden.com or via email at raymondcamden@gmail.com Raymond is a DZone MVB and is not an employee of DZone and has posted 212 posts at DZone. You can read more from them at their website. View Full User Profile

Tips for Using Brackets and Theseus

09.26.2013
| 1632 views |
  • submit to reddit

I've blogged before about the Theseus project, a way to debug client-side and server-side JavaScript, but I never got around to actually testing it. Today, the Brackets blog discussed the most recent 0.4 release and how it works within Brackets. I ran into a few issues (part my misunderstanding and part simple issues), so I thought I'd share some tips and examples of how Theseus works. My thanks go to both Thomas Lieber and Joel Brandt for being helpful!

In a nutshell, Theseus can help you see what methods are being called, what arguments are being passed to them, and inspect stack traces for your code. This is supported for "regular" client-side code, Node.js on the server, and both together.

Let's consider a simple example, a client-side application. If you watch the video on the blog entry I linked to above, you'll note the narrator says he "enables Theseus," and things just work. I didn't quite get that. I had installed the Theseus extension (remember you can do so very easily by using the Brackets extension manager), but the only menu I had noticed was Debug/Debug Brackets with Theseus. I wasn't interested in debugging Brackets, just my regular code.

Turns out it was under the File menu, and already enabled:

So, given a simple HTML page (and yes, Theseus will work with JavaScript embedded in an HTML page, which is nice!), you can click the Live Development icon and you should be good to go.

Consider the following code. It is a simple example of the HTML5 Datalist control bound to server side data (blog post).

<!doctype html>
<html>
<head>
<title>Example 2</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {

  if(document.createElement("datalist").options) {

		$("#search").on("input", function(e) {
			var val = $(this).val();
			if(val === "") return;
			//You could use this to limit results
			//if(val.length < 3) return;
			console.log(val);

			$.get("artservice.cfc?method=getart&returnformat=json", {term:val}, function(res) {
                console.log('got stuff');
                alert('hi');
				var dataList = $("#searchresults");
				dataList.empty();
				if(res.DATA.length) {
					for(var i=0, len=res.DATA.length; i<len; i++) {
						var opt = $("<option></option>").attr("value", res.DATA[i][0]);
						dataList.append(opt);
					}

				}
			},"json");
        
        });

	}

})
</script>	
</head>

<body>

<p>
	<input type="text" name="search" id="search" placeholder="Type Something" list="searchresults" autocomplete="off">
	<datalist id="searchresults"></datalist>
</p>

</body>
</html>

After connecting Brackets to my browser and typing a bit, I can immediately see Theseus working!

But look... it's broken. It reported document.ready. It reported the input calls. But my Ajax calls are not firing. WTF. Stupid open-source software.

Then it occurred to me ... wait ... is this Ajax event firing right? Turns out my backend application server was dead. Notice how my jQuery code doesn't have an error handler? Yeah, that was a test. If you noticed it, you passed. I rewrote my code:

$.get("artservice.cfc?method=getart&returnformat=json", {term:val}, function(res) {
    console.log('got stuff');
    var dataList = $("#searchresults");
    dataList.empty();
    if(res.DATA.length) {
         for(var i=0, len=res.DATA.length; i<len; i++) {
              var opt = $("<option></option>").attr("value", res.DATA[i][0]);
              dataList.append(opt);
         }

    }
},"json").done(function() {
   console.log("done");
}).fail(function(e) {
   console.log("freaking fail");
 });

And now check it ...

So, my next issue was how to use this with Node. While documented at the Theseus GitHub page, if you just read the Bracket's blog, you may miss this. You need to install node-theseus via NPM and then run your application at the command line with node-theseus. You then may run into this bug:

[node-theseus] caught uncaught exception
Error: listen EADDRINUSE
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1039:14)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.exports.listen (/usr/local/lib/node_modules/node-theseus/node_modules/websocket.io/lib/websocket.io.js:62:10)
    at Object.exports.listen (/usr/local/lib/node_modules/node-theseus/node-theseus.js:88:14)
    at Object. (/usr/local/lib/node_modules/node-theseus/bin/node-theseus:92:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
[node-theseus] caught process.exit(), not exiting
Express server listening on port 3000

Notice the EADDRINUSE error? This didn't make sense to me, as Express did start up and my application was available. Turned out that Theseus was using port 8888 in the background, and that port was being used by something else on my machine. Killing that fixed everything.

At this point, you still want to connect Brackets to Chrome - you may forget that. And you may - I'm still digging into this - need to switch the "proxy" option under the Brackets File menu as shown above. But it should work great. One thing that tripped me up for a second was the following: I have this in my app.js:

app.get('/', routes.index);
app.get('/data', routes.data);

I noticed Theseus didn't note this. Turns out that it was noting it in routes.index.js, which kind of makes sense. That's where the actual code is. Here is a screen shot from that file:

There you go. All in all, pretty darn fascinating. I definitely recommend checking it out, and if you have trouble like I did, use the Theseus Discuss Google Group for help.

Published at DZone with permission of Raymond Camden, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)