Saturday, June 29, 2013

PLINQ

using System.Linq;
using System.Web.Mvc;
using MyApplication.Models;
namespace MyApplication.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         string loremIpsum = LoremIpsum.Copy();
         var query = from word in loremIpsum.Trim().Split(' ').AsParallel()
                  select word.ToUpper();
         string alteration = string.Join(" ", query);
         return View();
      }
   }
}

 
 

PLINQ, LINQ with processing parallelized on multiple threads, is yet another thing I have read about in C# 4.0 in a Nutshell by Joseph and Ben Albahari. As you might guess, LoremIpsum.Copy(); above returns the copy of lorem ipsum in a string. I set a breakpoint at return View(); above in Visual Studio to see how .AsParallel() would bias the outcome. As it turned out, the words came back in an odd order, as to be expected, although this did not happen after I reran the code a few times. (Adding .AsOrdered() after .AsParallel() forces the ordering to be as though it did not happen on separate threads.)

 
 

Copy out of page 874 of the book:

  • In recent times, CPU clock speeds have stagnated and manufactures have shifted their focus to increasing core counts. This is problematic for us as programmers because our standard single-threaded code will not automatically run faster as a result of those extra cores.
  • Programming to leverage multicore or multiple processors is called parallel programming. This is a subset of the broader concept of multithreading.

Friday, June 28, 2013

JD Edwards is now owned by Oracle like PeopleSoft.

JD Edwards is another ERP like these. (Maximo isn't really an ERP. It is just asset management software which is just a piece of the other ERPs.)

Bluetooth

...is short range wireless signal stuff like your wireless keyboard talking to your PC or your cell phone talking to your earpiece. It is not long range communication stuff like your cell phone speaking to a tower.

Monday, June 24, 2013

Subrepositories in Mercurial

If one populates a folder within a project by way of a subrepository it opens the door to some danger. A commit at the top of the consuming project will cascade to commit changes in the subrepository folder as well making such a pattern not so great for scenarios in which one project needs to consume a library that is another project without altering it. The ways to fix this shortcoming may lie in merely permissions for the subrepository for only the right users or there may be a setting for labeling the subrepository as commit-impaired, but such a setting would have to be prepped properly by the individual crafting the call to the subrepository to begin with.

Sunday, June 23, 2013

Introduce Middle Man

I found I enjoyed wasting time here by snapping some photos of the insides of a book and writing up some thoughts on code which only really tied in with the book's contents within my imagination and thus, I feel compelled to do something similar again. I have a good (well, better) excuse this time, and thus I will draw upon three books as I want to show off a refactoring I will dub: "Introduce Middle Man"

Alright, in preparing for this presentation, I looked through Martin Fowler's "Refactoring" for a refactoring that matched one I would speak to. I did not find what I had hoped for. The closest thing I found was the exact opposite of what I hoped to find. It was a refactoring called "Remove Middle Man."

In the example shown here, a Client speaks with a Person within a Department to interface with the Department. One would embrace the refactoring by deciding that not only was it not a violation of the Law of Demeter for Clients to just interface directly with Departments but moreover it was sloppy to have to go through a Person in lieu of having a direct line of interaction as it created unneeded complexity. Alright, what if we wanted to introduce a middleman instead of taking one away. Could there ever be an application for as much? If there was, why didn't Fowler put it in his book?

In second edition Advanced Dungeons and Dragons, the last version of the game that I really embraced, a lot of the spells were marked as reversible meaning that if your character knew the spell your character also knew an alternate opposite. This was at least true with the way we played priests specifically. The fourth level Priest spell "Sticks to Snakes" which one may use to turn fallen tree branches in a woody area into serpents was, for example, reversible and its reverse was "Snakes to Sticks" which, as the name suggests, turned snakes into sticks. Both versions were a corny thing I just saw in the Player's Handbook and not something that I actually ever saw come out in actual gameplay. I don't think I ever was in a Raiders of the Lost Ark* Scenario, facing down a bunch of snakes, in which I wished I had "Snakes to Sticks" in my pocket. I suppose that the praxis for "Snakes to Sticks" was turning back off an opponent's "Sticks to Snakes." I mention this because I feel that the "Remove Middle Man" refactoring should be marked as reversible and that the reverse would be "Introduce Middle Man!" The closest thing to a reverse of "Remove Middle Man" in Fowler's book is "Hide Delegate," but it sort of assumes that an existing class/method/function/thingamabob will take away responsibilities from a dance partner which should not be directly talking to the thing it hides. What if we instead want the class/method/function/thingamabob to be a new creation that empowers better interactions with the two things it separates as a sole responsibility in lieu of a secondary feature? Why would we ever want this complexity, why wouldn't A and C just talk to each other without B being sandwiched between them. The answer comes in scenarios in which C is third-party code which you cannot or should not change on your own that yet needs to do more than it does. In these circumstances B becomes an extension for C. Examples:

  • This is how one extends a controller in ASP.NET MVC: Every controller inherits from Controller which sits in the System.Web.Mvc namespace. I do not recommend that you use JetBrains dotPeak to break open System.Web.Mvc so that you may change its guts about and then save off your alternate System.Web.Mvc .dll as a delicate little snowflake somewhere else. A better way to go is to have controllers inherit from a middleman class which in turn inherits from Controller. At AMD, our implementation came in a class called BaseController which inherited from Controller. All of the individual controllers inherited from BaseController and it held some stuff for helping in serializing types to JSON. Every controller in our app could have access to the new feature we bolted onto Controller by way of a middleman.
  • More recently, I have written on how we extended the default transition within a dojox/app application to allow it to fire an event when it finished which it did not do by default. Within the config.json (the Web.config of dojox/app) one may specify an AMD module to use in lieu of the default for transitions. We specified a middleman which just turned around and called the default module for transition. In setting up this pass-through, we could then shove stuff into the pass-through and we added an event which fires when transitions end. This solution comes from one of my superiors, I originally thought to make a copy of the default (dojox/css3/transit) and doctor it up, but it was pointed out to me that we didn't want to make something we could not upgrade. (We don't alter any of the dojox code itself, just our own extensions of it and controllers and views for it.)

*Speaking of arks (good segue?), as I thought to type this I thought of the bit in the sequel to The Hitchhiker's Guide to the Galaxy called The Restaurant at the End of the Universe which had to do with getting rid of all of the middlemen by sending them off on Ark B. When I read the The Hitchhiker's Guide to the Galaxy as a teen I initially cared enough to start into the sequel, but I gave up on the series partway through this second book. (I love the place of Douglas Adams' books in geek culture, but his books aren't really good books by any means.) I think I only learned of the Ark B stuff via some TV representation of the book. Anyways, a planet-bound society wants to get rid of all its middlemen (personnel officers, security guards, public relations executives, management consultants) and does so by drumming up a lie that the planet is doomed and that all of the citizens will journey out into the stars to find a new home in three giant arks (spaceships). Ark A will hold the "achievers" (brilliant leaders, scientists, great artists), Ark B will hold the middlemen, and Ark C will hold the people who actually do all the work on the "doomed" planet. Ark B leaves first, and of course the A and C groups don't leave at all. This sort of cleaning is pretty consistent with Martin Fowler's "Remove Middle Man" refactoring, but I for one have come to find that middlemen are not always wastes of space and that there are times when they are needed.

Saturday, June 22, 2013

Crisscross will make you jump, jump!

Look, this isn't so good:

How may we prevent this and keep the trunk changes at the left consistently and the branch changes off to the right? In TortoiseHG when you are either ready to shove a local commit to your branch or you just want to get the trunk changes in line with your own code, you may see a scenario like so in which the trunk changes sit to the right, detached from your own head.

Right-click on the trunk's head. There will be an option for updating to main line. Do it. You will get something like so:

Then get latest from the trunk. Alright, now your own stuff sits to the right of the main line with a detached head.

Right click on the head and pick the merge option.

Everything should be happy now.

SalesForce email API

While I am thinking of it, I'd like to offer something random. When I worked with SalesForce at Headspring (more than two but less than five years ago) at that time there was an email-based API for SalesForce which was pretty magically. I imagine it is still around. If you are a sales rep (you hold a SalesForce account) and you email a lead or a contract while CCing a SalesForce email address... a communication record (I cannot remember what they are called) is logged at that party in SalesForce with the copy out of the email. How was this possible? I would imagine that:

  1. a server at SalesForce consumes the inbound emails that reach the carbon copied address
  2. a process checks to see if the email address that sent the email is also the username for an account at SalesForce
  3. in finding a match the process queries for a matching email address at a lead or contact
  4. a record is written at the lead or contact

Thursday, June 20, 2013

Use join() in JavaScript to concatenate the items in an array to a string wherein the array items are separated by commas.

define([], function() {
   return {
      getTargetById: function(id, tabToBe){
         var pieces = id.split("_");
         pieces.shift();
         pieces.push(tabToBe);
         return pieces.join(',');
      }
   };
});

 
 

If we hand in "foo_bar_baz" for id and "qux" for tabToBe, we get back "bar,baz,qux" from our AMD module above. If the comma were left out of the join and the join just looks like join() then the comma would be used as a default.

JSDuck is going to walk your JavaScript code and return documentation.

See: https://github.com/senchalabs/jsduck

An iOS7 Beta is available now and open to the public and not just developers.

You are free to download it and screw up your phone. Remember: Beta

Wednesday, June 19, 2013

Pushing from a DVD to YouTube seems pretty painless.

Log into your YouTube account, go to upload, and then find a .VOB file on the DVD in your DVD drive to push up. This makes it look easy. It also suggests there is now a ten minute time limit.

Mou is a Markdown editor for the Mac.

See this. Markdown is a markup syntax like HTML.

Bower

CommonJS is another paradigm for breaking JavaScript out of one huge file into demonstrable chunks not unlike AMD modules, and Bower is a generic "front-end" package management tool which can manage either CommonJS gunk or AMD modules or another flavor of JavaScript packeting (making up my own word) along these lines.

Karma drama with modern Node.js

Testing with Karma is the only good way to test AngularJS. If you use with PhantomJS with Karma there will be a dependency on Node 10.6 or earlier.

ghost semicolons in JavaScript

Building on this, I learned today that the reason to not have a line break between an open curly bracket and the thing opening it in JavaScript lies in the reality that the semicolon is optional as terminator in JavaScript and that when it is left off (intentionally or unintentionally) that JavaScript may assume a termination when there is some ambiguity as to whether or not a termination should be. You may cut the ambiguity by just putting open curly braces on the same line as their openers. Please do so. If you do not you run the risk of authoring something like this...

return
{
   "foo":"bar", "baz":"qux"
}

 
 

...which ends up being interpreted with a ghost semicolon like so:

return;
{
   "foo":"bar", "baz":"qux"
}

 
 

Spooky!

Share photos on twitter with Twitpic

Tuesday, June 18, 2013

Empty Cache and Hard Reload

Once you open the Google Chrome Developer Tools in Google Chrome you will be able to get some new and interesting options when you right-click upon the refresh symbol at the upper left of the browser. The option for "Empty Cache and Hard Reload" is yet another way to throw away your cache.

JavaScript stack-walking loop!

The o in alert(isInLetterStack("o")); below may be replaced with any lowercase letter from a to j in the name of having an alert when comes back with true. Otherwise the alert will come back with false.

<html>
   <head>
      <script type="text/javascript">
         var letterStack = {
            "b":"a",
            "c":"b",
            "d":"c",
            "e":"d",
            "f":"e",
            "g":"f",
            "h":"g",
            "i":"h",
            "j":"i",
            "k":"j"
         }
         alert(isInLetterStack("o"));
         function isInLetterStack(target) {
            return inLetterStack("k");
            function inLetterStack(currentTarget) {
               if(!letterStack[currentTarget]) {
                  return false;
               }
               if(letterStack[currentTarget] == target) {
                  return true;
               }
               return inLetterStack(letterStack[currentTarget])
            }
         }
      </script>
   </head>
   <body />
</html>

_.isUndefined in underscore.js

This will give an alert saying "foo is undefined" followed by a second alert saying "foo is for real" immediately after:

<html>
   <head>
      <script type="text/javascript" src="underscore.js"></script>
      <script type="text/javascript">
         var foo;
         checkFoo();
         foo = "foo";
         checkFoo();
         function checkFoo() {
            if (!_.isUndefined(foo)) {
               alert('foo is for real');
            } else {
               alert('foo is undefined');
            }
         }
      </script>
   </head>
   <body />
</html>

 
 

It more or less behaves like so:

<html>
   <head>
      <script type="text/javascript">
         var foo;
         checkFoo();
         foo = "foo";
         checkFoo();
         function checkFoo() {
            if (foo) {
               alert('foo is for real');
            } else {
               alert('foo is undefined');
            }
         }
      </script>
   </head>
   <body />
</html>

 
 

I suppose in the second scenario foo could vary its behavior from the first scenario's circumstance by being set to false.

Google Reader for RSS is going away.

This is one of what I bet are many articles on the topic.

A method (C#) or function (JavaScript) not idempotent should not follow the "Is" convention.

  • Good:
    • C#: public bool IsOnDice(int possibleValue)
    • JavaScript: isOnDice(possibleValue)
     
     
  • Not so good:
    • C#: public bool IsCrappedOut()
    • JavaScript: isCrappedOut()
     
     
In my imagination isOnDice just tells you if the number handed in is between 2 and 12, HOWEVER the not idempotent isCrappedOut I envision as bad:
  1. generates a sum of two separate random numbers between 1 and 6,
  2. sets state at a field for LastRoll with the value,
  3. returns false if the value is 2, 3, or 12,
  4. and true otherwise
If the logic in isCrappedOut is only called by one other method/function and it can just be tucked into that method/function, that might be better than having isCrappedOut standalone. Otherwise, it needs a better name, one that does not start with is.

It looks like file type fields will allow for selecting and uploading photos on an iOS6 device.

This has a write up on these:

<input type=file>

...which look like so...

Monday, June 17, 2013

troubleshooting what is in the dojox/app 1.9 registry

In the name of troubleshooting this I set this breakpoint in Sources* like so:

I could then look into the "registry" variable at the Console* like so:

*within Google Chrome Developer Tools

Addendum: 6/18/2013: I typed the word "registry" at the console to get the first line following it which I then expanded by clicking the little arrows seen above.

the _.last of underscore.js will get the last item in an array

This...

var foo = _.last(myArray);

 
 

...does the same thing as this...

var foo = myArray[myArray.length - 1];

dropping stuff out of a Dojo 1.9 registry

I had been destroying unwanted temporary views in a dojox/app application like so...

function destroyView(view) {
   delete app.views[view];
   id = domMonikerForView + view;
   require(["dojo/dom-construct"], function(domConstruct){
      domConstruct.destroy(id);
   });
}

 
 

...but now I am doing so as seen here in the name of cleaning up the dojo registry first.

function destroyView(view, domNode) {
   delete app.views[view];
   require(["dijit/registry"], function(registry){
      var widgets = registry.findWidgets(domNode);
      _.each(widgets, function(widget) {
         widget.destroyRecursive(true);
      });
   });
   require(["dojo/dom-construct"], function(domConstruct){
      domConstruct.destroy(domNode.id);
   });
}

 
 

The registry keeps a living record of AMD modules which have been brought into state. One of my superiors thought that just dropping the view for a div without cleaning up the registry could open the door to a memory leak as there could be events tied to the views. It's hard to know. I don't know what dojox/app does under the hood to keep views/controllers in state as of yet.

how to run mocha tests for real

I have written a JavaScript function at C:\alttestrunner\spec\app\mythingtotest.js which I was able to get under mocha testing WITHOUT using Node.js by way of using a HTML test runner. My function is:

define([], function(){
   return {
      pythagoreanTheorem: function(a,b){
         var aSquared = a*a;
         var bSquared = b*b;
         var cSquared = aSquared + bSquared;
         var c = Math.sqrt(cSquared);
         return c;
      }
   };
});

 
 

The HTML test runner at C:\alttestrunner\test.html is just a plain jane .html document that one may open up outside of any web server!

The guts of the HTML file are shown below. Note the dependencies on require.js, mocha, and Chai. You will need to go get these from the world at large to get this example to work.

<!DOCTYPE HTML>
<html>
   <head>
      <meta charset="utf-8">
      <title>Mocha Tests</title>
      <script type="text/javascript" src="require.js"></script>
      <script type="text/javascript">
         require([
               'require',
               './lib/chai',
               './lib/mocha'
            ], function (require, chai, moca) {
            var options = {
               ui: 'bdd',
               timeout: 10000
            };
            mocha.setup(options);
            window.assert = chai.assert;
            require([
               'spec/alltests'
               ], function () {
                  mocha.run();
            });
         });
      </script>
   </head>
   <body>
      <div id="mocha"></div>
   </body>
</html>

 
 

There are only two more files to discuss. Firstly, C:\alttestrunner\spec\alltests.js denotes all test suites to run:

define([
   "./mytestsuite"
], function () {
   return "all tests loaded";
});

 
 

As you can see, we could run numerous test suites, but we are only running one. It is kept at C:\alttestrunner\spec\mytestsuite.js and looks like so:

define(["./app/mythingtotest"], function (mythingtotest) {
   "use strict";
   describe("attempting tests", function () {
      describe("test my thing to test", function () {
         describe("test Pythagorean Theorem", function () {
            
            var three;
            var four;
            var five;
            var twelve;
            var thirteen;
            
            before(function () {
               three = 3;
               four = 4;
               five = 5;
               twelve = 12;
               thirteen = 13;
            });
            
            it("should give a hypotenuse five units long for a right angle with sides three and
                  four units long", function () {
               var hypotenuse = mythingtotest.pythagoreanTheorem(three,four);
               assert.equal(hypotenuse, five);
            });
            
            it("should give a hypotenuse thirteen units long for a right angle with sides five and
                  twelve units long", function () {
               var hypotenuse = mythingtotest.pythagoreanTheorem(five,twelve);
               assert.equal(hypotenuse, thirteen);
            });
         });
      });
   });
});

Saturday, June 15, 2013

Grab elements by a class in Dojo 1.9.

In this case, I find all elements with dijitLayoutContainer slapped on them, but I really only want the first one which I assume will be around. In a dojox/app application this container holds a bunch of divs which are the outer containers for views.

function findDesiredViews() {
   require(["dojo/query"], function(query) {
      var viewWrapper = query(".dijitLayoutContainer")[0];
      
whatever...

Get an element by id in Dojo 1.9 and also find the ids of the elements within it.

Using underscore.js with Dojo, I herein put the id monikers of all of the tagged items within foo into an array called kids and then I just do nothing with the array:

<html lang="en">
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1,maximum-
            scale=1,minimum-scale=1,user-scalable=no"/>
      <meta name="apple-mobile-web-app-capable" content="yes" />
      <title>Whatever</title>
      <link rel="stylesheet" type="text/css" href="styles.css" media="screen">
      <style type="text/css" media="all">
         section {
            height: 40px;
         }
      </style>
   </head>
   <body style="overflow-y:hidden; overflow-x:hidden;">
      <article id="foo">
         <h1>FOO</h1>
         <section id="bar">BAR</section>
         <section id="baz">BAZ</section>
         <section id="qux">QUX</section>
      </article>
      <script src="underscore-min.js" data-dojo-config="async: true"></script>
      <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
      <script type="text/javascript">
         require(["dojo/dom", "dojo/domReady!"], function(dom) {
            var foo = dom.byId("foo");
            var kids = new Array();
            _.each(foo.childNodes, function(node) {
               if (node.id != undefined && node.id != "") {
                  kids.push(node.id);
               }
            });
         });
      </script>
   </body>
</html>

SMS Marketing

On Wednesday I saw Matthew Silk of Waterfall Mobile present on SMS messaging at AMPD (Austin Mobile Professional Developers) which is a meetup.com group that corrals at Capital Factory which is that entrepreneurial services shop at the top of the Omni hotel. Mobile marketing comes in many channels and marketers must consider each of them and then make the tough choices about how to split up budget amongst the pieces of the pie chart. Pie pieces range from old school push stuff to truly exotic cutting edge craziness:

  1. Mobile-friendly HTML5 web sites
  2. Pay-per-click links, banners, and other bits of comparable bait ads also in the HTML5 space
  3. Mobile Native Apps
  4. Mobile-friendly email campaigns
  5. Mobile Messaging (SMS)
  6. Location-tagging (This could be of reacting to your Foursquare interactions or any other geo-location-flavored quirks you might imagine. I once interviewed at 3seventy, a competitor of Waterfall Mobile, and learned that there are some services that one may just opt into that will then periodically poll for your location without your manual check in!)
  7. Interactive Voice Response ("Would you like to subscribe? If so, press 2 now.")
  8. Push (Matthew didn't qualify what shape this takes. It could be any sort of blind campaign where one cannot gauge the positive feedback at the other end of the funnel.)
  9. Passbook (iOS6 devices will let you tie into your banking and make transactions from your phone. Matthew didn't qualify how marketing gimmicks around this new sexiness will work. I imagine that when I pay for Starbucks with my smartphone that Starbucks will get some metrics on me with which to send me discount codes or prod me in other ways.)
  10. MMS (Multimedia messaging, a richer form of SMS which exists viably mostly in Europe and is supported poorly by American technologies and carriers)

Alright, shall we zoom in on the SMS piece of the pie? Matthew's idea of a good outbound SMS campaign looks like this:

  • a potential client gets a new message with
    • content
    • a call to action to text back a few characters to opt in
  • the potential client becomes a client by opting in and then
    • comes some legalize including how they may unsubscribe to opt out
    • the client is asked one follow up question, fishing for another bit of data for building a profile on top of the phone number, geo-location, and carrier data their phone handed back on its own
  • perhaps a thank you message comes here at the end of the process

McDonald's, paranoid of legal problems, apparently undertook a campaign that had a double opt in of sorts in which a user had to clear two hurdles to join instead of one and this ultimately sabotaged their campaign. Funnel metrics showed that only a quarter of those jumping the first hurdle cared enough to jump the second hurdle without getting frustrated or discouraged. Comparably, a user should only be flagged with one follow up question and not dozens. You do not want to alienate your flock. Another way to drive people away is to over message them or to send them off-topic stuff. As much will drive up an unsubscribe rate. The campaign shown in bullets above takes a slightly different shape upfront if one uses a short code:

  • one texts a keyword to a short code and then
    • comes some legalize including how they may unsubscribe to opt out
    • the client is asked one follow up question, fishing for another bit of data for building a profile on top of the phone number, geo-location, and carrier data their phone handed back on its own
  • perhaps a thank you message comes here at the end of the process

shortcodes.com is the sole registrar for short codes in America. All short codes are either five or six digit numbers. They cost about $500 a month to maintain and thus there isn't the sort of short code squatting that one expects with domain name squatting. If you cannot afford one there are short code keepers that allow others to set (rent) keywords on their short code which act as a middleman, ultimately routing to the key holder. An example of how the short code thing works: A man wins an Oscar for the film The Cove and during his acceptance speech he holds up a banner that a million people see on TV which says "text dolphin to 44144" to which there is flood of responses. For this to work, something outside of your cell phone has to prompt you to use your cell phone to join up.

Friday, June 14, 2013

If everything that exists in localStorage and sessionStorage exists in a dictionary with string keys and string values, can you store an object in such locales?

Yes! Put something in:

sessionStorage.setItem("foo", JSON.stringify(myObject));

 
 

Pull it back out:

var foo = JSON.parse(sessionStorage.getItem("foo"));

more regarding destroying views after a promise in a dojo 1.9 dojox/app application

domNode.id will give you the id of the div wrapping the view you just left as suggested here like so:

function doDomCleanup(domNode) {
   alert(domNode.id);
}

dojo/when and promises

I think the dojo/when stuff of Dojo 1.9 shown here does in fact create a promise scenario creating an act to occur when the thing it wraps finishes.

Thursday, June 13, 2013

Find an exact match in Sublime

The double quote icon at the lower left in Sublime will allow you to find a match on an exact phrase in lieu of a possibly also a piece of a bigger string. The icon that looks like an arrow pointing back to its own tail allows one to wrap the document at hand in searching so that one does not have to worry about if one is searching downwards or upwards.

See variable contents in Google Chrome Developer Tools.

While at a breakpoint, if you type the name of a variable in at the Console and press Enter you should get the value.

Create event spies for dojox/app 1.9 transitions.

This problem demanded a solution. We needed a way to act after the app.transitionToView transition defined on line 343 of /lib/dojox/app/main.js ...which reaches into /lib/dojox/app/controllers/Transition.js for a lot of its mechanics where the following is on line 29:

require([this.app.transit || "dojox/css3/transit"], function(t){
   transit = t;
});

 
 

As you can see /lib/dojox/css3/transit.js is ultimately deferred to facilitate the transition, well assuming that the app does not have a transit property, but what if we bolted one on in config.json in the root of our application?

"transit": "foo/transit", ...gets spliced into the file somewhere.

 
 

The "foo" folder holds the application's custom code, including app.js. Rather than write our own way of facilitating transitions, our old module will just be deferred to by our new module. We only introduce a new module in the name of extending the old module. We do not want to alter the code in the dojox stuff directly as that would make it hard to upgrade when version 2.0 rolls out, so instead we have a need to introduce a middleman at /foo/transit.js:

define(["dojox/css3/transit", "dojo/when", "dojo/_base/connect"],
   function(transit, when, connect) {
      return function(from, to, options) {
         var promise = transit(from, to, options);
         when(promise, function() {
            connect.publish("/foo/domTransitionFinished", from);
         });
         return promise;
      };
});

 
 

Above an event will be fired whenever a transition finishes. I can't tell if an asynchronous promise comes back from /lib/dojox/css3/transit.js or if code runs synchronously and locks up the application until the transition is complete, but either way, the /foo/domTransitionFinished event is fired upon completion and then may be consumed in /foo/app.js like so:

connect.subscribe("/foo/domTransitionFinished", doDomCleanup);
function doDomCleanup(domNode) {
   alert('whatever');
}

 
 

For this to work connect has to be added to the app.js AMD module at its top. Clearly, you will moreover want doDomCleanup to do more than fire an alert.

Addendum 6/14/2013: The stuff of the dojo/when when function above should indeed be returning its contents as a promise.

Another Addendum 6/14/2013: domNode.id will give you the id of the div wrapping the view you just left. Think:

function doDomCleanup(domNode) {
   alert(domNode.id);
}

iPhone FaceTime works well for bringing a remote party into a daily stand up meeting!

Try it.

Wednesday, June 12, 2013

Ctrl-Shift-F in Sublime Text 2 will allow for a find across all files in the folder one is working in...

...as opposed to Ctrl-F which just finds against the file at hand. The Ctrl-Shift-F results appear in a new tab titled "Find Results" and one may click results to jump to the files listed as matches.

This might be an example of spying on a dojox/app 1.9 event.

app.on("app-layoutView",
   function(evt){
      alert('whatever');
   });

debugging in Dojo

data-dojo-config in a bootstrapper HTML page for a dojo 1.9 application may contain a debugApp variable which is set to 0 in the absence of debugging an 1 in the name of having more verbose details bubble up to the console in Google Chrome Developer Tools. The data-dojo-config parameter will appear in the script tag calling out for lib/dojo/dojo.js

console.log("foo");

...as a line of JavaScript will put foo as a line in the Console pane within Google Chrome Developer Tools.

I don't know how to really call a callback function from a Dojo transition.

This is wrong. I need a better posting:

app.transitionToView(myNode, myRoute, myMethod(foo,bar));

 
 

...will frustrate you in that myMethod will run before the transistion and not as a callback afterwards. I thought I had to hack around the problem asynchronously, but I don't. Again, this is of dojox/app 1.9. What is above is basically the same as:

app.transitionToView(myNode, myRoute, (function() {
   myMethod(foo,bar)
})());

 
 

...while in the following circumstance the function won't be triggered at all!

app.transitionToView(myNode, myRoute, function() {
   myMethod(foo,bar)
});

 
 

I'll still digging. More soon.

I saw Michael Nero speak on SignalR on Monday.

This was at an Austin .NET User Group meeting. Things that were said that were new to me included the priority that SignalR will give to how it facilitates real time updates:

  1. WebSockets
  2. Server Sent Events
  3. Forever Frame
  4. Long Polling
  5. Short Polling

Short polling, which I had not heard of before, would entail a kludgy means of periodically attempting an asynchronous connection based upon a timer in lieu of holding open a connection via long polling. I also learned that the 1.0 release of SignalR came with the second update for Visual Studio 2012 and that SignalR will respect matching between a camel case JavaScript function name and a Pascal case C# method that is to be its dance partner provided that the names are otherwise the same. There is a respect for JavaScript conventions and not an attempt to force a C# convention into the JavaScript space.

Tuesday, June 11, 2013

shallow copies in both jQuery and Dojo

This had the following image today which suggested that shallow copying in JavaScript entails creating a new pointer to an object or array that already has a pointer as opposed to making a deep copy in which an object (or array I suppose), its contents, and its pointer are all cloned elsewhere to an independent thing that would be unaware of alterations to the original after the point in time of the copy.

Here is a Dojo 1.9 example:

function shallowCopy(from, to) {
   require(["dojo/_base/lang"], function(lang){
      foo[to] = lang.mixin({},foo[from]);
   });
}

 
 

jQuery Shallow copy

var newObject = jQuery.extend({}, oldObject);

 
 

jQuery Deep copy

var newObject = jQuery.extend(true, {}, oldObject);

Destroy a controller's HTML by id in a dojox/app application.

If you are transitioning leftward in a breadcrumb trail and you want to throw away the thing you are pulling back from, you may need to delay doing so until after the transition has run its course (least you sabotage the transition, DOM, and user experience) like so:

function destroyDomNode(view) {
   require(["dojo/request"],
      function(request) {
         request("index.html").then(
            function(){
               setTimeout(function() {
                  require(["dojo/dom-construct"], function(domConstruct){
                     domConstruct.destroy(view);
                  });
               }, 1000);
            }
         );
      });
}

 
 

This assumes index.html is always going to be there. You can also bolt on a fail function. It would sit just after the third to last closing curly bracket and look like so (perhaps):

, function(error){ alert(error); }

 
 

The unneeded call to index.html is a hack. I need to find a better way. (more soon, I hope) This posting assumes Dojo 1.9.

Destroy a DOM element in Dojo 1.9.

Per this the following with do way with a DOM node in Dojo:

require(["dojo/dom-construct"], function(domConstruct){
   domConstruct.destroy("someId");
});

Console Output in Jenkins

If you go to a job in Jenkins and it is red, that means the last build broke. If you click on the build and then click "Console Output" at the left navigation you should get a dump to the screen of what happened.

Karma is a test runner friendly to AngularJS.

See:

See the contents of "Web SQL" databases at the Resources tab within Google Chrome Developer Tools.

You may drill into table rows. It's cool.

See what is in the DOM with Google Chrome Developer Tools at the Elements tab.

Duh.

Earth

Mostly harmless.

I'm hazy on what Cordova is...

I guess it is the engine underlying PhoneGap per...

PhantomJS doesn't use the latest WebKit.

Pain.

RSpec is a convention for BDD-flavored TDD in the Ruby space.

It's ways bleed into the JavaScript space. At my work we are "theming" our own tests comparably.

Sinon.JS is a mocking library for the JavaScript space.

spies, stubs, mocks...

JSDoc provides some sort of canned documentation for JavaScript files I think.

See:

Maven is yet another build tool.

Read more here?

Horizontal scaling versus Vertical scaling

http://en.wikipedia.org/wiki/Scalability suggests that horizontal scaling is of adding more computers to a LAN or servers to an application that fails over across a few servers. Vertical scaling is of beefing up horsepower at a server by adding memory or RAM or something comparable.

Monday, June 10, 2013

Restify is the lightweight version of Express.

I mention Express here. It makes a web server for Node.

_.each and _.find in underscore.js

_.each is for looping and _.find returns the first match:

function dropExtraneousViews(viewsToKeep) {
   var temporaryViews = new Array();
   _.each(app.views, function(name,view) {
      if (view.indexOf(tempMoniker) == 0) {
         temporaryViews.push(view);
      }
   });
   _.each(temporaryViews, function(view) {
      var match = _.find(viewsToKeep, function(keeper) {
         return keeper == view;
      });
      if (match == undefined) {
         delete app.views[view];
      }
   });
}

GRUNT is another JavaScript build tool.

GRUNT is "heavier" than Jake apparently.

Friday, June 7, 2013

Make backups of the files you revert via TortoiseHg.

Right-click on a file and pick: TortoiseHg > Revert Files... ...to revert it. On the confirmation pane which appears you should see a checkbox for "Do not save backup files (*.orig)" and if you toggle this checkbox on and off it will do what you'd expect. Backups are made in the same folders as their counterparts. /this/that.html would be /this/that.html.orig in backup shape.

Jake is a JavaScript build tool that requires Node.

https://github.com/mde/jake has it.

Click events in Dojo are not too tough to master.

I have expanded upon the hello world app I made in Dojo 1.9 here to make the token module I made in the dojo folder named tom.js look like so:

define(["dojo/on", "dojo/dom"], function(on, dom){
   return {
      upfrontMessage: function(id, message){
         var node = dom.byId(id);
         node.innerHTML = message;
      },
      userMessage: function(clickableitem, textfield, id){
         var signal = on(dom.byId(clickableitem), "click", function(){
            var node = dom.byId(id);
            var copy = dom.byId(textfield).value;
            node.innerHTML = copy;
         });
      }
   };
});

 
 

As you can see, the two items in the array to the right of the word "define" populate the two variables in the function. This is how the AMD module stuff works. Then within the define function there is a dictionary of regular functions to which variables may be passed normally. One of them holds the mechanics for a click event while taking in:

  1. the id of a button to consider the clicks for in the DOM
  2. the id of an input field to pull the value from in the DOM
  3. the id of a div in the DOM to put the string pulled from the input field into

Below is the HTML that uses tom.js. You can see it is called in a dojo/tom manner using a route to the module wherein the last bit is the name of the .js file and the preceding bits are the folders to navigate to get there.

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <title>Tutorial: Hello Dojo!</title>
   </head>
   <body>
      <h1 id="status">Loading...</h1>
      <input type="text" id="userinput" />
      <button id="button">Click me</button>
      <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
      <script>
         require(["dojo/tom"], function(myModule){
            myModule.upfrontMessage("status", "Ready!");
         });
         require(["dojo/tom"], function(myModule){
            myModule.userMessage("button", "userinput", "status");
         });
      </script>
   </body>
</html>

 
 

Our app initially writes "Ready!" Into a div's contents and then again rewrites the div's contents whenever a user clicks the token button. What goes into the div upon the click of the button parallels what a user puts into the sole input field. I figured out the Dojo eventing stuff from here.

Thursday, June 6, 2013

The delete keyword in JavaScript...

...is a good way to drop something out of an object type collection (a dictionaryesque JSON-shaped hierarchy with keys and values) and an example is:

delete myCollection[myKey];

Debug a dojox/app controller within Google Chrome Developer Tools.

I'm not sure how the stuff in the Sources tab of Google Chrome Developer Tools is generated. The tree there does not show every file in a topmost folder. Instead, I am betting that links are crawled from an entry point, perhaps main.js in a dojox/app application. This would explains why controllers such as /app/foo/Bar.js are not showing up by default as "foo,Bar" would be called as a route to reach this item and the app would not have a hardcoded reference to this .js file anywhere. I am still too green to these tools to know if you can add a file to the tree at Sources. I could not figure that out. What you can do to hack around the problem is to put...

debugger;

 
 

...in the controller. If your app makes it to that line of code, the controller will suddenly be a part of the file tree and stop at a breakpoint at that line of code within the Sources tab.

F10 in the Google Chrome Developer Tools seems to let you step to the next line of code within the Sources tab.

As mentioned before F8 just takes you to the next breakpoint.

Disable caching in Google Chrome Developer Tools.

There is an icon that looks like a gear at the lower right of the Google Chrome Developer Tools pane. Clicking it brings up a place to tweak some settings. One of the settings a checkbox for "Disable cache" which may make life easier.

something ugly

uglify-js is a minification tool akin to the minification feature in Google Closure, I think.

There are extreme restrictions on the ability of installers to add to the GAC.

Something another coworker mentioned yesterday is that only Microsoft's installers (.msi type files) are really suited to install things in the GAC. If you use a different installer such as NSIS (Nullsoft Scriptable Install System) you will find that the next time a .msi is run that it "cleans up" what the NSIS installation routine added to the GAC.

JavaScript has a strict mode.

This suggests that one may use strict mode in JavaScript by merely using the following in a .js file before any other statements:

"use strict";

 
 

Some of the fun that is strict:

  • You can't reference variables that don't exist. I guess an error will be thrown. (I write this without having used the feature.)
  • breaks in Safari
  • breaks Dojo inheritance

Wednesday, June 5, 2013

Always put the open curly brace on the same line as the thing opening it in JavaScript.

This suggests not doing so comes with pain here and there. An example:

return
{
   id: $item.data('id'),
   text: $item.text()
}

Call a callback function from a Dojo transition.

Addendum 6/12/2013: This posting is bad. See this instead.

A transition in a dojox/app setting might look like this.

app.transitionToView(app.currentView.domNode, options, event);

 
 

In this setting, options.target will have the route path to transition to in it as a string. I mention that as a sidebar. But not to digress, you may bolt on a function to call on the other side of the transition like so:

app.transitionToView(app.currentView.domNode, options, event, myCallback());

 
 

This is also acceptable:

app.transitionToView(app.currentView.domNode, options, myCallback());

Encapsulation exists in JavaScript.

There are not public and private keywords akin to those in C# but you can nest a function within an function making it only accessible from within the function wrapping it. Behold:

function mypublicthing() {
   myprivatething("Hello");
   function myprivatething(greeting) {
      alert(greeting +" World");
   }
}

 
 

I didn't really think encapsulation existed in JavaScript, but a superior pointed out to me that it does exist and recommended JavaScript: The Good Parts by Douglas Crockford as a good read.

Shift-Ctrl-Del in Google Chrome brings up the Clear browsing data... option within the Tools menu.

The pane of options which appears will allow you to destroy your cache.

Tuesday, June 4, 2013

Google Chrome Developer Tools are good for inspecting the JSON within variables.

...at the "Sources" tab...

create a new continuous integration job within Jenkins by copying one that already works

  1. click on "New Job" at the upper left
  2. add a name for the job and click the radio button for "Copy existing job" where you will need to specify the name of the job you are duplicating
  3. click "OK"
  4. you will be taken to a screen full of configurations preset based upon the job you are copying from, and here you will probably want to tweak settings for at least Source Code Management and Email Notification

.shift() like .pop() removes an item from an array in JavaScript.

Where .pop() removes the last item, .shift() however removes the first item. Please note that:

routePieces.shift();

 
 

...would be the appropriate way to update routePieces and not

routePieces = routePieces.shift();

 
 

...which behaves badly.

 
 

Addendum 12/14/2018: The variable assignment above will get the item removed by the .shift() operation I think.

.reverse() in JavaScript

...reverses the order of an array as shown in this w3schools.com example:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.reverse();

 
 

This makes fruits like so:

  1. Mango
  2. Apple
  3. Orange
  4. Banana

 
 

Personally, I'd put the banana first not fourth. It seems like the array was shipshape to begin with.

restify is RESTful routing for Node.js

Maybe look at...

Using __parent in a dojox/app app.

I am trying to feel my way around a dojox/app application and understand it. As suggested here, the contents on config.json end up in a variable called config simply enough, but the existing app I am tinkering with does a lot of its mechanics downstream of the main.js setup in another .js file where a bit of the config variable JSON is referenced. modules within config is exposed, but I want to have at views (both reading from it and writing to it) which sits not within modules but parallel to it within the config hierarchy. A pointer lingers at modules which allows me to reach out to views through a "parent."

app.reopenView = function(domNode, transOpts, evt) {
   var views = app.modules.__parent.views;
   var domain = transOpts.target.split(",")[0];
   var view = transOpts.target.split(",")[1];
   var domainSpecs = _.filter(views, function(a,b) {
      return b == domain;
   })[0];
   var dummyDomain = nameDummyDomain();
   views[dummyDomain] = domainSpecs;
   app.modules.__parent.views[dummyDomain] = domainSpecs;
   transOpts.target = dummyDomain + "," + view;
   app.openView(domNode, transOpts, evt);
};

 
 

This doesn't make any sense to me as of yet. I'll let you know when it does. How is this state hanging out?

 
 

Note: Having just written this, I now realize that I am a moron. app.views is available just as app.modules.__parent.views is. Duh. Mystery solved.

 
 

Addendum: OK, now I have had a peer review and it has been pointed out to me that I did not need to use underscore.js whatsoever and that the line using it could just read as:
var domainSpecs = views[domain];

 
 

Duh.

Monday, June 3, 2013

The split/join way to "replace all" in JavaScript.

var foo = bar.replace('baz','qux'); is painful because only the first instance of baz within bar is going to be replaced with qux. If bar contains "this foo bar stuff is fubared" then foo will end up reading "this foo qux stuff is fubared" and not "this foo qux stuff is fuquxed" which might be desired. A good way to replace ALL instances on the left side with a right side counterpart looks like this:

function nameDummyDomain() {
   var dummyDomain = "temp" + new Date();
   dummyDomain = dummyDomain.split("(")[0];
   dummyDomain = dummyDomain.split(' ').join('');
   dummyDomain = dummyDomain.split(':').join('');
   dummyDomain = dummyDomain.split('-').join('');
   return dummyDomain;
}

Random notes on the dojox framework.

  • This is some documentation.
  • This touches on dojox/app which consumes the config file.
  • I believe that dojox/app may spin up like so:
    require(["dojox/app/main", "dojox/json/ref", "dojo/text!./config.json"],
       function(Application, json, config){

    ...and calling it like this...
    require(["./main.js"], function(){});
    ...then the three items in require populate the three variables in the function signature. The last of the require items drinks up the contents of config.json.
  • dojo/sniff is for browser detection
  • dojo/text looks cool too

See what is in Local/Session Storage within the Google Chrome Developer Tools.

  1. Go to the "Resources" tab.
  2. Expand "Local Storage" or "Session Storage."
  3. Click on an applicable site to see a dictionary of all the values tucked away for that site.

Sunday, June 2, 2013