I've spent the last 20 minutes trying to figure out why my AngularJS directive was not working.

Here's a sample of the directive:

.directive("dataFolderItem", [ function() {

    return {
        "restrict"      : "E",
        "replace"       : true,
        "template"      : "<p>Data Folder Item</p>",
        link : function(scope, elem, attr) {
            console.log("data folder item");
        }
    };
    
}])

Here's a sample of the HTML that uses the directive:

<div>
    <data-folder-item></data-folder-item
</div>

Shameless Self-Promotion : Please checkout Kids In Touch - a family friendly messaging app for young kids.

The AngularJS pros around here will see the problem right away. I was too busy introducing my head to the wall to see the problem. After ensuring my directive was injected properly, was included in the <head>, etc, it finally dawned on me.

My problem was the use of the data- prefix. The data- prefix is a special HTML5 prefix for data binding. I was trying to use it as part of my directive name which is not possible with AngularJS. In AngularJS, you would use the data- prefix to create standard's compliant directive.

Per the AngularJS docs

The normalization process is as follows:

Strip x- and data- from the front of the element/attributes.
Convert the :, -, or _-delimited name to camelCase.

So, my element data-folder-item was being translated to folderItem. Of course, I had no such directive.

So, the fix was to stop trying to use a directive name that included data.

Corrected Directive:

.directive("folderItem", [ function() {

    return {
        "restrict"      : "E",
        "replace"       : true,
        "template"      : "<p>Data Folder Item</p>",
        link : function(scope, elem, attr) {
            console.log("data folder item");
        }
    };
    
}])

Corrected HTML:

<div>
    <folder-item></folder-item
</div>

Alternatively to be standards compliant, I could still use the data-folder-item as the element name.

Alternative:

<div>
    <data-folder-item></data-folder-item
</div>