Thursday, October 31, 2013

"enterprising" the free

Here is an idea for a business model:

  1. take a piece of open source software that everyone in consulting uses and loves
  2. dress it up some with your own shim of extensions so that you may call the new thing (the free thing with your tweaks bolted on) a commercial product
  3. put a helpdesk in front of it so that your commercial software may become enterprise software
  4. start selling support engagements

What? You don't think that is a good business model? Well, that seems to be the business model of both StrongLoop and Datical as best as I can tell! That is correct, not one but at least two Austin-based ventures are doing this. How can this possibly work? Why wouldn't an enterprise just use the free version? The answer is that enterprises hate free stuff as they fear there will be no one around to support it. They need to be able to call someone in the middle of the night when things go South. They are all about engaging with vendors for IT solutions.

Bubbling copy/paste-friendly gunk up to smartphones in HTML5 applications.

When surfacing something that needs to be copy/paste-friendly from within the bowels of your application, why not use a textarea control as suggested here and make its copy automatically selected with JavaScript like this?

textarea.focus();
textarea.selectionStart = 0;
textarea.selectionEnd = textarea.value.length;

 
 

I hope this approach will prove iPhone-friendly. I'm not certain as of yet.

 
 

Addendum 11/1/2013: It didn't work. :(

When calling a file that is not a .js file via the AMD convention...

...you need you specify the extension, such as .html.

Manipulate CSS styles in Dojo!

"Up top" we have...

define([
   "dojo/dom",
   "dojo/dom-style"
], function(dom, domStyle){

 
 

"Down below" we have...

var textarea = dom.byId("whatever");
domStyle.set(textarea, "width", "100%");
domStyle.set(textarea, "height", "300px");
textarea.innerHTML = text;

swapping dates as strings from local to UTC time with moment.js

Cast a local time date in a military-time/nothing-but-digits-and-dividers/alphabetical-order-friendly string format to a UTC time military-time/nothing-but-digits-and-dividers/alphabetical-order-friendly string format:

var localString = "1974-8-24 06:13:13";
var pointInTime = moment.utc(localString);
var formattedTime = pointInTime.format('YYYY-MM-D HH:mm:ss');

 
 

Cast a UTC time date in a military-time/nothing-but-digits-and-dividers/alphabetical-order-friendly string format to a local time military-time/nothing-but-digits-and-dividers/alphabetical-order-friendly string format:

var utcString = "1974-8-24 06:13:13 GMT";
var pointInTime = moment(utcString);
pointInTime.local();
var formattedTime = pointInTime.format('YYYY-MM-D HH:mm:ss');

 
 

Using "UTC" in place of "GMT" above seems to work just fine too.

Datical DB

I saw a Mr. Pete Pickerill of Datical speak on Datical DB which is built on top of an open source piece of software called Liquibase and felt a lot like a different, comparable open source piece of software I've used called The Tarantino Project. Datical DB is not free however, it is enterprise software. As with Tarantino, a schema gets an extra table that keeps track of what scripts have been run against a given instance of a database so that a continuous integration process may update the database with just the lacking scripts as kept in source code. Tarantino uses raw SQL while Datical has an XML abstraction. Tarantino is for MSSQL while MSSQL, Oracle, mySQL, PostgreSQL, and IBM's DB2 all jive with Datical's stuff which also has a GUI and a "Forecast" feature that warns us when we are doing something like truncating a field will which sabotage existing data. The talk was an Agile Austin special interest group thing held at Bazaarvoice. A Mr. Carey Benge of Datical also spoke and emphasized the need to keep scripts small and atomic in database change management implementations.

the objects moment.js makes are not JavaScript date objects

Cast them back to plain Jane dates like so:

var lastHalloween = moment().subtract('year', 1).toDate();

nesting an AMD module within a regular library and giving it a virtual path to be called by

define('ourFakeFolder/ourFakeFile',[
   "whereWeKeepUnderscore/underscore",
   "whereWeKeepMoment/moment"
], function (
   _,
   moment
   ) {

 
 

In order for this to work, you need to be absorbing the file this sits inside of somehow. If there are other dependencies for this, I do not know what they are yet.

Wednesday, October 30, 2013

spy!

The NSA (National Security Agency) as part of a project called MUSCULAR has been "intercepting traffic between our data centers" to have at the data of Google and Yahoo without the blessing of either entity! See the link. I went to an Agile Austin talk today and when the host asked: "Are there any other announcements?" ...this came out!

Am I wrong about this?

I have heard... that you need a Mac account to get software installed on a Mac. The you make a legitmate installer with the Mac account and it will be either a .manifest or maybe a .ipass. I do not know about this first hand as I hate Macintosh.

Tuesday, October 29, 2013

dojo/_base/lang!

If "dojo/_base/lang" is defined as "lang" then...


myArray.forEach(lang.hitch(this, function(itemInMyArray) {
   alert(this.whatever + itemInMyArray);
}));

 
 

...inserts the scope of "this" from outside of the function into the function in a manner that is more or less equal to something like so:

var self = this;
myArray.forEach(function(itemInMyArray) {
   alert(self.whatever + itemInMyArray);
});

Xamarin lets you write C# code which may be compiled to native code at iPhones and Androids.

Microsoft's Xamarin Studio is to C# what Appcelerator's Titanium is to JavaScript. Oh, you may also write C# for Windows Phone, so it covers three platforms where Titanium straddles two. No one cares about BlackBerry.

Monday, October 28, 2013

of acronym ambiguity

This suggests that POJ (Plain Old JavaScript) is the acronym du jour when trying to articulate Plain Old JSON Object as POJO is an acronym for Plain Old Java Object. That said, I see plenty of examples of POJO being used in such a way to suggest the J does not stand for Java.

Sunday, October 27, 2013

metatag redirect

<meta http-equiv="refresh" content="1; url=http://example.com/">

...the perfect way to abuse myspace HTML comments in 2005.

CDN stands for content delivery network

...I am stealing directly from Wikipedia to offer: A content delivery network or content distribution network (CDN) is a large distributed system of servers deployed in multiple data centers across the Internet. The goal of a CDN is to serve content to end-users with high availability and high performance. CDNs serve a large fraction of the Internet content today, including web objects (text, graphics and scripts), downloadable objects (media files, software, documents), applications (e-commerce, portals), live streaming media, on-demand streaming media, and social networks.

Saturday, October 26, 2013

braindump of FubuMVC vNext as hosted by Jeremy Miller at Pablo's Fiesta in room 105

I can't tell if this a real end of the day Session or not, but I think I'm just gonna go home.

braindump of making EF (Entity Framework) Suck Less as hosted by Tim Rayburn at Pablo's Fiesta in room 105

Tim askes if anyone is doing test driven with EF. Tim has made expansions on top of EF to make it more testable. Highway Framework is a framework ontop of Entity Framework that makes it suck less. Tim every ORM that has every existed is drying to map a row in a table to an object that is a hodgepodge of behavior and state and this is comparing apples to oranges. There are some common things to do in an ORM - create read update and delete. Do separation between repo and unit of work. Tim prefers to call "code first" "code centric" ---he feels that in C# he will want to use C# as the primary point of definition and not a SQL schema. Unit testing is important to Tim and EF falls down in this regard he feels. He feels testability really kills things. EF6 just dropped. The definition of a DbContext shows that it will return a DbSet of T which will be hard to mock. Tim believes one of the greatest evils in recent years is Queryable. Everyone knows not to bury SQL strings in code, but somehow Queryable is OK? Not so much. Queryable is not read only it can be modified at the ORM itself. Having get person by Id in your code base based on Queryable you will have code sprinkled about that will require multiple changeups to fix. Tim is using Code Rush in his presentation. Visual Studio 2013 will have the grey word reference appearing over method signatures which you may mouse over to see references! public ICollection<Tasks> Tasks { get; set; } is an example of specifying a collection from a parent in the code first core classes. Database.SetInitializer(new DropCreateDatabaseAlways<... is yet more EF code. DataContext is a common abstraction over working with different underlying types of data. IDataContext implements IDisposable. IEventManager is something for intercepting transactions for AOP stuff. Tim has way to hand stuff to IDataContext for mocking and let IQueryable hand it back when chained onto it. Tim is coding in front of his audience and making Queryable stuff. All closures are passed by reference in C#. I can't follow the talk. Either it's late in the day and I'm tired or it's just really deep and complicated. I'm not sure. Tim doesn't remember how to insert into an row with one auto incrementing column and no other columns. He is doing some magic to downcast IQueryable to IEnumerable so that where clauses off happen in memory. He has a way to pop off the query behind an IQueryable to a string so that you may test it. I'm starting to space out.

braindump of Node.JS as hosted by Mike O'Brien (spelling?) at Pablo's Fiesta in room 107

Gabe: what is the most compelling reason to run Node at server? Guy in black hat: you can use JavaScript at both frontend and backend. Mike: package manager has just about anything you can imagine. Gabe: how is it if you have 100,ooo+ lines of JavaScript. Worries about bug hunting in a dynamic language. Guy in black hat feels that Ruby has already been proven as a good front end language and doesn't feel dynamic must be a deal breaker. Mike agrees there are a lot of benefits to using a strongly typed language. guy in black: compiler can be a wonderful thing but no matter what you will write JavaScript in our business and then you might as well extend into writing JavaScript that isn't bad. Mike: play around with in a small case to see how it works. Node is a single thread but you have libraries written in C or C++ which do different things it can reach out to. There is an event loop that goes around and around. You don't want anything to stop the event loop do you need to use good judgement as to what you should use node for. Something synchronous is not a good example. Anything that is blocking will be done asynchronously. One code hitting an event loop firing off threads is node. Node can catch an input and hand it off to another library on a different thread, but largely there are not threads. Gage: You would expect the modules to do everything one thread? Guy in black hat: you'd call a module asynchronously and eventually call back into another loop. He suspects the breakaway and back here happens on different thread, but the main looping thread is the consistent one thread. Mike: you can run node on almost any operating system. Guy in black hat: it uses the V8 engine. Guy in purple sweater: the asynchronous happenings are not long lived. The do their thing and then reconcile with main thread. var http = require("http"), url = require("url"); http.createServer(function(req, res) { res.writeHead(200, { .... is an example of spinning up a server. Mike feels setting up a server is easier if you use a library like Express. Mike: everything you do has to quick. If you are going to do something that takes a while you are going to kill the server and a different technology where one may have threads at the server will likely be superior. Mike: make a connection, make a map reduce call, send event back to client, close the connection. Express cuts down on the amount of boilerplate code one has to write. Express handle a lot of URL stuff. Black hat: the first thing I'd do is write MVC-data binders for requests. The blink tag doesn't work anymore. Guy in glasses: Express can also handle rendering views. You can set up Express and tell it where to look for templates. Black hat: payoff in Node is promising. Wants to know how all the parts word. Purple sweater: RESTful API requests would happen at the client outside of Node code. Guy in black hat is explaining model binding in MVC. Guy in purple sweater: If you are using Mongo you could pass in JSON object directly to be a Mongo object. Gabe: don't use a hammer for screws. JavaScript is not ASP.NET MVC. Guy in black hat asks about frameworks on top of express. Guy in green shirt mentions Sails which is like "Rails" guy in black shirt: if you do SQL you may use some kind of dynamic SQL. npm is the node package manager. Gabe: all the cool guys are on NodeJS, what happened to Ruby? How many of us still develop in Ruby? No one put their hand up. Tessel is a board that will allow you to run JavaScript at it. Black hat: you have so much rope to hang yourself by in JavaScript. Second guy in glasses: Node.JS is very big in streams. Guy in black hat: is the code you write in node akin to the clientside stuff? Second guy in glasses mentions AMD/require is used in Node. You can do jQuery on the server which is pretty cool. You can use it for screen scraping. Make a request, get it back, crawl it with JavaScript. Podcast called NodeUp is good. There are good walk through for stream (stream of events) stuff which emits and accepts events. you can make five or six different string objects and "pipe to them" ... He has seen request.body handed to a JSON parser stream where it is read in chunks. Hand chunks into multiplier or persister to do processing on it. Black hat: in a fluent interface in C# you may dot (.) to different things but it's not timed based. Wonders if there is a security story around Node authentication. Second guy in glasses: There can be middleware which "turtles down" objects passed through it for security validation to Node. Jade and Passport are middleware examples. All of his Jade templates may be requested directly. Guy in black hat: Seems like a wide open environment. Is there any documentation on how to get started? Second guy in glasses: Groupon has moved to Node. Groupon showed off a EngineX app with Plural plugins at a talk he saw. Guy in black hat thinks LinkedIn is on node. Nolan Egly says: Thank you ...and we are done.

braindump of Toxic Teams and Expert Beginners as hosted by Keith Dahlby at Pablo's Fiesta in room 106

Keith suggests we don't as an industry think we don't talk about the things that effect us enough. With healthcare.gov the big government culture was likely not helpful. healthcare.gov is a buggy mess. Keith was part of a team of ten acquired by a team of thirty and ended up quiting within a month. He has gone back to contract for the big team keeping old systems on life support. The Dreyfus model of skill acquisition: you start as a beginner, you become an advanced beginner, then you become competent, then a rate of skill acquisition starts to decline. Eventually "proficient" and "expect" lie ahead in the Dreyfus model. There is the danger of moving from advanced beginner into expect beginner from which there is no path forward. A bad environment can make you take this fork in your development which puts you into pit. "Eric" per Keith (who?) suggests that if you bowl without putting your fingers in the ball at top out around 160... at first it may seem like this is OK when no one else does better in your small town. However when you go to teach someone else your teaching may be poisonous. The first developer at a company may turn into the first developer lead at a company and then teach poison downwards in a situation where others may be forced to go along. This sort of thing forced Keith to leave his job. What can we do if you're told to fall in line or get out of the way. Guy in grey shirt: try to demonstrate that things can be better. Guy in blue shirt: feels you need to prove it on your own. Guy in black shirt: a job creates isolation for you, a great first job should not be stayed at past a three year mark because you will become stagnated within the management style there. Keith: you don't want to be the smartest person in the room. It is good to have a culture where everyone in Austin has to go to an event. Guy in black shirt: a lot of people would not go to a Saturday event as we are now. He feels a company cannot push employees to do this stuff. Guy in yellow shirt: think about the horrible experience of making the apathetic nine-to-fivers managers. Grrr. Keith: the laws of physics are not fixed in our industry. Guy in black shirt: if your first job taught you web forms, it will eventually time to learn MVC. Guy in orange shirt: deals with corporation programmers keep limited scope to their knowledge and don't want to grow. He keeps trying at work and being fought. Black shirt: hierarchy of pain 1. character (people who don't perform. 2. ??? 3. ??? 4th item is "tech" Keith: expert beginners think they have climbed a ladder and know it all. Guy next to me: thinks fear drives individuals to not grow. Fear of failure. You have to let people. Patrick Lioi suggested it is good to make sure the learner in that situation does not have the head trash of thinking their the novice it in the room and you have to be sensitive to it. Black shirt: the fear of climbing a the painful mountain of learning a new language or framework is driven by the experience of how painful it once was. Improving makes interviewers ask questions until the candidate says I don't know. One of the worst things you can do as a consultant is to lie to a client do Improving makes you learn to say I don't know. Guy in blue shirt: said saying I don't know is a lot like taking issue of you problems in an addiction control group therapy session. Girl in purple shirt: you are going to have a lot of growth when you put yourself in a position where you are uncomfortable. Keith: when you start to feel your imposter, that's when you have passed beginner to competent. My phone is dying. I think I'm going to duck out of this and find my charger.

braindump of Blogging Workshop (Frustrated? Curious? Looking for ideas & suggestions? Come talk to an editor!) as hosted by Chris Massey at Pablo's Fiesta in room 103

Kevin Miller has been blogging at his company's blog quite a bit. Kevin doesn't finds it fulfilling and feels like he is writing documentation for future self. He is interested in blogging not of work but struggles to find "traction" with his ideas. Chris Massey has five lies of blogging and three how tos. Another guy at Kevin's right gave up on blogging at some point. He did create a mailing list for other programmers to make ideas exchanges and he found that more rewarding. Guy at my left dabbles in blogging. He started a specific topic and did thirty or forty postings and doesn't know what to do next. Chris Massey is going around the room. Next guy is vaguely interested. Next guy started writing a post and then asked himself "who really cares what I have to say" - Chris suggests this is the most common thing to blocking others. The Internet is a really big place. Next guy asked "how do you keep the ball rolling so it is a common thing to do" -Next guy frustrated by spam at comments and looks to a lack of legitimate comments as a lack of legitimate feedback. Next guy struggles with scope and how to jam an idea into something that may be articulated in a few hours in lieu of a novelette. Last guy is interested in SEO and ranking for long-tail-searches. Chris Massey is to go throw five lies: 1. is easy - takes discipline 2. it's hard - it's not it's just words on the Internet 3. I've got nothing interesting to say - 4. "What's the point?" what am I going to get out of it. Perhaps for a tech blog you can pull an audience in.  5. I can't write. Writing isn't necessarily easy. It's like coding. You can learn to reformat things. Like coding, you will get better at writing the more you do it. Three rules: 1. What am I saying? 2. Why am I saying it? 3. Who am I saying it to? If I discovered a particularly nasty gotcha in a CI script who and I broadcasting a fix to? Do you in scope give links out to prerequisite knowledge or bake all prerequisite knowledge into the blog posting. Who are you writing for and why will define scope. Who are you writing for is another issue and writing for future self versus others should be determined. Cadence and discipline is important. Maybe you should write a post every two weeks without worrying if it's good. If you're not sure of what you want to say... do associative writing and just put words on the page and see what falls out. Don't be paralyzed by indecision. SEO interest guy says the comments should drive what the next blog post should be! Chris suggests the guy at my left should ask himself what he wants to get out of the 20 or 30 posts he wrote on a tabletop game and abandoned. He got started on a community site where there were a lot of other gamers. He had an itch at the time to explain a rule system that had a lot of possible interpretations. Chris, don't try to force a blog posting. This leads to apathy and burnout. Chris asks the guy at my left, did you enjoy the act of writing. Chris feels the guy at my right could try to fork into other game-related subject matter. Kevin wants to hone his ability to persuade. The guy to my left was informed in his first effort by a strong knowledge of what he wanted to write. Chris thinks its important to have some consistent theme on a blog. Don't write about something you don't care about. Kevin wants to find a nontechnical topic to blog off in the name of a worklife balance. People don't expect a manicured treatise. Haters are gonna hate. You're always going to find someone who will take a swing at you. Chris suggests turning off comments if you are ruffled by negative comments. Guy at Kevin's right has expressed an opinion such as Microsoft hasn't innovated in ten years and has people point at some one small thing that undermines his bigger point. Chris says this is called bikeshedding. Guy at my left likes the ribbon bar in Microsoft's design such as that of SharePoint and Outlook. Chris suggests that out should try not to care too much when someone disagrees with them. The one guy who disagreed with you is perhaps not representative. Guy at my left suggested that posts should be crafted as discussion starters, example: How much has Microsoft innovated in the last ten years? Chris prefers the informative voice to the discussion voice. Couch opinions as opinions. Bad code and bad writing isn't a problem but being defensive and not acknowledging it is. Professional actors acknowledge stage fright. We are all weak in our ways. See if you can acknowledge it publicly. Chris suggests that the intention to blog puts you ahead already of the vast majority of peeps in terms progress. Not even Scott Hanselman has your connect, others may have said similar things but yours really is yours. Your collection and presentation of ideas is unique. Different people have different topics. Do not underestimate yourself. 

braindump of What is your Passion as hosted by Ryan Joy at Pablo's Fiesta in room 103

Derick Bailey says that he spends his days blogging and getting paid for it. Ryan: on second Tuesday of november there will be a talk on why one will be a tech evangelist. "Anne Epstein" says that it is sort of a Headspring thing that people go to conferences and brown bags. There are few people in the room... we are getting started though. Ryan: When going to open conferences in the past he always hears about passions outside of tech. He is into photography, whiskey, robotics... he owns a boat. He eats directly out of his fridge and loves cooking. Derick: +1 to Whiskey. He says Balconies Whiskey from Waco is good. He loves code electronics, blogging. Another guy asks about Derick's blogging. Derick has never given me grief about how much he blogs. Guy in blue shirt doesn't like ranting over blogs. Anne blogged a lot more when she had a terrible blog. Derick tries to maintain a positive persona when he blogs. Guy in blue shirt mentions putting in new floor in home. Ryan asserts that such home projects are a passion. Guy in blue shirt mentions that his attention goes in different directions. He mentioned a time when another asked him for help with a computer that had a bad hard drive. He advised them to slowly migrate data to another computer. This got him interested in getting an A+ certification. His passion ultimately is learning. Anne is renovating a property she rents via YouTube movies. She is into ballroom dancing and asserts its heavily expensive when you consider lessons, airline tickets for yourself and another. Guy in grey hat is passionate about family and Bible ministry. He is also interested in robotics. Marshal is the name of the guy in the hat. Do/while/foreach/dowhile are examples of loops. Ryan some people are just bad interviewers. He has pushed people about encapsulation and had then struggle to articulate it when he knows they use it. Guy who lives in the middle of nowhere likes home brewing and HAM radio. Instead of having hardware components that tune to signal you can now do that in software. We've started talking about tweeting in morse code. Guy who lives in the middle of nowhere wants to get into robotic prosthetics and 3D printing is apparently helping amputees build their limbs. Guy with grey ponytail likes music. He started on trumpet when he was eight and he is on piano now. Music eats his disposable income and money goes into recording gear. He is 52. In his forties he did martial arts. He likes genealogy too. He wanted an escape from technology. Sharon Chichelli (spelling?) asked him about eventual travel. I could find acting again perhaps. Guy with grey ponytail mentions the Austin film society. We talked about dungeons and dragons some. Another guy suggests dance classes. He suggests you hold a character when you dance. All of Ryan's passions are analytical. With photography and cooking it is very much a self taught type thing. (as is code) Ryan sometimes goes to photography meetups and picks their brains about other meetings. Sharon likes pinball. She says its cool electronics. She has been under the hood of a pinball machine. She took a class at Laguna Gloria. She revisited ink bottle and "gum" erasers. Derick mentions "drawing on the right side of your brain/mind" a book. He bemoans his long art takes. He designs logos for open source projects. Inkscape is software he uses. "Paper" for the iPad is an app he uses to draw. He is pulling up some illustrations. He had drawn a snail with a jetpack. He made a series images for a screen cast that were to compare HTTP requests to an airport. Eric Hexter has played drums since 3rd grade. He loves metal (music). He is into robotics. He plays drums at his church. He wrote a program to help his daughter to win a conch in a school contest. Paul Herrea (spelling?) is a drummer too. He has played professional for a year and it sabotaged his passion. He wonders of he loved playing music or being on stage. He was in a cover band. Guy in purple converse with accident: speaks to passions that have irregular hours like being a chef or being a musician. Paul thinks its more fun to be in the audience than onstage. Ryan is recapping the hobbies listed so far. He thinks everyone in the group shares learning/teaching. Guy in purple shoes mentions gaming. Sharon: if you are drawing cards off a deck of cards the future is knowable, not so with dice. Ryan asserts that this is why California allows blackjack gambling but not craps gambling. Guy is purple shoes likes "pulling things back" and asking why is it this way. Guy in middle of nowhere: we destroy reality by categorizations into language. Derick: read Neil Stevenson's Snowcraft staring Hero Protagonist. Guy with ponytail: Diana doytche (spelling?) suggested that people develop filters for languages and learn moreso in Vietnam and China to have perfect pitch. Guy in sneakers: think of birdsong and the way animals communicate and he asserts music is the beginning of language. Guy from nowhere: they have taught dolphins to play specific games with whistles. Each dolphin had its own whistle as though a whistle corresponds to names. Ryan is a news and information junkie. Ryan puts on Bloomberg podcasts when he codes. The room erupts in a "how can you do that?" chorus. Ryan starts the day drinking coffee and ends the day drinking coffee. He loves twitter streams a tweekdeck. Purple converse guy will accidentally type things he hears while working. Ryan said that he is over the need to listen to everything in an information stream. Sharon challenges Ryan to medicate for a minute without multitasking. It's lunchtime. We are ending.

braindump of Script Loading, AMD and SPA (Single Page Applications) as hosted by Ryan Vice at Pablo's Fiesta in room 104

Ryan: We haven't seen any fantastic approaches out in wild when loading JavaScript in single pages apps. We wants feedback from others. Amir Rajan: console.log will break IE8! Ryan: If you bootstrap a SPA, can you create an abstract factory and have require.js hand you dependencies. How do we delay load from bootstrap time. Kevin Miller: Calling require outright will allow you to delay a call to another piece until you need it. Guy in grey sweater: Not all of your models need to be declarative. Amir: Separate a SPA into small spas. Load dependencies per view, this also prevents memory leaks. Kevin: Intercept clicks on links in a multiple-SPA-within-SPA app to keep links from going back to the server. Grey sweater guy: You throw away some minification when you call require directly in lieu of at the bootstrapping. A guy named Gabe: Calling under this condition this and other this other condition that can become a mess. Jeremy Miller: think of this logic as a proxy in lieu of a service locator. Ryan: As long as you have the service locator in an abstract library you will not have an antipattern. Jeremy Miller: The value to do composition upfront is valuable. If you use service locator you are making your class have a hard dependency that is hard to test. Dependency injection is the way to go and Angular is building this way. Ryan: In the multiple SPA approaches you release memory when you change SPAs. Amir: A Dom element clinging to a delegate is the source for memory leaks he's seen. Alot of his memory issues is in IE8 and IE7 and Angular is weak in this regard. Ryan: Let's switch topics to whether or not using AMD patterns to create reusable stuff is worth doing. Guy in pink shirt (Jonathan Mateos?) is saying that you have to know when it's useful instead of just using it out of the gate. Amir: Pulling in as if a namespace call window.module.something to call in globals. Create a JSON object that has functions and has no state. Where AngularJS and those services shine is when they deliver their own components not home- rolled components. Pink shirt guy: Don't prematurely optimize for AMD. Guy is glasses: Spinning up AMD for mobile is expensive! Pink shirt guy: Minification combined with concatenation (just reach to dependencies synchronously) is a good way to go until you really need asynchronous loading. Guy in glasses: AMD is a lot of complexity. Pink shirt guy: Trying to get require to work with nonAMD-friendly stuff is rough. Amir: Node.js uses a different means for managing modules. Pink shirt guy: Angular manages code organization and this there is little reason to drag in AMD. Guy with glasses: in browserify you use require statements in the browser for your requirements. Ryan Node: it was origanally for running node modules in the browser. Gabe: heard angular breaks down in using requirejs when you scale it up. Amir: Is AMD good for using underscore, moment, etc. and wonders if leaving more esoteric stuff to another means. Guy in grey sweater: if you don't load jQuery via AMD then modules that need it are going to fail. He thinks you should either embrace require or not use it. It's small modules maintaining small fine grain scripts that do things makes troubleshooting easy. Grey sweater guy doesn't love ko.observable. He likes that knockout is a grid of observable items. Amir: For client side caching, at Web.config a Guid drives versioning of .js files and leaves it to browsers to cache it. Grey sweater guy asserts that Amir is using caching based on a Guid in the URL string and is just changing it out to jog a reversioning refresh. Amir: AWD CNDs are used in his app. Amazon has a CND offering. Guy behind me: You can also use cloud flare for hosting static images and the like. Gabe: how do you handle disposing of resources? Amir: do memory profiling and keep spas small. Grey sweater guy: chrome profiling tools are really beneficial for this. Kevin: had small amount of leaks for backbone and marionette cleaned up problem. Guy in glasses says Angular is much less leaky than backbone. Amir: Anytime you show or hide elements things can get leaky. If you delete a DOM element and a class is still around and you reload the KO.observable you may have trouble. Gabe: is there a difference in intranet versus internet apps? Guy with glasses uses the I'm on dialup sanity checking on Fiddler. Don't expect to get under 100 milliseconds on a phone because it takes a while for a phone to spin up a ping outwards. You are ahead to make massive apps that require a big download. Ryan: you are requiring a certain amount of battery time Everytime you make a request. guy in glasses: Google will make six requests per domain outwards when in loading. Asks is anyone doing end to end testing and others mention. I ask about dirty checking. Amir: Angular has scope. An event loop sees if an object has changes. If an object is dirty (changed) then an event happens. KO.observable drives this in backbone. We seem to be done.

braindump of Love it or Leave it JavaScript Frameworks as hosted by Ryan Vice at Pablo's Fiesta in room 104 which is jointly a session hosted by Derick Bailey called Backbone vs Angular vs Ember

Derick was Durango is what Knockout should have been as it brings in Require.js. Derick's Marionette framework sits ontop of Backbone. Guy in black hat: There are two different camps people who like to poop on HTML and those who want to write JavaScript apps. Ryan Vice is asking who has worked with what Frameworks. Ryan says a negative in Knockout is negative syntax based on proxies. In your models you have to wrap everything in proxies. He feels it is not fair to compare it to Angular and Ember as it is a microframework but Durangal brings it on par. Amir Rajan mentions painpoints and says Angluar feels like a better Knockout while Ember feels like a better Backbone. Derick, said the Ember people looked at Backbone and found user hated how verbose it is. An Ember guy was a Ruby on Rails guy and made Ember also stay "on rails" - Ember is phenomenal at large scale while Backbone is phenomenal at scalable - you do have to bring in larger constructs like Marionette or Chapel. Amir: Be aware that Ember and Ember data (for getting data) are two different things. Another guy in a github shirt: most frameworks are not very dictatorial about how you connect to the server. Amir: if you start with Backbone it feels natural going to Ember. Derick: There are two kinds of scalability, scaling out to a large number of users, scaling out features. Amir: two different backbone apps will look very different. Guy in black hat: does not like being told what to do, we likes to use his own pieces and fail horribly. Guy in tan clothes: Also doesn't like being locked in and constrained as is the case in Silverlight. Ryan: Outside of the documentation provided how much conversations and informal documentation is provided. Black hat guy bemoans view models in MVC and a second set of models in a JS framework. He is explaining his ways around the trouble... he feels it helps not to have Backbone view models for this which are too heavy. He uses KO.mapping. Ryan: Could not find an easy way to pull things out of the mapper. Black hat guy: You should send your view model up properly defined so that you don't have to mess with it on the frontend. Gabe is the guy who didn't want to be locked in and Derick asserts that is just the way it is. Your team has to embrace a core framework. Around the edges, beyond the core, there is more wiggleroom. Pick a framework your team can embrace. Ryan: Single page apps are becoming what smart client apps once were. Github shirt guy: Silverlight and Kendo lock you in but Angular will have forks. Ryan: Is it a good idea to create seams for loose coupling. Derick at github shirt guy say no as there is a performance hit. Dirty Checking in Angular (ectmascript, spelling?) has not yet shown to be a performance. Derick: you'd better virtual information on a phone app for virtual scrolling, dropping stuff as you load stuff from a long list. Amir: backbone is easy to jump to from spaghetti jQuery. Backbone to backbone marionette is the next step up and going to backbone marionette is the step to the top of scope. Ember is opinionated and makes you do dirty checking the right way. Guy in black hat introduced the Backbone view. He made every page have a convention and got his team used to writing code in a particular way. Amir: scoping feature in Angular is manipulatable you may specify... this Dom node is a view, this Dom node is a view.. Derick: Backbone.view should really be called Backbone.presenter. Guy in black hat: will refactor to that and hates the amibuigity of term view. Amir: I'm putting my weight behind Angular. Ryan: If you need a lot of resources in the future you may like Angular given all the meetups in town. There is a question about converting apps to a modern JS app. Jimmy Bogard assert that the gentleman who asked the question is on Silverlight and will have pain regardless in any migration scenario. Gabe uses a MVVM pattern. He does not use Silverlight patterns. Derick someone with a history of Silverlight might be comfortable with Durangal. Gabe is ambivalent about Google and wonders if it will be a big evil like Microsoft. Amir: AngularUI is another good piece if you are doing Angular. amirrajan.github.com/oak#peeps is a sample app comparing the frameworks and it has ASP.NET MVC and server side. Github guy: Breeze.js is a crud framework now integrated with Angular. Ryan: Breeze is like NHibernate in your browser. Derick: Breeze really shines when you need all of your data pulled up to the UI. Amir: You can have implied business logic in the links you return in Breeze. Guy in black hat: How do we decouple HTML and CSS from JS? Are all of  the data binding frameworks friendly to this? Derick: Angular is bad at this. Ryan: Google is aligning itself for web components which is a spec that will trend in the future. Derick: If you are not building components you are building a spaghetti mess. Derick: You're not going to find any framework that doesn't have an HTML handing problem. The JS code will want something from your HTML in terms of formatting. Ember uses handlebars and handlebar helpers. Each handlebar template is going to have some looping logic which may be a bit dirty. Amir: Returns MVC Razor and then has JavaScript come in an dress it up based on HTML tags. Your Razor page is basically an HTML page with a .cshtml content. EmberJS has a precomipled thing which is supposed to be SEO friendly. Derick: there are services that crawl JS and make HTML content for Google to find of you point it there. Amir: microformat2 is a format that also helps with SEO. Another gentleman asks about testing. Amir: We tried to use Jasmine but the DOM is nasty. Do it at a higher level with Selenium. Don't mock you DOM. Guy in black hat: Uses knockout to totally abstract the DOM away. Another guy yet: Has been using Angular directives and has been attaching them to the DOM. Karma used to be testacular which sounds bad. Karma is a test runner for Angular. Browser uses socketIO to connect to the server. 

Bumblebees bounce.

Pablo's Fiesta is an Open Spaces conference that is going on this weekend. The kick-off was yesterday evening. I learned that "bumblebees" bounce from one session to another while "butterflies" sit quietly by themselves and wait for others to engage with them or leave them be.

Thursday, October 24, 2013

go to chrome://settings/cookies in Google Chrome to delete cookies for particular domains

As much is the way to throw away a Web SQL database.

It's kinda cool that a string may be false in JavaScript.

var error = whatever.sanityCheckFormFields(foo, bar, baz);
if(!error) {
   whatever.saveRecord(foo, bar, baz);
} else {
   alert(error);
}

Keep a number type HTML field from incrementing into negative numbers.

<input type="number" min="0">

...has the magic. Note the "min" setting.

Mass Relevance

When CNN shows tweets on TV they are likely filtered by Mass Relevance to get rid of dirty words and to keep content on target. While CNN could use Twitter for free, it would pay to bottleneck through Mass Relevance and Mass Relevance in turn would turn around and give a kickback to Twitter. This is one of the ways Twitter makes its money.

search in Windows 8

  • Click in the corner on the pseudostart and then start typing to perform a search for an application.
  • Windows-Q lets you search for applications.
  • Windows-F lets you search for files.

Wednesday, October 23, 2013

A dojox widget is a dojox widget if it calls (implements) "dojo/_base/declare" in define.

I looked into http://dojotoolkit.org/reference-guide/1.8/dojox/mobile/ValuePicker.html in the name of having a number field that one could increment. It looked easy enough to use. In the end, I just used a "number" type HTML5 control however.

Tuesday, October 22, 2013

OS X Mavericks is the new Mac operating system that will allow you to tag files and folders for searching.

Why don't we have this already in operating systems? This is a really good idea that we as human beings are oddly just coming up with now.

loop through an array in JavaScript

myArray.forEach(function(itemInMyArray) {
   alert(itemInMyArray.name);
});

Step back out with Shift-F11.

In debugging C# in Visual Studio or JavaScript in Chrome Developer tools:
  • F10 steps to the next sequential line
  • F11 steps into a method or function
  • Shift-F11 steps back out to the point where you F11ed in

Get tomorrow's date with moment.js and format it so that it will work in a date type HTML5 control.

function stringifyTomorrow() {
   var today = moment();
   var tomorrow = today.add('days', 1);
   return moment(tomorrow).format("YYYY-MM-DD");
}

 
 

Please also note:

  • there is also moment.utc()
  • there is also subtract
  • legit (dojo-flavored): if (moment() < moment(this.whatever.get("value"))) {

Monday, October 21, 2013

squircles

...are shapes halfway between squares and circles, like those uses in iPhone icons:

using underscore.js to sort a collection

dictionary.queryFilter(query).fetch().then(lang.hitch(this, function(entries) {
   entries.forEach(function(entry) {
      items.push({
         label: entry.name,
         value: entry.number
      });
   });
   items = _.sortBy(items, function(item){ return item.value });

Friday, October 18, 2013

truthy and falsey slang terms in JavaScript

This suggests that falsey has one of the following five values:

  1. undefined
  2. null
  3. NaN
  4. 0
  5. ...and an empty string like so: ""

 
 

truthy is... not falsey.

calling dojox events from HTML

<span class="icon-button" style="float: right"
   data-dojo-type="dojox.mobile.ToolBarButton"
   data-dojo-props="icon:'whatever', onClick: dojo.hitch(this, this.add)"></span>

 
 

The onClick above in a dojox view's HTML may trigger something like this in the sister .js file:

add: function(evt) {
   app.openView(this.domNode, {
      target: "somethingErOther",
      data: { }
   }, evt);
},

 
 

While I'm thinking of it, this shows off how to use a dojox attach point and the following are pretty good references for how to craft AMD modules:

I don't know why we whiteboard databases as cylinders.

And, the smart guys at stackoverflow don't know either. Poo.

Thursday, October 17, 2013

Wednesday, October 16, 2013

today's epiphany

Assuming this HTML...

<div id="ying" class="tao">ying</div>
<div id="yang" class="tao">yang</div>

 
 

This blob of dojo will run without blowing up and even so if you take out the HTML all together, leave in the destroy call which does not sabotage the prequeried collection, or both. If there are elements with the "tao" class they are altered and if they are not there, so be it. There are no errors either way.

define([
   "dojo/dom-construct",
   "dojo/query",
], function (
   domConstruct,
   query
) {
   return {
      init: function() {
         app = this.app;
      },
      beforeActivate: function(current, data) {
         var collection = query(".tao");
         domConstruct.destroy("yang");
         collection.forEach(function(node, index, arr){
            node.innerHTML = "meh";
         });
      }
   };
});

So what? Why care? What if you want to dress up one or zero DOM elements? When would you have this need? Well, what if you want to query a database and upon a callback put data into a DOM element based on the query results and a unique string you hand into the callback (a GUID for example) for identifying the DOM element. Well, alright that sounds great, but what if, before the callback resolves, the DOM element disappears (is dropped) as a part of a transition from one pane to another in a one page JavaScript application where DOM elements are commonly discarded? If you call the element by id and it is not there you will have a problem. Not so in calling a class which may or may not exist at just one element. Here is some jQuery that does something similar:

 
 

$( ".tao" ).html("meh");

one way to populate a list of object details in dojo/dojox

<ul class="displayList" data-dojo-type="dojox.mobile.RoundRectDataList"
      data-dojo-attach-point="summaryList"></ul>

 
 

Assuming the HTML above, we could use the code below:

define([
   "dojo/_base/lang",
   "dojo/data/ItemFileReadStore",
   "dojox/mobile/RoundRectDataList"
], function (
   lang,
   ItemFileReadStore
) {
   return {
      init: function() {
         app = this.app;
      },
      
      beforeActivate: function(current, data) {
         if(data && data.mdoElt !== undefined) {
            this.mdoElt = data.mdoElt;
            this.displayData();
         }
      },
      
      displayData: function() {
         var workRequest = this.mdoElt || {};
         var app = this.app;
         var items = [];
         items.push({
            label: "Foo",
            rightText: this.mdoElt.foo
         });
         items.push({
            label: "Bar",
            rightText: this.mdoElt.bar
         });
         items.push({
            label: "Baz",
            rightText: this.mdoElt.baz
         });
         items.push({
            label: "Qux",
            rightText: this.mdoElt.qux
         });
         var store = new ItemFileReadStore({ data: { items: items }});
         this.summaryList.setStore(store);
      }
   };
});

rejected at declare.loadChild (http://localhost/Whatever/dojox/app/controllers/Load.js:248:23)

...likely means that you are trying to change pages in dojox and calling a route that does not exist. Make sure you do not have a typo. This is magic string pain.

When there are more AMD modules defined than assigned to variables...

...like so:

define([
   "dojo/data/ItemFileReadStore",
   "dojo/_base/lang",
   "dojo/_base/declare",
   "dojox/mobile/ListItem",
   "lib/moment",
   "dojox/mobile/EdgeToEdgeDataList",
   "dojox/mobile/LongListMixin",
   "dojox/mobile/FilteredListMixin"
], function (
   ItemFileReadStore,
   lang,
   declare,
   ListItem,
   moment
) {

 
 

Well, if there are x variables then these are filled by the first x defines. Note, one does not strictly have to hand "lib/moment" to "moment" to use "moment" but my teammates tell me it is better to do so.

Moment.js date formatting!

return x.toDateString();
gives: Sat Oct 26th 2013

 
 

return moment(x).format("MMM Do YY");
gives: Oct 26th 13

 
 

return x.toDateString() + moment(x).format(" hh:mm:ss A");
gives: Sat Oct 26th 2013 03:42:50 PM

 
 

http://momentjs.com/docs/ has a cheat sheet that is neat.

Non-breaking space!

\u00a0 is the &nbsp; of JavaScript. If you hand \u00a0 to HTML it will become &nbsp;!

in .hgignore in the root of a Mercurial project put line items such as: foo/bar/baz.html

...to spec files to ignore. This will only work for files not yet committed.

The 1.0 release of Ember.js is named for J.J. Abrams!

I saw Tom Dale of Ember fame speak at a joint meeting of Austin JavaScript and also a meetup group called Ember ATX. The talk had to do with the new, not-beta version which is a reboot and thus named for someone good at reboots. I would have gotten more out of the presentation if I were already Ember-saavy which I was not. The new version embraces AMD while trying to containerize AMD modules to make them easier to work with. Tom Dale said he made significant changes in the name of keeping Ember from becoming the PHP of JavaScript frameworks. Ha!

Tag a Mercurial repository from within Grunt!

grunt.registerMultiTask('executerepotagging', 'tag a repository', function() {
   var done = this.async();
   executerepotagging = grunt.util.spawn({
   cmd: "hg",
   args: ["tag",
      "-u build",
      "v" + global['version']]
   }, function(error, result, code) {
      if(code == 127) {
         return grunt.warn(
            'The attempt to push a tag failed. '
         );
      }
      done(error);
   });
   executerepotagging.stdout.pipe(process.stdout);
   executerepotagging.stderr.pipe(process.stderr);
   executerepotagging = grunt.util.spawn({
      cmd: "hg",
      args: ["push"]
   }, function(error, result, code) {
      if(code == 127) {
         return grunt.warn(
            'The attempt to push a tag failed. '
         );
      }
      done(error);
   });
   executerepotagging.stdout.pipe(process.stdout);
   executerepotagging.stderr.pipe(process.stderr);
});
grunt.registerTask('tagrepo', 'executerepotagging');

 
 

"Up top" inside grunt.initConfig({ is:

executerepotagging: {
   main: {
      src: [],
      dest: 'tagrepo',
      options: {}
   }
},

 
 

If you run this locally from the command line you will likely be prompted for a username and password when attempting the push. Clearly, this will not do in an automated process. The request for a username and a password will act link a kink in a hose and sabotage the push.

You cannot spec a username and a password at the push command, but there are, of course, ways to save credentials for Mercurial. One is making a mercurial.ini file at the build server at C:\Program Files\Mercurial which looks like so:

[extensions]
fetch=
purge=
mq=
extdiff=
[auth]
kiln.prefix = http://jenkins.example.com/whatever
kiln.username = god
kiln.password = iamsuper

 
 

In Jenkins, for example, one would specify a Mercurial repository url under Source Code Management and here the path needs to match up with what is in the .ini file in a case-sensitive manner.

To push from one Mercurial Repository to another in FogBugz Kiln...

  1. go to the repository to push from
  2. go to the "Related" tab
  3. click on "Outgoing"
  4. set the "Outgoing changes to" dropdown to the repository to push to
  5. click on "Push" at the upper right

Tuesday, October 15, 2013

hg tag --remove v1.2.3

This will remove tag v1.2.3 from a Mercurial repository.

push a tag to Mercurial

The "tags" in the history sort of say: Everything before this point is of this tag (version). Open up the terminal window and push in a tag with commands like so:

hg tag -u tjaeschke v1.2.3
hg push

Monday, October 14, 2013

Grunt globals

This says it best. Set globals like so:

global['foo'] = 'bar';

 
 

Turn around and use them like this:

console.log("the global is: " + global['foo']);

Sunday, October 13, 2013

Rename a .docx file to be a .zip file to see it's "guts."

Inside there will be .xml files in folders and perhaps images or other files that cannot be kept as XML sprinkled here and there. All of the modern Microsoft Office file types which end in an x may be recast to .zip files in this manner as they are, in fact, .zip files full of .xml files in essence "under the hood."

If you hide the menu in Sublime Text...

Pressing alt will let you see it again for a moment. You may make it stay for real by going to: View > Show Menu

An ApiController should be named for the plural version of the object it manages CRUD for.

If you do not do so, you are breaking with Roy's REST spec. This bit of wisdom is mentioned in the book I am reading on the ASP.NET Web API. I realize I have a lot to learn about REST!

Mess with input fields in dojox.

A control:

<input type="text" style="z-index: 1;" data-dojo-attach-point="foo"
   data-dojo-type="dojox.mobile.TextBox" />

 
 

Set its value:

this.foo.set("value", "whatever");

 
 

Fish out its value:

var whatever = this.foo.get("value");

 
 

This all requires "dojox/mobile" in the opening define. This speaks to another way to go wherein one uses "dijit/form/TextBox" and goes fishing for controls to get/set from/to as seen above like so:

var box0 = registry.byId("value0Box");

Save an FTP connection in FileZilla.

You're probably tired of using the Quickconnect over and over again and reentering specs, eh?

My copy of WS_FTP95 ceased behaving and I am trying to FileZilla again. I could not remember how to set up an FTP account such that the connection specs would be saved. This reminded me that there is an option for "Site Manager..." under the "File" menu.

Once you get this far, it should be obvious what to do. Admittedly, I had to Google to get this far. You also have to come back into this dialog box every time you connect to one of the accounts you set up.

Saturday, October 12, 2013

Check please!

If your dinner was nasty you're not going to want to stay for dessert. Run tests first in a build script. If a build script is going to break due to a test failing it should break right away before you do other things such as rendering out files or version tagging. Those concerns should be pushed downstream of giving a green light to the testing. Check first. Fail fast. (wink, wink, Headspring)

make a page in a dojox app

The "template" setting in config.json will likely point to a particular .html file in a directory nested within another directory for collecting views which is typically called "app" and let's assume that this folder is called "app" in our example. To add a new page:

  1. add a new folder at app
  2. put some pages in here (each "page" has both a .js file and an .html file template) perhaps by copying from preexisting pages
  3. add a menu item at app\shared\Nav.html (or wherever the universal navigation page is located)
  4. add controller/view stuff in config.json

Run queries in Google Chrome Web Tools.

Run queries against a Web SQL database like so:

Thursday, October 10, 2013

JavaScript charting elegance bleeding into other spaces.

The same people who make JChartFX also make native iOS charts! Man, when is the good version of SSRS coming?

POST!

A serialized object makes a round trip in a POST verb action in the ASP.NET Web API from client to server to client again:

  1. The client will send a request to the server by way of the API that will contain an object to create.

     
  2. The POST method in the ASP.NET Web API will then create the object at the server and then ultimately send it back to the client reshaped.

     
  3. Everyone is happy!

     

This does not happen with DELETE in which one specifies an object to axe. One gets nothing back (ideally per REST ideals) from a server when trigging a DELETE at the API from the client. In PUT one also sends in a serialized object in the name of making an update (ideally per REST ideals) but here too, nothing is returned back. The POST is different (ideally per REST ideals) however, and the same serialized object you hand into a POST gets deserialized, tweaked, reserialized, and sent back to you! Why so? Isn't that silly? Well, the object that comes back to the client can have some bonus material that it might not have had to begin with. Something it may have learned in its travels is the unique id in the form of an integer (or a little less likely a Guid) that identifies it at the database. Anything else that must be calculated at the server may then decorate the newer, better thing that returns. The image at the right shows the process in terms of JSON serialization. It is from the book I have started reading on ASP.NET Web API which specifically is: Pro ASP.NET Web API Security: Securing ASP.NET Web API by Badrinarayanan Lakshmiraghavan. Note that if you hand in JSON you will, by default, get JSON back and if you hand in XML you will, by default, get XML back. Decorating the request shown here with an extra line reading...

Accept: application/xml

...will allow for XML to be handed back even though we are handing JSON in. The Accept value may be a list of comma separated items in lieu of one in particular. The ASP.NET Web API will honor the first MIME type it may make sense of in the list and if it can't make sense of any of them then it will be as if the Accept condition was never specified. One of the things which could come back decorating the new object is a set of Hypermedia links which denote what one may do with the object and how to drill down into more functionality yet. This sort of thing is part of the formal REST spec as suggested by Roy T. Fielding. That said, you are really a stickler for Roy if you feel the need to be that loyal. Most people fudge REST.

Get a list of files in two folders and tag them with comments denoting a version number in node.js!

The following assumes we will use this grunt-jenkins-build-number trick.

grunt.registerMultiTask('whatever', 'versioning stuff', function() {
   var version = 'tis: ' + process.env.BUILD_NUMBER;
   var fs = require('fs');
   var directories = ["foo","foo/bar"];
   directories.forEach(function(directory) {
      fs.readdir(directory, function(err, list) {
         list.forEach(function(file) {
            var route = directory + '/' + file;
            if (route.indexOf(".html") >= 0) {
               fs.readFile(route, function (err, data) {
                  fs.writeFile(route, '<!-- ' + version + " -->\r\n" + data, function (err) {});
               });
            }
            if (route.indexOf(".css") >= 0) {
               fs.readFile(route, function (err, data) {
                  fs.writeFile(route, '/* ' + version + " */\r\n" + data, function (err) {});
               });
            }
            if (route.indexOf(".js") >= 0) {
               fs.readFile(route, function (err, data) {
                  fs.writeFile(route, '/* ' + version + " */\r\n" + data, function (err) {});
               });
            }
         });
      });
   });
});

 
 

The following helped me:

 
 

I take back all of my hate for node!

/* comment */

...is golden in both .js and .css files!

Wednesday, October 9, 2013

box-sizing:border-box;

Seems to allow you to specify a width and height for a div that will include the measurements for padding and border. This is in contrast to box-sizing:content-box; which is the default setting forcing settings of greater than zero for padding and border width/height to add onto the width/height of the element they decorate. This suggests that good CSS to use for this is:

-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;

Moment.js

...is "for parsing, validating, manipulating, and formatting dates" and can do things like subtract one date from another. It also helps with creating a date from a magic string which (by way of default JavaScript) otherwise requires different formats in different browsers. Google Chrome has a different cast-me-to-a-date-friendly string format than Safari at an iPad.

npm install --production

...is going to install just the dependencies in package.json and not the devDependencies too.

Tuesday, October 8, 2013

what Obamacare means to the lone wolf tech contractor

Well, it means you'd better buy a plan! Otherwise one to eventually two and a half percent of your cowboy revenue is gonna go to the taxman. An Amanda Fredriksen spoke on Obamacare in general tonight at Refresh Austin. The talk really had little to do with tech and thus I probably don't need to delve into it at my blog where it would be out of place. Interesting things said worth repeating:

  • healthcare.gov is the online portal for plans.
  • 96 percent of American businesses have less than fifty people.
  • If you buy a plan in the official market you may get some financial assistance from Uncle Sam if you make $48,000 or less. However, if you qualify for this condition, you may want to rethink cowboy contracting in general as entry-level developers as direct hires tend to get $60,000 in the worst case scenario. (at least in Austin) Anyhow, the interesting thing here is that $48,000 is a representation of four times the "poverty level" so that level is at $12,000.

Refresh Austin seemed a cool group. Maybe I'll go back one night for a talk that really has to do with technology.

grunt-jenkins-build-number

To make grunt-jenkins-build-number work in GRUNT to sniff the current build number:

  1. You need something like this in dependencies in package.json:
    "grunt-jenkins-build-number": ">=0.0.2",
     
  2. You need this blob in the opening .initConfig of Gruntfile.js:
    jenkinsBuildNumber: {
       dist: {
          options: {
             hostname: 'http://jenkins.example.com/',
             state: 'lastBuild',
             username: 'usersuper',
             password: 'badpassword',
             projectName: 'TheNameOfMyJenkinsProject'
          }
       }
    },

     
  3. Farther down Gruntfile.js you need:
    grunt.loadNpmTasks('grunt-jenkins-build-number');
     
  4. Now I'm going to tell what they don't tell you in the documentation! You may get the build number farther down yet in Gruntfile.js (in a .registerMultiTask) like so:
    var lastBuild = process.env.BUILD_NUMBER;

-g is for global

in: npm install -g grunt ...the g means "install this globally" and the package should end up at C:\Program Files\nodejs\node_modules\npm\node_modules or some place comparable. By the way, do not try to copy the "node-modules" folders that appear when you run "npm install" at a particular folder from the command line to your master/global stash. The copy and paste trick will not work. There is more to registering than that. Another trick: Destroy the "node-modules" folders in these isolated cases to rerun the installs and get everything again to be sure the install is working as expected.

use .util.spawn in a GRUNT build

The following Gruntfile.js will send foo and baz parameters to doe/ray/me which may consume the request with optimist.

module.exports = function(grunt) {
   grunt.initConfig({
      pkg: '<json:package.json>',
      
      
OTHER STUFF HERE
      
      executetagger: {
         main: {
            //path to code
            src: [],
            dest: 'tagger',
            options: {}
         }
      },
      clean: ["<%= build.dest %>"]
   });
   
   
OTHER STUFF HERE TOO
   
   grunt.registerMultiTask('executetagger', 'something er other', function(outDir) {
            var done = this.async();
            console.log(arguments);
            executetagger = grunt.util.spawn({
                  cmd: "node",
                  args: ["doe/ray/me",
                              "--foo=bar",
                              "--baz=qux"]
            }, function(error, result, code) {
                  if(code == 127) {
                        return grunt.warn(
                           'The attempt to do whatever failed. '
                        );
                  }
                  done(error);
            });
            executetagger.stdout.pipe(process.stdout);
            executetagger.stderr.pipe(process.stderr);
   });
   grunt.registerTask('tagger', 'executetagger');
   grunt.registerTask('hudson-ci', ['tagger', 'somethingelse', 'athirdthing']);
};

 
 

process.argv[0] ...may be used instead of "node" above. I've seen some stuff online that suggests this is good practice and some stuff that claims the opposite. Whatever. The package.json at doe/ray/me will need to look like so:

{
   "name": "somethingelse-cli",
   "main": "somethingelse-cli.js"
}

 
 

The "main" setting will route the request to somethingelse-cli.js (in doe/ray/me) which may in turn defer to somethingelse.js (in doe/ray/me) as suggested here.

GET overloads in the ASP.NET web API

In conflict to what I say here, it looks like there is overloading for GET in this shape:

public string Get(int id)
{
   return "foo";
}
public string GetAll()
{
   return "bar";
}

 
 

These two methods could respectively be hit by these two urls:

  • /api/PET/42
  • /api/PET

 
 

GET stuff should be nullipotent (there is no change to state regardless of how may times one hits a GET method or if one does not hit the method at all).

Monday, October 7, 2013

Just reinstall node if you can't use grunt from the command line after you install it.

The cure for the problem I mention at the end of this is going to be a path in the PATH variable like such: C:\Users\tjaeschke\AppData\Roaming\npm

Do not try to "comment out" lines of code in a package.json.

You will get node errors asserting that package.json needs to be JSON and not JavaScript.

npm install -g grunt

...as a command line command in Windows 7 is to install GRUNT.

Error: Can't find Python executable "python", you set the PYTHON env variable.

If you get this error trying to do an "npm install" in node you probably need to install Python. Duh. I got the error trying to install restler. restler wants a version between 2.5.0 and 3.0.0 so a good candidate may be this. Per this, one will need to add the path to Python at the PATH variable at: Control Panel > Large icons > System > Change Settings > "Advanced" tab (by way of "Advanced system settings" link) > "Environment Variables" button

 
 

C:\oraclexe\app\oracle\product\11.2.0\server\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\Dell\DW WLAN Card;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files\TortoiseHg\;c:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\nant-0.91;C:\nant-0.91\bin;C:\Program Files\TortoiseSVN\bin;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Git\cmd;C:\Program Files\nodejs\;C:\Program Files (x86)\nodejs\

...is an example of what might be in the PATH variable. You will want to splice in something like "C:\Python27;" here, but be sure you do not overwrite all of the other semicolon-separated items as otherwise you may sabotage something else. For example, with the node stuff gone a command at the command line such as grunt --vers for returning the lastest version of grunt will return.:

'grunt' is not recognized as an internal or external command, operable program or batch file.

the CIA triad and two-factor authentication

More from the book I'm reading... the CIA triad:

  1. confidentiality – let only the authorized see the private
  2. integrity – guard against inappropriate edits/deletes ensuring data stays valid (nonrepudiation)
  3. availability – uptime for access

 
 

Authentication can be based on three different factors (and if you require two of the three then you have two-factor authentication).

  1. knowledge – you must recall a password
  2. ownership – you have a token or a certificate
  3. inherence – validation based on something uniquely of you such as your DNA or a fingerprint (not inheritance but inherence)

 
 

Two-factor authentication acronyms:

  • TFA
  • 2FA

Saturday, October 5, 2013

I saw Matt Schmulen of StrongLoop speak of StrongLoop in general on Thursday night.

Matt Schmulen (pictured here with Johnathan Hebert at right who runs The JavaScript Austin Meetup Group where the talk was held) asserted that StrongLoop is a middle layer, running in Node, for JavaScript applications. Instead of binding a Dojo app to Mongo you could bind the app to StrongLoop's endpoints and then StrongLoop would talk to Mongo instead. This decouples Dojox and MongoDB in your app and makes the front end and the backend swapoutable to some extent via loose coupling. StrongLoop interfaces with numerous frontends and backends. The backend does not have to be a database. It could be the Facebook API. If you think about a traditional three-layered application in which the data layer bleeds into the business logic which bleeds into the UI, then StrongLoop's stuff is of the middle layer (the business logic). A distro is a distributed version of an application and a StrongLoop Node.js distro may be spun up at Rackspace for your UI to talk to. It is hard to get Node rolled out in big businesses as there is no one to support it, but StrongLoop makes its money by offering contracts to support its own stuff. They are the people to call in the middle of a seasonal sales spike when the Node stuff falls down.

  • github.com/strongloop has all of their npm modules. All of their technology is free. It is the support contracts that feeds/fuels the free.
  • github.com/strongloop-community has a bunch of "Hello World" examples for how to do stuff with StrongLoop tooling. StrongLoop knows you have to become an addict first before you ask for help.
  • The Node Republic is a community that StrongLoop watches for wants and trends. This steers what it spends time developing.

 
 

Other interesting things mentioned during this talk:

  • swagger is for pimping out RESTful APIs and helps you manage your Posts and Gets.
  • AFNetworking stands for Alamo Fire Networking and is a set of Networking Tools for the iOS space. In glancing at their site I see a lot of serialization and deserialization stuff. An Alamo Fire is a kind of Bluebonnet. It's Texasesque.
  • iOS7 supports JavaScript-binding natively! An iOS app may be written in JavaScript and then pushed to Objective-C.
  • ObjectRocket is a database-as-a-service (DBaaS) that lives in the cloud and is of MongoDB.
  • node-inspector is for inspecting server-side (Node) code via tools not unlike the Google Chrome Developer Tools.

an example of handing an object to an ASP.NET Web API ApiController from jQuery

Just give a blob of JSON like so:

<script src="/Scripts/jquery-1.8.2.js"></script>
<script language="javascript">
   $(function () {
      myAsynchronousThing();
   });
   function myAsynchronousThing() {
      $.ajax({
         type: "POST",
         url: '/api/PET/',
         dataType: 'json',
         data: {
            Fleas: 42
         },
         success: function (result) {
            alert(result);
         }
      });
   }
</script>

 
 

Here is my ApiController. Note, that a method for a verb does not need to be explicitly named for the verb, it just needs to have a name that STARTS with the explicit name for the verb. I had sort of hoped I could overload the methods in an ApiController and have two POST methods, one for a Dog and one for a Cat, but it does not seem I may do so.

using System.Web.Http;
using WebApiExperiment.Models;
namespace WebApiExperiment.Controllers
{
   public class PetController : ApiController
   {
      public string PostDog(Dog dog)
      {
         return "My dog has fleas! (" + dog.Fleas + ")";
      }
   }
}

 
 

Here is my Dog:

namespace WebApiExperiment.Models
{
   public class Dog
   {
      public int Fleas { get; set; }
   }
}

 
 

I am starting to read a book on security for the ASP.NET Web API. One of the things in the book is a shocking (I'm kidding) suggestion that the verb methods should do things that correspond to their designations in ApiControllers for various objects with regards to CRUD functionality. In a Dog-themed ApiController, the Delete method would destroy a Dog record and the Get method would get one or many. I was surprised to see Put slated for updates and Post slated for creates as Put is idempotent. I suppose one may sanity check a create to see if a record already exists upon a create act, but there is not really a comparable way of preventing duplicate updates. I suppose it makes sense.

Friday, October 4, 2013

xml2js does what its name hints at turning XML into JSON.

see: this

grunt-cli

Grunt's command line interface may be installed like so:

npm install -g grunt-cli

 
 

You need it to call targets like so from the Windows command prompt:

grunt hudson-ci

Google Translate

...sure seems like a pretty neat free iPhone app. You can speak into it or type into it and translate what is given into another language.

 
 

Addendum 10/19/2015: We were goofing off with this at work today. You can hold the camera up to a sign in another language and the camera will show you, after a moment, what the sign would say in another language yet. The software recognizes the characters, translates them, and then reimages the image in a similar format and font. Japanese translations work a bit differently. You can take a photo of something in Japanese and then run your finger over characters to highlight them in the photo and it will tell you what the highlighted copy translates to.

feedspot.com

...is a replacement for Google Reader! Anuj Agarwal, sent me an email today telling me that people were checking out my blog there.

Thursday, October 3, 2013

Reflector

Reflector allows you to throw the screen of your iPad up onto a PC! Great for demos.

use require to fish for a .js file within a folder

var tagger = require('./testy');

...becomes...

var tagger = require('./myfolder/testy');

...with regards to this stuff. The last bit in a chain of slash separated things is assumed to be the name of a .js file and not a folder.

mystery requirement for require

The require thing won't just work out of the box in GRUNT. There is a dependency you need, but I'm not sure what it is. This works however:

module.exports = function(grunt) {
   grunt.initConfig({
      pkg: '<json:package.json>',
      build: {
         dest: 'dist'
      },
      mocha: {
         test: {
            src: ['test.html'],
            options: {
               log: true,
               reporter: 'Dot',
               run: false
            }
         }
      }
   });
   grunt.loadNpmTasks('grunt-mocha');
   grunt.registerTask('default', ['mocha']);
   grunt.registerTask('test', 'mocha');
   grunt.registerTask('tagger', function() {
      var tagger = require('./testy');
   });
   grunt.registerTask('hudson-ci', ['tagger', 'test']);
};

 
 

...so if you reference mocha, that will carry along whatever the underlying requirement is for line of code above reaching out to testy.js. I don't know what it is yet.

Do the impossible! Call one .js file from within another without any HTML being used as the bootstrapper.

Do so in GRUNT! The last bit of code here could be refactored to:

grunt.registerTask('bar', function() {
   var whatever = require('./whatever');
   whatever.somethingErOther();
});

 
 

This gives you access to the somethingErOther function kept in whatever.js which should sit in the same folder as Gruntfile.js! To empower this I think you will need to call...
grunt.loadNpmTasks('grunt-contrib-clean');
...or...
grunt.loadNpmTasks('grunt-contrib-copy');
...or...
grunt.loadNpmTasks('grunt-contrib-requirejs');
...somewhere beforehand. I'm not sure which yet.

GRUNT lets you call a function and write to the console, and here is how.

Keeping with this, and with the last line still reading...

grunt.registerTask('foo', ['bar', 'baz', 'qux']);

 

 

The following could be replaced...

grunt.registerTask('bar', 'sweet');

 

 

...with...

grunt.registerTask('bar', function() {
   console.log("Tom Jaeschke is getting better at Grunt!");
});

 

 

...to both call a function and then, ultimately, write a line to "the console" which could be, in the case of Jenkins, what one sees at the "Console Output" link's page at the build results of a Jenkins' build.

Wednesday, October 2, 2013

Drama with calling GIT from package.json in Node.js installs.

Remember how I told you you could use git urls for specifying dependencies in a package.json? Well, if you run an install from Jenkins in a Mac environment you will be fine, but not so in Windowsland. This suggests: This is a bug in graceful-fs. It's catching EMFILEs from fs.open, but not from fs.readdir, which also uses a file descriptor. Patch coming soon. The error materializes in showing off a lot of ENOENT alerts which sort of mean "no such file or directory" as a rule.