Where does that log come from?

Of course we all use Studio’s debugger or Ti-Inspector to step through code when we run into errors, but I’m sure your code has its fair share of Ti.API.debug() or console.debug() calls as well. If your console is filled with these logs, wouldn’t it be nice to know from which file they come?

Double-underscore === Warning

In Alloy controllers – including those of widgets – have some special properties. I’ve used $.__parentSymbol for my infiniteScroll and pullToRefresh widgets and when Alloy 1.3.0 came out quickly found out what Tony already warned me for:

Double-underscore means “Don’t count on it being there”

Unfortunately, an alternative is still in progress.

__controllerPath

Having warned you about the above, there are 2 other properties we can use for something less sensitive for breaking changes. The $.__controllerPath property holds the path to the controller, without the actual controllers/ directory and the file extension. So a controller in app/controllers/foo/bar.js will give foo/bar. Widgets have another property $.__widgetId which as the ID of the widget.

Combine these and you can include the path to the controller in your logs like this:

console.debug('[' + $.__controllerPath + '] ' + JSON.stringify(someStuff));

You could further simplify this by creating lib/console.js with:

module.exports = function($) {
  var prefix = ($.__widgetId ? 'widgets/' + $.__widgetId + '/' : '') + 'controllers/' + $.__controllerPath;

  function format(msg) {
    return '[' + prefix + '] ' + JSON.stringify(msg, null, '  ');
  }

  var self = {};

  _.each(['debug', 'error', 'info', 'log', 'warn'], function(level) {
    self[level] = function(message) {
      console[level](format(message));
    };
  });

  return self;
};

In a controller, you can then simply override the default console and use it like you’d normally do:

var console = require('console')($);

console.debug(someStuff);

Code strong!

App imagineer: Imagining, Engineering & Speaking about Native mobile Apps with Appcelerator Titanium & Alloy • Meetup organizer • Certified Expert • Titan


Comments

  • Steven House

    Man…. another awesome tip! I’ve been working on a logging library and optional widget for a good amount of time.
    I’d usually invoke it with log.info(‘File.js :: msg’, {optionalData}); – it echos to the console and then saves it in a model – good to search by a file. This will alleviate the necessity of including the file name!
    I’d like to share it with you for feedback before a public release. It’s not a waste of your time and could likely improve your workflow. Let’s get in touch.