Sunday, March 31, 2013

Fun vs. the truth

I heard or overheard "Easter bunny is a lie... just like... parents lied about religion" three times this week.

I have children.  They need to know that Easter is to celebrate the day Christ rose from the dead.   They should also have easter day fun.   I enjoy waking up, hunting for colorfully painted eggs, eating a big breakfast then going to church.  It is fun!  I do not want to take away their fun.

I never tell them the easter bunny is real or true. It is not!  It's just fun.  Santa Clause, the Easter Bunny, and the Tooth Fairy are probably not the false prophets mentioned in the Bible.

The connection between the Easter Bunny and Easter?  Here in Virginia we start seeing bunnies in the spring. Grandma saw the first one of the season this morning, Easter morning! Signs of new life? I think every child knows chickens come from eggs.  New Life!  Spring and the resurrection have things in common.

To believe or not to believe; every American gets to make that choice for themselves.  Not to believe something because of the easter bunny? I can't believe that.

Thursday, March 28, 2013

Optimizing Directives in AngularJs

Not many apps require this optimization technique. If the directive is applied 50+ times on a page, consider this technique.

I am displaying xml on a page.  When the user clicks on a node, a drop down list (ddl) is displayed.

Initially my app rendered all nodes with a ddl.  The ddl was hidden.  This significantly increased the size of my dom. Most nodes are not selected for editing.  Wasted work compiling on page load.

Using $compile(htmlStr)(scope) AngularJS compiles and renders ddl's only after the user clicks to edit.

HtmlStr is a string including the ng-select expression.  Be sure to have all data loaded in scope before compiling.

I apologize for the lack of code, phone bogging today.

Another optimization would be one list on the page used by all directives.  This would not support simultaneous editing.

Tuesday, March 26, 2013

Scrum poker

A round of Scrum Poker is good for any project.  It's always fun to see how new participants come to terms with relative time measurements. "What is 3... hours, days, weeks?"  Then the discussion about how humans are good at relative measurement.  "Is a marker bigger than a pencil? Yes."  If task A is bigger or more difficult than task B, assign it a higher number. Relationships between the numbering scale and time can be asserted after enough data is collected.

Saturday, March 23, 2013

jSad- jQuery on Small Documents

Given a small xml fragment with namespaces, jQuery selectors fail. Defined, a small xml fragment has a root node and a few children.
The fix is to wrap the fragment in a root elemement do the work, then remove the root element.

Wednesday, March 20, 2013

Constants in AngularJs

Angular has a compile process.  Functions might not be ready when directives need them.  Constants are compiled and evaluated earlier than directives.  The constants defined in mySettings is ready for use by directives when called.
Using constants also helps keep some order in the app. I'm using the same names or interface for the constants on each page.  Some constants such as apiUri are referenced five or six times on each page.  Each page has different values, but the interface is the same.  I prefer constants over hard coding strings.

The directive shown below is not my service, don't let the name fool you.  I use it to call an xml file.  Then directives with lower priorities generate behavioral aspects for the page.  My app is more document centric than model centric.  The MVC is very light. 

//root module

var myApp = angular.module('CoiApp',[]);
//constants
myApp.constant('mySettings', {
    apiUri: '/api/foo',
    nsUri: 'mySite/foo.xsd',
    nsPrefix: 's'
});

//directive using constants, mySettings is injected in using the minification safe method.
mayApp.directive('getById',
    ['$log', '$location', 'mySettings'
        function ($log, $location, mySettings) {
            return {
                priority: 500,
                templateUrl: mySettings.apiUri +'/' +  ($location.search()).myid
            };
}]);

Saturday, March 16, 2013

XML is Too Complicated

I can't believe I just said that 'XML is too complicated', but it must be true!  By capital XML I mean, xml, xsl, xsd, and xpath or xquery.  Raw xml is easy enough just angle brackets.  But everything else is so marginally supported.  Why? Must be too complicated? Right?
Let's compare xml to json as a base. Json is basically a key value pairs and arrays. Xml, the object model (DOM); namespaces, elements, and attributes. But each of these needs to be broken down into other parts.  Elements alone have start tag, tag name, end tag, text, and children.  The permutations start to really add up, making full implementation of the supporting technologies difficult.  I find xml easy and intuitive, but I don't build the tools to support xml.  The full lack of support is an impedance on workflow today.

Thursday, March 7, 2013

(jBAD)- jQuery on Big A$$ Documents

Take a look at the metrics on vanilla-js.com.  jQuery, while easy to use is not exactly fast.  That is not a slam on jQuery. In any app as functionality increases speed decreases.  When working with big documents mix vanilla-js with jQuery for best results.

var xmlFrag = document.getElementById(“12345”);
$(“f\\:user > f\\:name”,xmlFrag);
In the code sample above I'm searching xml with namespaces.  My namespace prefix is f.  I know the Id of the root node from an event (code not shown).  I'm using plain old javascript getElementById to quickly grab that dom node and create a fragment.  Then passing just that fragment of xml into jQuery for further processing.

<f:user xmlns:f="user.xsd"><f:name></f:name></f:user>

Tuesday, March 5, 2013

Visual Studio 2012 make string one line

Click the button to allow regex, then paste in [ \t\r\n]

Make sure only current document is selected, or hope you have version control!

image

AngularJs and Xml Priming the Pump

AngularJS is powerful data binder.  It has MVC tools built in for basic tasks.  AngulaJS Directives, I wouldn’t say they are really part of the MVC.  They are powerful!
When using directives against xml, there is a chicken and an egg problem. Angular does a good job separating code from data.  But sometimes they are the same.  Think dynamic sql, (which I agree is bad).  Putting raw xml on the page and then applying directives requires a different approach than the traditional MVC.
The code below will put the raw xml on the page.  In the xml, each element must have a namespace prefix. The root must have the namespace uri. 
Then other directives can be applied to the xml.

Directive
MyApp.directive('loadXmlGetById', function (MySvcApi) {
    return {
        priority: 500,
        templateUrl: MySvcApi.getByIdUrl,
    };
});
Html
<div load-xml-get-by-id></div>
MySvcApi
Is not much of a service, just a function that returns a string with the url for my services + the Id which it gets from the ($location.Search()).Id

Client Side Xml from IE Meets Server Side Xml C#

In Internet Explorer (8), when adding xml with namespaces to the DOM… it adds a partial xml declaration “<?xml:namespace prefix…”. 
In IE this is not a problem, but in the asp.net webApi I’m using XElement.Parse(xml) to do some clean up like remove jquery id’s and some css that gets added from AngularJs.
XElement.Parse(xml) blows up! So before parse, I’m removing the node with the following code. I’ve written a few tests, seems to work. I’d like to say I’ll post my tests later, but I doubt that will happen.

public string FixIENamespace(string contentStream)
      {
          const string pattern = @"<\?xml:namespace prefix =.* />";
          const string replacement = "";
          var rgx = new Regex(pattern);
          var result = rgx.Replace(contentStream, replacement);
          return result.ToString(CultureInfo.InvariantCulture);
      }

I have not had this problem with Chrome.

Monday, March 4, 2013

AngularJs: One Modal Many Controllers

I started seeing a common pattern in my app for adding a new xml node to a page.  I’m tired of copy and pasting the html for a modal where the only change is two small pieces of text.
Problem: only one ng-view can be on a page. Where to put ng-controller’s?    Nesting all the controllers around ng-view is not a good idea.
Solution:  ng-template to the rescue.  Be sure to update $routeProvider to include the route. If you use this route, don’t include the controller in the route.

We don’t have to use ng-template, but then we would have to create a whole new file with just two lines of code!
The script tag below is embedded inside <div ng-app>. 

<script type="text/ng-template" id="addTask.html">
<div ng-controller="newTaskCtrl" class="form-inline">
<div ng-include src="'genericAddItemModal.html'"></div>
</div>
</script>



I’ve even gone so for as to include another  <div ng-include src=”protoXmlFile”></div> where the protoXmlFile name is set in the controller with all my variables.


This can be further simplified by using the routeProvider by calling the same template , but different controller.  Then you don’t even need to use the script template method shown above. 


$routeProvider.when('/addCoi/:className', { templateUrl: 'addListModal.html', controller: addCoiCtrl });

Don’t forget the extra quotes on ng-include

On little thing that can be tough to remember when working with ng-include. 

Works:
<div ng-include src="'tasksPrototype.xml'"></div>
Does Not Work
<div ng-include src="tasksPrototype.xml"></div>



 

AngularJS and Xml with Namespaces Manipulation

 

The code below (find.find) gave me the same ID for each task.  Not really what I wanted.

Also notice the ‘\\:’ , this is a quick fix for working with namespaces in a document.  Technically it’s not accurate since it totally bypasses checking the resolver to ensure the prefix really matches the namespace requested. But for most circumstances should work.

Below is the xml fragment we are looking for

<f:task><f:id>12345</f:id></f:task>


xmlDom.find("f\\:task").find("f\\:id").text(getId());

By moving to a loop, each item has a new id.  Not a big fan of loops, but they are fast and well supported. I like Christian Johansen’s use of the map function to do this kind of work.  Unfortunately map is not supported by all browsers.  Not enough time tonight to find a substitute.

var taskList = xmlDom.find("f\\:task");
for (var k = 0; k < taskList.length; k++)
var id = angular.element(taskList[k]).find("f:\\id");
id.text(getId());
}