Search code examples
javascriptangularjsangularjs-scopeangular-ngmodel

Why doesn't my Angular ngModel example throw an error?


I have read several SO responses regarding Angular $scope and how it's a plain old JavaScript object, which means that it'll follow JS's prototypal inheritance (What are the nuances of scope prototypal / prototypical inheritance in AngularJS?)

Since this is the case, I'm curious why my following example DOESN'T throw an error:

<!doctype html>
<html ng-app='MyApp'>
<head>
  <meta charset='utf-8'>
  <title>Egghead</title>
  <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js'></script>
  <script>
    var app = angular.module('MyApp', []);
    app.controller('MainCtrl', ['$scope', function ($scope) {

    }])
  </script>
</head>
<body>
  <div ng-controller='MainCtrl'>
    <input type='text' ng-model='data.message'>
    <p>{{ data.message }}</p>
  </div>
</body>
</html>

Based on prototypal inheritance, here's what I would expect to happen:

  1. When MainCtrl is invoked, it will create a $scope object for the MainCtrl and its corresponding view.
  2. Whenever you type into the input box, it will bind some string to $scope.data.message.
  3. However, in order to do this, the first step in JavaScript will be to try to resolve $scope.data.
  4. Since the MainCtrl function doesn't have a data property, it will try to look for the data property in the rootScope.
  5. Since the rootScope doesn't have a data property, $scope.data should resolve to 'undefined'.
  6. Finally, if you try to assign to undefined.message, this should throw an error.

However, the code happily works and data is bound correctly. Can someone help untangle why this isn't throwing an error for me?


Solution

  • Made my original comment because I wasn't 100%, but after checking the docs, it's because...

    "ngModel will try to bind to the property given by evaluating the expression on the current scope. If the property doesn't already exist on this scope, it will be created implicitly and added to the scope."

    So if that property doesn't exist, it will create when then assign the value to it.

    src: here