Friday, January 31, 2014
online documentation tools
Thursday, January 30, 2014
A better way to manage which tab is up in a TabBar in a dojox app.
I got rid of this.tabs.push(btn); as suggested here, which was something I had added in the wrong way of doing things which did not exist before, and had the following methods in a controller manage the tabs. (see below) Note that setting the "selected" state on a tab does nothing and I am doing it just out of feeling a need to keep this setting consistent with what happens in a ._setSelectedAttr call (which is what causes an existing tab to be lit as active or muted as not currently active) in a psychosomatic hand washing way.
init: function() {
this.createTabButton("Foo", false);
this.createTabButton("Bar", false);
this.createTabButton("Baz", false);
this.createTabButton("Qux", false);
},
afterActivate: function(current, data) {
this.setTabs(this.app.currentView.name);
},
setTabs: function (currentTab){
var priorTab = this.assetTabBar.getSelectedTab();
if (priorTab) {
priorTab.set("selected", false);
priorTab._setSelectedAttr(false);
}
if (currentTab == "Foo") this.setTabUp(0);
if (currentTab == "Bar") this.setTabUp(1);
if (currentTab == "Baz") this.setTabUp(2);
if (currentTab == "Qux") this.setTabUp(3);
this.actionButton.on("click", lang.hitch(this.actions, this.actions.open));
this.actions.addAction("Whatever", "mblDomButtonIconAdd", lang.hitch(this,
this.addLaborEntry));
},
setTabUp: function (currentTab){
var activeTab = this.assetTabBar.getChildren()[currentTab];
activeTab.set("selected", true);
activeTab._setSelectedAttr(true);
},
In figuring out how to make these changes I looked at three web pages and three files. The web pages were:
- http://dojotoolkit.org/reference-guide/1.9/dojox/mobile/TabBar.html
- http://stackoverflow.com/questions/6819098/how-to-programmatically-create-a-dojox-mobile-tabbar
- http://dojo-toolkit.33424.n3.nabble.com/Adding-a-tabBarButton-programmatically-td3438220.html
The files:
- dojox/mobile/TabBar.js is where dojox keeps the TabBar widget which holds TabBarButton type widgets. Looking at the code for this widget initially gave me no help. I did ultimately use .getSelectedTab() out of here.
- digit/_Container.js is used by all dojox widgets which could be considered containers such as a TabBar which will contain, you'd assume, more than one TabBarButton. In this file I found the addChild and removeChild methods for the TabBar widget which I previously had no insight into.
- dojox/mobile/TabBarButton.js is a separate widget for the buttons which go in the widget which contains them. A look through the first two files gave me little hope for finding a better way to implement a TabBar, but at the child widget lay ._setSelectedAttr which I use above. The underscore convention at ._setSelectedAttr should imply a "private" method but I am latching onto it nonetheless. I'm the devil.
Ctrl-U in TortoiseHg Workbench will throw away the last local commit you just made if you immediately use it after the commit.
Wednesday, January 29, 2014
race condition
Tuesday, January 28, 2014
Different things to consider in trying to get rid of Malware at Google Chrome.
Today I made the mistake of downloading Paint.NET, a free lightweight version of something like Photoshop, from here (bad) instead of here (good) and in dealing with the malware I found I ended up with I learned a little more about Google Chrome itself. Note six places to look for trouble:
- Go to "Settings" under the hot dog menu, and then click the "Extensions" link at the upperleft to see a list of extensions. Get rid of those which are questionable.
- Go to chrome://plugins/ in Chrome to see a list of plugins. Get rid of those which are questionable.
- Under "Settings" under the hot dog menu, check the radio button for "Open a specific page or set of pages." under "On startup" and then click the link for "Set pages" to see what the browser feels default pages should be.
- Under "Settings" under the hot dog menu, check the checkbox for "Show Home button" under "Appearance" and then click the link for "Change" to see what the browser feels the default page should be at "Open this page:"
- Under "Settings" under the hot dog menu, click the "Manage search engines..." button under "Search" to see what search engine Chrome will try to use when you type something goofy in at the URL line. This may be something sinister too.
- Open Google Chrome from the desktop icon, then with Google Chrome open, open Google Chrome again from the desktop icon. The second browser to appear will display the "New Tab" which is a setting there is no way for you to configure yourself. If the "New Tab" advertises malware then something ill needs to be uninstalled from your environment. :(
typing "startup" at the start menu in Windows 7 lets you change the icon for yourself
Monday, January 27, 2014
What is a pattern portfolio?
It is more than a style sheet. My boss sent out a link to this today which includes a link to this suggesting that a pattern portfolio should have:
- a component library
- page examples
The first link also suggests that a pattern portfolio should be fairly baked-out in terms of deliverables too and not skimpy. Examples of it done right seem to be:
This posting should show off my ignorance of dojox.
This was in a view. It managed tabbing between subviews within the view.
<ul data-dojo-attach-point="workOrderTabBar"
data-dojo-type="dojox/mobile/TabBar"
data-dojo-props='barType:"segmentedControl"' />
Something like the following code existed before I touched the controller. It is for newing up the tabs when first entering the view. The only thing I added was the second to last line where I put the items we put into the control above into an array named "tabs" which I established as a controller-wide variable. I needed a way to manage state for which tab was up. A pain point came up when one jumped into this view at a tab other than the very first tab. In such scenarios, the simple implementation displayed the wrong tab as up. Lame!
createTabButton: function (label, selected){
var app = this.app;
var self = this;
var view = targetHelper.appendTarget(targetHelper.targetFromId(this.id), label);
var btn = new TabBarButton( {
label: label,
selected: selected,
view: view,
onClick: function(evt) {
var transOpts = {
target: view,
data: { mdoElt: self.mdoElt }
};
app.transitionToView(this.domNode, transOpts, evt);
}
});
this.tabs.push(btn);
this.workOrderTabBar.addChild(btn);
},
I call out to the following at init and afterActivate in the controller to get what I want. This is code I added. This example assumes there are four tabs labeled Foo, Bar, Baz, and Qux. In taking a look at dojox/mobile/TabBar I could not clearly understand the mechanics of how tabs were handed to the tab manager/wrapper we call "workOrderTabBar." Whatever. I guessed if .addChild was available that so too would be .removeChild and I was right.
setTabs: function (){
this.tabs.forEach(lang.hitch(this, function(btn) {
this.workOrderTabBar.removeChild(btn);
}));
var currentTab = this.app.getCurrentTabName();
this.createTabButton("Foo", currentTab == "Foo");
this.createTabButton("Bar", currentTab == "Bar");
this.createTabButton("Baz", currentTab == "Baz");
this.createTabButton("Qux", currentTab == "Qux");
this.actionButton.on("click", lang.hitch(this.actions, this.actions.open));
this.actions.addAction("Whatever", "mblDomButtonIconAdd", lang.hitch(this,
this.whatever));
},
There probably is a better way to empty the array holding the tabs, but I don't know what it is. Anyone want to explain to me why I suck?
"page lifecycle" stuff in dojox 1.9.2
When you have a view that has subviews...
- beforeActivate in the view runs first.
- beforeActivate in the current subview runs next.
- afterActivate in the same subview then runs.
- afterActivate back in the parental view then comes last.
Sunday, January 26, 2014
Pass in URL line style variables to an ASP.NET Web API Controller.
Consider this blob of HTML and jQuery:
<input id="Name"/>
<br />
<input id="Email" />
<br />
<input id="Password" />
<br />
<input id="ConfirmPassword" />
<br />
<input id="SecurityQuestion" />
<br />
<input id="SecurityQuestionAnswer" />
<br />
<button id="CreatePerson">Submit</button>
<script type="text/javascript">
$(function () {
});
$('#CreatePerson').bind('click', function () {
$.ajax({
type: "POST",
url: '/api/Person?name=' + $('#Name').val() +
'&email=' + $('#Email').val() +
'&password=' + $('#Password').val() +
'&confirmPassword=' + $('#ConfirmPassword').val() +
'&securityQuestion=' + $('#SecurityQuestion').val() +
'&securityQuestionAnswer=' + $('#SecurityQuestionAnswer').val(),
dataType: 'json',
success: function (result) {
alert('Success!');
}
});
});
</script>
What is above could feed into something that starts out like this on the C# side:
using System.Web.Http;
using FluffyNothing.Core.Objects;
namespace FluffyNothing.UserInterface.Controllers
{
public class PersonController : ApiController
{
public SuccessOrFailure Post(string name, string email, string password, string
confirmPassword, string securityQuestion, string securityQuestionAnswer)
{
Addendum 1/27/2014: Something I am experimenting with here is trying to push all validations to C#. If password and confirmPassword do not match and we need to throw a message back to the user, and, well, let C# drive that sanity checking.
public Foo Get() versus public Foo Get(string id)
@ViewBag.Title
I found the two links below which suggest you should solve the problem of how to put metatag and title tag data in _Layout.cshtml outside of the @RenderBody() call by just putting stuff in the ViewBag at the Controller side and just pulling it back out again. I am not in love with that. I'll try to find a better way.
Saturday, January 25, 2014
conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value
As suggested here, this problem in Entity Framework stuff basically stems (most likely) from handing in an unassigned DateTime value which ends up being translated to day one of year one which is only legitimate in datetime2 formatting.
What's in the Appendix?
Back for more torture from the book I'm sick of reading, I took it upon myself to read pages 997 to 1004 of Joseph and Ben Albahari's "C# 4.0 in a Nutshell" which is the one and only appendix. The appendix is on C# Keywords and offers a bunch of Webster's Dictionary stuff like this:
- using
- A directive that specifies that types in a particular namespace can be referred to without requiring their fully qualified name types.
- A statement that ensures an object implementing IDisposable is disposed of at the end of the statement's scope.
Uck. If you didn't already know what this means, you'd get nothing from this description. That said, I did take a few things away from this entry. I realized that when I speak of using statements (IDisposable stuff) I am not making an ass of myself as "statements" is the appropriate thing to say. It is using directives in contrast which sort of call out the assemblies which are in scope. All and all, there were four things I learned from the appendix. They are:
- I just mentioned the first thing. Look above.
- The second has to do with signed and unsigned types. As this explains, unsigned numeric types do not have half of their possible values sitting below the zero like a signed counterpart does. int and uint are both 4 bytes in size but the values you may put in an int range from -2,147,483,648 to 2,147,483,647 while the values you may put in a uint are 0 to 4,294,967,295 instead. ulong and ushort are the other two types like uint, and by that I mean they are unsigned. Now that I have read of this in the appendix I vaguely remember reading of it in the meat of the book too.
- Third, I suggest here that one cannot override up to a grandparent. I was wrong! One of the things a sealed class gives you is an assurance that methods decorated with override are not being overridden themselves! You may otherwise override that which is decorated with override as you may override that which is decorated with virtual! Consider these classes:
- namespace Core
{
public class Foo
{
public virtual string DoSomething()
{
return "Foo";
}
}
}
- namespace Core
{
public class Bar : Foo
{
public override string DoSomething()
{
return "Bar";
}
}
}
- namespace Core
{
public class Baz : Bar
{
public override string DoSomething()
{
return "Baz";
}
}
}
using Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Tests
{
[TestClass]
public class Inheritance
{
[TestMethod]
public void SimpleInheritance()
{
Bar bar = new Bar();
Foo foo = (Foo)bar;
Assert.AreEqual(foo.DoSomething(), "Bar");
}
[TestMethod]
public void NotSoSimpleInheritance()
{
Baz baz = new Baz();
Foo foo = (Foo)baz;
Assert.AreEqual(foo.DoSomething(), "Baz");
}
[TestMethod]
public void VerboseVersionOfNotSoSimpleInheritance()
{
Baz baz = new Baz();
Bar bar = (Bar)baz;
Foo foo = (Foo)bar;
Assert.AreEqual(foo.DoSomething(), "Baz");
}
}
}
- namespace Core
- Finally, I am also wrong here where I suggest there are no gotos in C#. C# does have a goofy limited goto. It is not what you'd expect from an older language. It is in fact a just way to jump around in a case statement or in other circumstances to do something comparably nasty. Observe:
namespace Core
{
public static class Qux
{
public static int DoSomething(int variable)
{
switch (variable)
{
case(13):
variable = variable + 88;
break;
case(42):
variable = variable + 99;
goto case(13);
break;
default:
break;
}
return variable;
}
}
}
Now behold this test which passes.
using Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Tests
{
[TestClass]
public class GoTo
{
[TestMethod]
public void JumpJump()
{
Assert.AreEqual(Qux.DoSomething(7), 7);
Assert.AreEqual(Qux.DoSomething(13), 101);
Assert.AreEqual(Qux.DoSomething(42), 229);
}
}
}
I thought I was done with "C# 4.0 in a Nutshell" last year, but it turns out it still had some things to teach me. This appendix is not just a useless organ where your body stashes the bubblegum you swallow (per urban myth).
Thursday, January 23, 2014
dojox events!
Per this, a good way to go fishing for the current view in a dojox app is by way of a property set like so:
app.on("app-layoutView",
function(evt){
var view = evt.view;
app.currentView = view;
});
Potential pain: Having this event fire off for a subview (tab within a "page") and then fire off for a view ("page") clobbering the more specific route.
Check to see if a JavaScript object has any properties on it whatsoever.
In the name of doing this sort of thing you may want to sanity check if you even can! You cannot do a falsey check on an object "newed up" with ={} like so:
if (viewOpeners) {
alert('has stuff');
} else {
alert('holds nothing and is equal to just: {}');
}
The way to go is:
if (Object.keys(viewOpeners).length) {
alert('has stuff');
} else {
alert('holds nothing and is equal to just: {}');
}
...which allows for:
if (Object.keys(viewOpeners).length) {
var topOfStack = Object.keys(viewOpeners)[Object.keys(viewOpeners).length - 1];
}
make a copy of one JavaScript object to another without the two objects referencing each other
You may not want to update a property at one object and have it update a property at another. Perhaps you want to grab a snapshot of something managing state in the moment for logging. Here is how you do that per StackOverflow:
app.exposeViewOpeners = function() {
var openers = getOpeners();
var snapshot = JSON.parse(JSON.stringify(openers));
console.log(snapshot);
};
Wednesday, January 22, 2014
cURL
Addendum 4/14/2018: It also says the name used to stand for: "see URL"
If you can't ride a bike from Houston to Austin in the name of fighting MS yourself...
....you can still sponsor someone else to do so. http://main.nationalmssociety.org/ has the details. The MS150 bike ride is April 12 and 13. Take part in any way you can. The company I work for is sending a team.
multiple sclerosis is a decay of the nervous system not to be confused with:
- scoliosis which is the spine curving forward too much in old women
- cirrhosis which is the process of the liver failing for alcoholics
- psoriasis which is itchy, flaky skin (better than multiple sclerosis, scoliosis, and cirrhosis)
viewOpeners
viewOpeners is isolated from the a lot of the this.app mechanics as it is not a property hanging off of app that one may manipulate at a dojox controller. Instead it is encapsulated as an object within app.js and only is "touched" through other methods and functions within app.js. viewOpeners is the stack of history in a dojox application. Views are popped off the stack to empower back buttons. (Note: It appears the ways dojo 1.9.2 and dojo 1.9.1 behave regarding this sort of management has changed.) Four functions touch viewOpeners from within app.js:
- isTargetOnPageStack
- clearPageStack
- pushViewOpener
- popViewOpener
Addendum: This may all be bunk, representative only of what goes on at my own workplace.
http://docs.angularjs.com/api is bunk.
Concatenate PDFs?
I found this last night offering four free ways to join stray PDFs into one PDF. I don't know if any of this works or not. Most interesting are:
- the suggestion to try http://merge.smallpdf.com/
- the suggestion to abuse a free trial of Nitro Pro (http://www.nitropdf.com/try)
Tuesday, January 21, 2014
Protractor is a testing framework for Angular.
There is a presentation on it at https://www.youtube.com/watch?v=aQipuiTcn3U (and this one of a slew of presentations given here which come from ng-conf 2014 which was a conference that happened last week in Salt Lake City which was themed around AngularJS). It is end-to-end testing.
Saturday, January 18, 2014
Get Entity Framework configurations out of Web.config!
This offers up the following example of handing a connection string to Entity Framework at a DbContext child in lieu of hunting for it in Web.config.
namespace MvcProject
{
public class Northwind : DbContext
{
public Northwind() : base("Data Source=servername;Initial Catalog=database;User
ID=yourID;Password=yourPass;Trusted_Connection=False;") {}
}
}
Does it work. I dunno as of yet. I have not tried it.
Addendum 1/19/2014: It works! Today I made:
using System.Data.Entity;
using FluffyNothing.Core.Objects;
namespace FluffyNothing.Infrastructure.DatabaseIntegration
{
public class PersonContext : DbContext
{
public DbSet<Person> People { get; set; }
public PersonContext() : base(@"server=.\JAESCHKE;database=FluffyNothing;
Integrated Security=true;") {}
}
}
Friday, January 17, 2014
So what's Net Neutrality?
Thursday, January 16, 2014
examples of throwing away a property on a JavaScript object
- delete tabs[Object.keys(tabs)[0]];
- delete myJSONObject['regex'];
grabbing a value off of a JavaScript object by position as if grabbing a value off of a JavaScript array
This trick (as advertised here and doctored up slightly by myself) worked...
var obj = { first: 'someVal' };
alert(obj[Object.keys(obj)[0]]);
...for grabbing a value off of a JavaScript object by position as if grabbing a value off of a JavaScript array.
The icon at the sources tab within Google Chrome Developer Tools at the rightmost pane which looks like a stop sign with two vertical slits in it (like an equals sign rotated ninety degrees) has three states that it may be toggled to by clicking upon it.
greyed-out: | Don't pause on exceptions. |
blue: | Pause on all exceptions |
red: | Pause on uncaught exceptions |
The "pause" behaves not unlike a breakpoint was at the line of code of interest.
data-dojo-props="onClick: dojo.hitch(this, this.delete)" ...breaking in Google Chrome 32.0.1700.76 but not Google Chrome 31.0.1650.63.
This dojo error materialized when there was no a "delete" method in the controller. The view was being used by a controller that managed an "update" CRUD screen and also a controller that managed a "create" CRUD screen. In the create scenario there was no delete method because we were just hiding the delete button which did not make sense in that circumstance. Google Chrome 31.0.1650.63 didn't care but Google Chrome 32.0.1700.76 did. We got a big stack trace error mess which meant a lot of nothing to us. This is something I find frustrating about both Dojo and AngularJS: opaque errors. Something goes inside of the thousands of lines of .js framework code, bounces around, and dies eventually while only surfacing an error that is not helpful at all.
Addendum: A coworker updated "delete" to be "destroy" to avoid a conflict with a JavaScript keyword. I don't know if this really bettered the problem or not. It was smart either way.
Wednesday, January 15, 2014
Slats in UX
A coworker today told me that Mail Chimp is developing reusable UI elements for developers and these include slats. I had to ask what a slat was and it turns out it is a horizontal strip of content like a header, but with more meat than just a background image and one string of copy. It will have slots (placeholders) for content, be they copy or controls. At http://ux.mailchimp.com/patterns/slats we have this example:
datetime2 is a new MSSQL type.
It has more precision than a datetime and also a greater date range that may reach backwards in time to day one of year one (instead of being constrained to not stray before 1753 when the British started using the Gregorian calendar) and forwards to the day before the start of year ten thousand.
Addendum 1/2/2020: 1753 is when Sweden went to Pope Gregory XIII's calendar, not just Britian.
The hgsubversion Extension will allow TortoiseHg to read from a Subversion repository into a local Mercurial repository.
Linting
DDD
I saw Ryan Vice speak on Domain Driven Design at the Austin .NET Users Group on Monday. DDD is the brainchild of Eric Evans and in "Domain-Driven Design: Tackling Complexity in the Heart of Software" he asserts that a project is doomed if one does not first get the business and developers to use a common language when speaking of objects. Ryan suggested that he really does not see this miracle happening in real life all that much and that instead he finds that a QA process eventually brings the business and the development into alignment. He feels that DDD is thus useful in how one approaches development more than in whiteboarding what is going on with that guy with the glazed over eyes who writes the checks. Ryan points to "Patterns of Enterprise Application Architecture" by Martin Fowler wherein Fowler offers some ammunition that reinforces this theory. Fowler suggests that if a challenge is small (simple) that one should just use a transaction script. Otherwise however, one should use a domain model. That's right, it can make a difference for you standalone even if it doesn't help your communications with a stakeholder. Ryan contrasted the difference between a domain model and the anemic model that typically develops in its absence while arguing that the former is better. He also offered a third approach, CQS. The three models:
- Anemic Model: Herein "domain" objects just have getters and setters, but no other logic. They are fleshed out enough and just enough to be hydrated from NHibernate, and we are using the familiar "Repository" pattern to facilitate that. (Ryan admitted that he did not know what the formal name for this pattern is if there is one. I've heard it referred to as the Repository pattern before. In it there is one God class for all database interactions for one particular anemic object or, in the case of the Domain Model approach, domain object.) Our objects are Data Transfer Objects (DTOs). All mechanics for lifecycle and sanity checking and the like are pulled out to a services layer which seemed to be a separate Visual Studio project in the code examples Ryan showed off. (This was true across all three patterns.) If you wanted to make sure that when a person object was newed up that it got a first name and a last name, then you'd have to write a separate class for sanity checking the Person object creation process.
- Domain Model: Is like the anemic model, but you won't need a separate class for sanity checking the Person object creation process. Person, as defined in C#, will get a little fatter. It's default constructor will be made to be of protected accessibility in lieu of public accessibility so that NHibernate may still use it. However, this walls the constructor off from code monkeys coding against it (unless they do something stupid with inheritance tricks) who will have to use different public constructors. A good public constructor for Person based on what we've kicked around so far would be one that takes in two strings for first name and last name and turns around and assigns them to the FirstName and LastName getsetters. Speaking of: public string FirstName { get; set; } ...may now become: public string FirstName { get; private set; } ...and whenever there is a need to change FirstName, one will have to go through a method on Person to do so. Not only does this get domain object-specific logic out of the service layer, but it also keeps it from easily bleeding back to there. Other convenience methods such as FullName() which concatenates FirstName and LastName could be kept at the object. If you want to make sure an Age for a Person is not a negative number, again, this goes at the object and not at the services. Ryan feels this makes the code a lot more readable for someone ramping up on a project. In his anemic model's unit tests there were many unit tests for services which were really not to do with the service but with an anemic object. Tests for ensuring exceptions were thrown if FirstName on Person was left null, etc. In the domain model, this confusion and noise is reduced. Ryan mentioned bounded contexts in passing and I'd bet these would also be less painful in the domain model approach. (The quintessential Eric Evans example for a bounded context is one for "orders" in which the word may be used to mean one thing at the shopping cart within a large system and something else with regards to how goods exit the warehouse. There could be two separate lifecycles and different getsetters instead of making one fat Order object. Conceptually, this means two bounded contexts.) So what goes in the services if not domain object rule enforcement? The use of an external dependency such as the sending of an email is not a good example. Ryan recommended looking into the Domain Events model of Udi Dahan for addressing emailing. (raise a domain event and have a default handler which will throw an event on a queue) Jimmy Bogard has further refined this stuff. (send a message and chain event handlers onto the message) Orchestration of cross-talk to external dependencies goes in the services layer. In goofing off with MongoDB, I once put together a silly little app with a Repository pattern. As a convenience, I wanted a new user to be created as an administrator if that was the first user created for the application. Otherwise, a new user should just be a plain Jane user. The decision making for if a new user should be an administrator did not go in my repository. I pulled it up to my core logic so that I might get it under unit testing independent of external dependencies. I believe in that scenario I just handed in an interface which could be implemented by my repository when the app was run or could be stubbed with dummy POCOs in testing. This is an example of stuff to pull up to the services from the infrastructure. Ryan seemed to admit feeling conflicted about whether or not to hand in dependencies as interfaces as suggested in my example, but confessed that he did it all the time in logging. He did not elaborate on other alternatives. Perhaps these circumstances beg for bigger solutions such as the Domain Event solution for emailing??? Mark Seemann doesn't want you to inject cross-cutting concerns as dependencies.
- CQS: Not to be confused with CQRS which stands for Command Query Responsibilities Segregation wherein there are separate databases for writing (normalized) and reading (denormalized), CQS stands for Command Query Segregation and demands that you should write code for reads and writes in two different ways on the C# side. Separate things into commands and queries. Have an abstract class (template pattern) and then override the class with object implementations for the acts. I surmise there would be two separate base classes for commands and queries. Prep a command in newing it up, but ultimately have an independent .Execute method for ultimately running Session.Save(Whatever); too. In getting away from the repository classes and being tied to NHibernate tooling, one is now free to cherry pick how one queries. NHibernate could be used most of the time while complicated searches could be done with stored procedures which are much faster to write and optimize than HQL equivalents.
Other things that came up in this talk:
- SourceTree by Atlassian is a Mercurial/Git client.
- The "Set Design Approach" for improving quality was mentioned by a gentleman in the audience. I tried to Google it but found nothing. Maybe I have misheard the name???
- Service Locator was again poopooed as inferior to Dependency Injection. Duh.
Tuesday, January 14, 2014
JSHint in Sublime
In Sublime, you may use the SublimeLinter (see Sublime's Package Control) to in turn use JSHint which is akin to JSLint. To install:
- first have Sublime text 3 and node installed
- run this at the command line: npm install -g jshint
- press Ctrl+` (the backtick or grave accent) in Sublime to get Sublime's console where you should push in: import urllib.request,os,hashlib; h = '7183a2d3e96f11eeadd761d777e62404e330c659d4bb41d3bdf022e94cab3cd0'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://sublime.wbond.net/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)
- press Ctrl+Shift+P in Sublime and then type "Install Package" in the dialog box which appears.
- pressing Enter here should let you search for and install "SublimeLinter-jshint" and you'll want to do so
- next, repeat the last two steps but install just "SublimeLinter"
- Preferences > Package Settings > SublimeLinter > Settings - Default ...should be something you may now navigate to to tweak settings and you should be done with the install process
When you use the tool, dots will appear beside lines of code which are "questionable" and you if click on a particular dot you will learn more:
Three properties are exposed in AngularJS templates without annotations.
They are:
- $scope holds stuff, and by stuff I mean data. Annotations such as ng-repeat and ng-show get full access to $scope and depend upon it for their mechanics.
- $id is a unique id for the current scope, and I mean $scope by scope.
- $window is the AngularJS way to do the stuff you do with window.whatever in JavaScript. It may be stubbed in testing.
Other properties such as $index which depends upon $ng-repeat are tied to a specific annotations and are used within an annotation and are not standalone "entities" themselves.
Shocker: Not closing MSSQL Server connections in C# may lead to a memory leak!
{{$index}} in an AngularJS template will print the current incremental position within an ng-repeat.
Monday, January 13, 2014
When a Mercurial repo no longer contains a subrepository in a folder named "Foo" and instead has actual files in "Foo"...
In the AngularJS MVC pattern, the models are services and the views are HTML templates.
confirm(whatever); is like alert(whatever); in JavaScript but with OK and Cancel buttons bolted onto the dialog box.
You can always close the dialog box with the X instead of explictly clicking Cancel so the example at w3schools.com here is sort of misleading as it suggests a result other than OK comes only from clicking Cancel. I made my own example which is better. It is:
var result = confirm("I'm OK with a meningitis vaccine.");
if (result)
{
alert("You picked OK.");
} else {
alert("You did NOT pick OK.");
}
bolting a controller onto an AngularJS application
If...
var app = angular.module('myApp', []);
...was upstream of the app.config stuff here, then one could add a controller to the application like so:
app.controller('fooCtrl',
function (etc...
HTML markup for AngularJS views
I am working my way through "AngularJS Starter" which is a 51 page book by Dan Menard. Some of the syntax examples in his first example of a view include:
- Here is a typical ng-repeat loop with a filter which refines how the results are ordered.
<li ng-repeat='note in chapter.notes | orderBy"id"'>
- This could be done inside the loop:
<p>{{note.content}}</p>
- This could be a link inside the loop:
<a href ng-click='onDelete(note.id)'>delete</a>
- A link to another route:
<a href='#/addNote/{{chapter.id}}'>add note</a>
- Showing or hiding copy conditionally:
<span ng-show='chapter.notes.length == 1'>note</span>
<span ng-hide='chapter.notes.length == 1'>notes</span>
AngularJS routing 101
Different ways to specify default routes in AngularJS (to fooCtrl in both examples) are:
- app.config(function($routeProvider) {
$routeProvider
.when('/', {
controller: "fooCtrl",
templateUrl: "templates/foo.html"
})
.when('/bar/:baz/:qux', {
controller: "barCtrl",
templateUrl: "templates/bar.html"
});
- app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/foo");
$stateProvider
.state('foo', {
url: "/foo",
templateUrl: "templates/foo.html",
controller: "fooCtrl"
})
.state('bar', {
url: "/bar/:baz/:qux",
templateUrl: "templates/bar.html",
controller: 'barCtrl'
});
I'm not yet sure how one fishes out the baz and qux variables in the first implemenation yet, but in the second implemenation, which I suspect is the more modern way to go, one would have $stateParams in the controller signature and then access the variables by doing a dot off of $stateParams like so:
ourControllers.controller('barCtrl', ['$scope', '$state', '$stateParams',
function detailCtrl($scope, $state, $stateParams) {
var baz = $stateParams.baz;
var qux = $stateParams.qux;
The URL line should change up to reflect these routes. Also, you may just type in a route at the browser to jump to where you want to be. (This feature is called deep linking. AngularJS routing supports using the forward and back buttons on the browser too somehow. The buttons are adapted to allow for walking to the last route visited ahead or behind.)
JSLint finds code comments ghetto.
"Unexpected comment." it says. I have worked with others which feel code comments are undesirable as:
- they will not be maintained
- the code should just be readable if it is good
I don't know that they are wrong, but should I clean away comments from existing code? (I participated in a book club on Bob Martin's Clean Code when I worked at Headspring. There was a chapter on comments which more or less told you not to use them.)
Friday, January 10, 2014
ng-app versus np-app="somethingInParticular"
ng-view
a JSLint example
JSLint prodded me to clean up this:
var foo = new Object();
foo["bar"] = "baz";
alert(foo["bar"]);
...to this:
var foo = {};
foo.bar = "baz";
alert(foo.bar);
...but still complained of this:
'alert' was used before it was defined.
Thursday, January 9, 2014
C# name!
I just bumbled upon this and this and learned the C# was once to be called Cool, but then that name was abandoned. It seems the name C++ comes from taking the name C and bolting an C-style incrementer on it that looks like this: ++
Keeping with that trend, C# would be C++++ wherein a ++ is slapped onto C++ to increment it. The # symbol is sort of like four + symbols and from there came the name. That is a better name than PHP, a recursive acronym for: PHP Hypertext Preprocessor
Wednesday, January 8, 2014
moment() versus moment.utc()
You may notice that in this:
var foo = moment.toDate();
var bar = moment.utc().toDate();
...foo and bar are basically the same thing. Perhaps you crave a hack like this:
var baz = new Date(moment.utc().format('YYYY-MM-DD HH:mm:ss'));
This stuff became an issue for me today when handing JavaScript dates to a library that then wrote them to a Web SQL database where the offsets were not maintained. About one sixth of the way down http://momentjs.com/docs/ there are some further details on moment() versus moment.utc().
chaining .then onto potential points of failure in dojo code
updateFoo: function(foo) {
foo.somethingFluffy = "bunnies";
dataFunctions.addFooHistoryRecord(foo).save();
return foo.save();
}
...isn't so good. You could save a history record, but not a foo if things go South at the right point in time. A better way:
updateFoo: function(foo) {
foo.somethingFluffy = "bunnies";
return foo.save()
.then(lang.hitch(this, function(){
dataFunctions.addFooHistoryRecord(foo).save();
}), lang.hitch(this, function(err) {
console.log('Yikes!');
}));
}
listening for the browser to resize in JavaScript
This suggests one may sniff for the browser being resized in plain Jane JavaScript like so:
window.addEventListener('resize', function(event){
// do stuff here
});
I researched this some for this but ended up doing things the dojo way and not blogging of the normal path to success. The stuff at the first link I give also has a link over to this which shows a working example using the following code:
go();
window.addEventListener('resize', go);
function go(){
document.querySelector('.width').innerText = document.documentElement.clientWidth;
document.querySelector('.height').innerText = document.documentElement.clientHeight;
}
a simple AngularJS example showing off a controller and a filter
Note the $scope variable in the controllers' function signature:
<!DOCTYPE html>
<html ng-app>
<head>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js'>
</script>
<script>
function foo($scope) {
$scope.bar = new Date();
}
</script>
</head>
<body>
<div ng-controller='foo'>
The time is: {{bar|date:'h:mm:ss a'}}
</div>
</body>
</html>
Tuesday, January 7, 2014
You may slap ng-app="whatever" on any tag. It doesn't have to be the HTML tag.
of moment.js and that trailing zero on the month and day
var foo = moment(myTime).format(" hh:mm:ss A MM/DD/YYYY");
...will put a trailing zero on the month and day ensuring it is always two digits long while...
var foo = moment(myTime).format(" hh:mm:ss A M/D/YYYY");
...will only show two digits for a month or day if a value is ten or greater.
Monday, January 6, 2014
The variables with dollar signs in an AngularJS application are protected from minification mangling.
The $ decorated items seen here will not get shorter names.
Saturday, January 4, 2014
AngularJS directives and filters
using require.js to slurp something else in outside of AMD signatures
var fooCtrl = require(["controllers/fooCtrl"]);
var barCtrl = require(["controllers/barCtrl"]);
...midstream in the app.js for an AngularJS implementation may be superior to bringing in "controllers/fooCtrl" and "controllers/barCtrl" at the AMD signature, especially so if the controllers need to use an Angular module defined partway into app.js.* I am struggling to try to take an Angular project full of script tags and migrate it to one which uses an AMD pattern and there is some pain. I used the trick here to get past (I think) one problem, but now I've just hit another.
*The pain... Uncaught Error: [$injector:nomod]
Friday, January 3, 2014
angular-resource.js has no method of $$minErr, eh?
I was hitting an error which looked like this:
Uncaught TypeError: Object #<Object> has no method '$$minErr'
When trying to include angular-resource.js. The whole problem was that I was using an old version of Angular, version 1.0.5. I downloaded 1.2.6 at http://angularjs.org/ and that solved my problem.
in addition to having providers AngularJS services typically have constant values too
services and providers setup in AngularJS
I show off prep for services and providers by refactoring the AngularJS app.js here to pull what was the .config stuff into the providers injection. One configures a service by preparing its provider as seen here:
define(["angular",
/* filters, directives, services, controllers */
"filters",
"services",
"otherservice",
"directives",
"controllers",
/* submodules */
"angular-route"
], function(angular, filters, services, otherservice, directives, controllers) {
"use strict";
var app = angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services',
'myApp.directives', 'myApp.controllers']);
app.service("$somethingElse", otherservice);
appConfig.$inject = ["$locationProvider", "$routeProvider"];
function appConfig($locationProvider, $routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}
app.config(appConfig);
appRun.$inject = ["$rootScope", "$somethingElse"];
function appRun($rootScope, $somethingElse) {
$somethingElse.helloWorld();
}
app.run(appRun);
return app;
});
I also brought in a new service in a new file called otherservice.js which I put in the js folder along with everything else.
define([], function() {
function otherService() {
}
otherService.prototype.helloWorld = function() {
alert('Hello World');
};
return otherService;
});
The services injection in app.js above shows off calling the helloWorld method exclusively upon the launch of the application (the refresh of the browser).
I guess I'm glad I never tried Snapchat as it has been hacked!
http://snapchatdb.info/ which holds a publicly available, ahem, snap of the database is rather brazen! Facebook was to pay a few billion to get their hands on Snapchat's user base. Now they, and everyone else, may have it for free.
Addendum: The user base may not easily be available although it is out there and certainly some have it. I found a story online this morning suggesting that the published database has the last two digits of each phone number obfuscated.
Thursday, January 2, 2014
The services which have gears by them have providers.
At http://docs.angularjs.org/api/ the services which have gears by them have providers for the services. Click the link to access the service and click the gear to access the provider. By naming convention FooProvider is the provider for a service called Foo.
I figured out how to abstract the AngularJS Seed Project to an AMD shape!
I did not do it alone. I had help from a coworker. Starting here I got rid of the np-app call at the HTML tag which would have cased the application to break by attempting to load Angular too soon. This is vital. I put require.js in the js folder and referenced it like so in the token HTML page:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My AngularJS App</title>
<link rel="stylesheet" href="css/app.css"/>
</head>
<body>
<ul class="menu">
<li><a href="#/view1">view1</a></li>
<li><a href="#/view2">view2</a></li>
</ul>
<div ng-view></div>
<div>Angular seed app: v<span app-version></span></div>
<script src="js/require.js" data-main="js/main.js"></script>
</body>
</html>
Notice above that all of the scripts tags are now gone (save for the new one). This is the desired effect. Alright, so what is js/main.js then? That is a configuration file for shimming angular.js and angular-route.js and for making sure that angular.js loads before app.js loads. (Note that I copied the "angular" folder out of the "lib" folder and into the "js" folder before just destroying the "lib" folder in the name of easier organization.) Below the deps will specify an array of modules to load and the callback function will only load after the deps at which point the application comes to life. I was missing this critical piece before. I was so close, yet so very far away...
(function() {
"use strict";
require.config({
baseUrl: "js",
shim: {
"angular": { exports: 'angular' },
"angular-route": { deps: ['angular'] }
},
paths: {
"angular": "angular/angular",
"angular-route": "angular/angular-route"
},
deps: ["angular", "app"],
callback: function(angular) {
angular.bootstrap(document, ['myApp']);
}
});
})();
Here is how app.js has changed up! A module name such as ngRoute for angular-route.js is not random. I opened up angular-route.js and looked for the name of a module inside. None of the module names are random or invented or attempts to match existing naming conventions. Do not get in that mindset as if trying to apply AMD module conventions to Angular modules. The referenced module names correspond to actual Angular modules kept in the specified files.
define(["angular",
/* filters, directives, services, controllers */
"filters",
"services",
"directives",
"controllers",
/* submodules */
"angular-route"
], function(angular, filters, services, directives, controllers) {
"use strict";
var app = angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services',
'myApp.directives', 'myApp.controllers']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
return app;
});
The only thing left to mention is that filters.js, services.js, directives.js, and controllers.js all blew up unable to find "angular" until I wrapped their guts in AMD module signatures as seen here:
- define(["angular",
], function(angular) {
'use strict';
angular.module('myApp.filters', []).
filter('interpolate', ['version', function(version) {
return function(text) {
return String(text).replace(/\%VERSION\%/mg, version);
}
}]);
});
- define(["angular",
], function(angular) {
'use strict';
angular.module('myApp.services', []).
value('version', '0.1');
});
- define(["angular",
], function(angular) {
'use strict';
angular.module('myApp.directives', []).
directive('appVersion', ['version', function(version) {
return function(scope, elm, attrs) {
elm.text(version);
};
}]);
});
- define(["angular",
], function(angular) {
'use strict';
angular.module('myApp.controllers', []).
controller('MyCtrl1', [function() {
}])
.controller('MyCtrl2', [function() {
}]);
});
DELETE star
case/switch statements in JavaScript
I found this and was able to make something like this:
addGunkToObject: function(myString, myObject) {
switch(myString) {
case "foo":
myObject.bar = "baz";
break;
case "qux":
myObject.bar = "qux";
break;
default:
console.log('There should not be a default failover at this thing.');
}
return myObject;
}
In writing this up I realized that I have already blogged of case/switch stuff in JavaScript before, but I still wanted to offer this as this code shows off the default outlier catching stuff.