Hi, I'm Nicholas Johnson!

software engineer / trainer / AI enthusiast

How does ng-app work?

Today’s Angular is the angularInit function. This is the function which makes ng-app work.

tldr; It selects elements, discovers the root module name, and then shells out to bootstrap, sending it the element and the module.

Here it is:


  function angularInit(element, bootstrap) {
const elements = [element],
    appElement,
    module,
    names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
    NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;

function append(element) {
  element && elements.push(element);
}

forEach(names, function(name) {
  names[name] = true;
  append(document.getElementById(name));
  name = name.replace(':', '\\:');
  if (element.querySelectorAll) {
    forEach(element.querySelectorAll('.' + name), append);
    forEach(element.querySelectorAll('.' + name + '\\:'), append);
    forEach(element.querySelectorAll('[' + name + ']'), append);
  }
});

forEach(elements, function(element) {
  if (!appElement) {
    const className = ' ' + element.className + ' ';
    const match = NG_APP_CLASS_REGEXP.exec(className);
    if (match) {
      appElement = element;
      module = (match[2] || '').replace(/\s+/g, ',');
    } else {
      forEach(element.attributes, function(attr) {
        if (!appElement && names[attr.name]) {
          appElement = element;
          module = attr.value;
        }
      });
    }
  }
});
if (appElement) {
  bootstrap(appElement, module ? [module] : []);
}
  }

We can see right away that we have an array of names, like so:

names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app']

These are the attributes that Angular will respond to, letting us do the familiar angular initialisation:

  <body ng:app>
  <body ng-app>
  <body x-ng-app>
  <body data-ng-app>

In addition, we also have the following class selector.

forEach(element.querySelectorAll('.' + name), append)

which allows us to initialise by class

  <body class="ng:app">
  <body class="ng-app">
  <body class="x-ng-app">
  <body class="data-ng-app">

Next we find the module

We then have this bit of code which finds the name of the module:

module = attr.value

Finally we bootstrap

Once we have our element and module name, we can bootstrap the app like so:

if (appElement) {
  bootstrap(appElement, module ? [module] : [])
}