title: Conflicts when working with scopes and controllers in AngularJS
body: <p>I have a simple website that uses AngularJS with a NodeJS backend.</p>
  
  <p>It has multiple pages, like a homepage, a login/register page, etc.</p>
  
  <p>I'd like to implement a "Chat" page where you could send messages to other clients using socket.io. I already got that part working, using a local controller (by local, I mean active on a single page - the Chat page).</p>
  
  <p>The problem is, I would like the chat system to be global (i.e. client can receive messages while being on the homepage, but they'll still only be displayed when going back on the Chat page). </p>
  
  <hr>
  
  <p>I'm having an issue when setting the Chat controller global (active on all pages).</p>
  
  <p>Here's how I'm including it:</p>
  
  <pre><code>&lt;body ng-controller="AppCtrl"&gt; &lt;!-- include main controller --&gt;
      &lt;div ng-include="'header.tpl.html'"&gt;&lt;/div&gt;
      &lt;div ng-controller="ChatCtrl" class="page"&gt; &lt;!-- include global Chat controller --&gt;
          &lt;div ng-view class="container"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div ng-include="'footer.tpl.html'"&gt;&lt;/div&gt;
      &lt;!-- ...etc. --&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>This works pretty well, but it seems like I can't access a value from my Chat page, though. Functions declared from the Chat controller can still be called, but the "$scope.message" value (which contains the message that's being typed) is always empty.</p>
  
  <hr>
  
  <p>Here's my Chat controller (which is actually called TravelCtrl)</p>
  
  <pre><code>angular.module('base').controller('TravelCtrl', //['$scope', 'security',
    function($rootScope, $scope, security, NgMap, $geolocation, socket){
  
      $scope.messages = [];
  
      // Socket listeners
      // ================
  
      socket.on('init', function (data) {
        $scope.name = data.name;
        $scope.users = data.users;
      });
  
      socket.on('send:message', function (message) {
        $scope.messages.push(message);
      });
  
      socket.on('change:name', function (data) {
        changeName(data.oldName, data.newName);
      });
  
      socket.on('user:join', function (data) {
        $scope.messages.push({
          user: 'Server',
          text: 'User ' + data.name + ' has joined.'
        });
        $scope.users.push(data.name);
      });
  
      // add a message to the conversation when a user disconnects or leaves the room
      socket.on('user:left', function (data) {
        $scope.messages.push({
          user: 'chatroom',
          text: 'User ' + data.name + ' has left.'
        });
        var i, user;
        for (i = 0; i &lt; $scope.users.length; i++) {
          user = $scope.users[i];
          if (user === data.name) {
            $scope.users.splice(i, 1);
            break;
          }
        }
      });
  
      // Private helpers
      // ===============
  
      var changeName = function (oldName, newName) {
        // rename user in list of users
        var i;
        for (i = 0; i &lt; $scope.users.length; i++) {
          if ($scope.users[i] === oldName) {
            $scope.users[i] = newName;
          }
        }
  
        $scope.messages.push({
          user: 'Server',
          text: 'User ' + oldName + ' has been authenticated as ' + newName + '.'
        });
      }
  
      // Methods published to the scope
      // ==============================
  
      $scope.changeName = function () {
        socket.emit('change:name', {
          name: $scope.newName
        }, function (result) {
          if (!result) {
            alert('There was an error changing your name');
          } else {
  
            changeName($scope.name, $scope.newName);
  
            $scope.name = $scope.newName;
            $scope.newName = '';
          }
        });
      };
  
      $scope.sendMessage = function () {
  
        socket.emit('send:message', {
          message: $scope.message
        });
  
        // add the message to our model locally
        $scope.messages.push({
          user: $scope.name,
          text: $scope.message
        });
  
        // clear message box
        $scope.message = '';
  
      };
  
      // ================
  
      var init = function () {
        $scope.newName = security.currentUser.username;
        $scope.changeName();
      }
  
      if ($rootScope.hasLoaded() &amp;&amp; $scope.name != security.currentUser.username) {
        init();
      } else {
        $rootScope.$on('info-loaded', init);
      }
  
    }
    //]
  );
  </code></pre>
  
  <hr>
  
  <p>As well as the Chat page itself. The strange thing is that connected users and messages display correctly, but the controller can't seem to retrieve the typed message.</p>
  
  <pre><code>&lt;div class='col'&gt;
    &lt;h3&gt;Users&lt;/h3&gt;
    &lt;div class='overflowable'&gt;
      &lt;p ng-repeat='user in users'&gt;{{user}}&lt;/p&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  
  &lt;div class='col'&gt;
      &lt;h3&gt;Messages&lt;/h3&gt;
      &lt;div class='overflowable'&gt;
      &lt;p ng-repeat='message in messages' ng-class='{alert: message.user == "chatroom"}'&gt;{{message.user}}: {{message.text}}&lt;/p&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  
  &lt;div class='clr'&gt;
    &lt;form ng-submit='sendMessage()'&gt;
      Message: {{message}}&lt;br/&gt;
      &lt;input size='60', ng-model='message'/&gt;
      &lt;input type='submit', value='Send as {{name}}'/&gt;
      &lt;/form&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>When pressing the "Send" button, AngularJS successfully calls the sendMessage function, but retrieves the "message" value as an empty string, leading it to send an empty socket.io message.</p>
  
  <hr>
  
  <p>I'm quite new to AngularJS, so my approach might be totally ridiculous. I'm convinced I'm missing something obvious but after re-reading the docs again, I really can't seem to find what.</p>
  
  <p>Is this a proper way to organise an AngularJS app?</p>
  
  <p>Thanks in advance for your help.</p>