0

Hi I was trying to run this angular based chat app, but it's giving me this error. Kindly please help me fix this. the code is already available on https://github.com/tamaspiros/AngularChat

the error i am getting is

Error: [ng:areq] Argument 'ChatAppCtrl' is not a function, got undefined http://errors.angularjs.org/1.3.9/ng/areq?p0=ChatAppCtrl&p1=not%20a%20function%2C%20got%20undefined at REGEX_STRING_REGEXP (angular.js:63) at assertArg (angular.js:1577) at assertArgFn (angular.js:1587) at angular.js:8418 at angular.js:7592 at forEach (angular.js:331) at nodeLinkFn (angular.js:7579) at compositeLinkFn (angular.js:7075) at compositeLinkFn (angular.js:7078) at publicLinkFn (angular.js:6954)

the index.html is

<!DOCTYPE html>
<html ng-app="chat">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="css/app.css">
  <link rel="stylesheet" href="css/bootstrap.yeti.css">
  <link rel="stylesheet" href="css/flags.css">
  <link rel="stylesheet" href="components/font-awesome/css/font-awesome.css">
</head>
<body ng-controller="ChatAppCtrl" ng-cloak>
  <!-- Fixed navbar -->
  <div class="navbar navbar-default navbar-fixed-top" role="navigation">
    <div class="container">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#" ng-click="about()">AngularChat</a>
      </div>
      <div class="collapse navbar-collapse">
        <ul class="nav navbar-nav">
          <li class="active"><a href="/">Home</a></li>
          <li><a href="#" ng-click="about()">About</a></li>
        </ul>
        <ul class="nav navbar-nav navbar-right">
          <li><p class="navbar-text online" ng-if='status === "online"'>{{ status }}</p><p class="navbar-text offline" ng-if='status === "offline"'>{{ status }}</p></li>
          <li class="dropdown" ng-show="joined">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ peopleCount }} online <b class="caret" ng-if="peopleCount > 0"></b></a>
            <ul class="dropdown-menu">
              <li ng-repeat="user in users"><p class="white">{{ user.name }} <span ng-if="user.countrycode"><img class="flag flag-{{user.countrycode}}"></span> <i class="fa fa-{{user.device}}"></i></p></li>
            </ul>
          </li>
          <li class="dropdown" ng-show="joined">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ roomCount }} room<span ng-if="roomCount  === 0 || roomCount > 1">s</span> <b class="caret" ng-if="roomCount > 0"></b></a>
            <ul class="dropdown-menu">
              <li ng-repeat="room in rooms">
                <form class="form-inline" role="form"><div class="form-group"><p class="white">{{ room.name }}</p></div><button class="btn btn-success btn-xs" type="submit" ng-click='joinRoom(room)' ng-hide='room.id === user.owns || room.id === user.inroom || user.owns || user.inroom'>Join</button>
                  <button type="submit" ng-click='deleteRoom(room)' class="btn btn-xs btn-danger" ng-show='room.id === user.owns'>Delete</button>
                  <button type="submit" ng-click="leaveRoom(room)" class="btn btn-xs btn-info" ng-hide='room.id === user.owns || !user.inroom || user.owns || user.inroom !== room.id'>Leave</button></form>
                </li>
              </ul>
            </li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </div>
    <!-- Begin page content -->
    <div class="container" ng-show="!joined">
      <form class="form-inline" role="form">
        <div class="form-group">
          <label class="sr-only" for="username">Name: </label>
          <input type="text" class="form-control" name="username" id="username" ng-model="username" placeholder="Enter desired name">
        </div>
        <button type="submit" class="btn btn-default btn-sm" ng-click='joinServer()'>Enter chat</button>
      </form>
      <small  ng-if="error" class="text-danger">{{ error.join }}</small> <small  ng-if="suggestedUsername" class="text-info" ng-click="setUsername(suggestedUsername)">How about <span class="text-success" style="cursor: pointer;">{{ suggestedUsername }}</a>?</small>
    </div>
    <div ng-hide="!joined" class="container" >
      <p >Hello {{ user.name }}. <span  ng-if="user.owns">You own a room: <strong>{{ user.roomname }}</strong>.</span> <span  ng-if="!user.owns && user.inroom">You have joined a room: <strong>{{ user.roomname }}</strong>.<br> You can create your own room as well (but you need to leave the current one first)
      </span><br>
      <small ng-if="user.owns">You can remove your room by clicking delete in drop-down menu in the top right corner.</small></p>
      <p ng-show="!user.inroom">Create a chat room or join one (top right corner).
        <div id="createroom">
          <form class="form-inline" role="form" ng-hide="user.owns && user.inroom">
            <div class="form-group">
              <label class="sr-only" for="roomname">Room name: </label>
              <input type="text" placeholder="Enter room name" class="form-control" ng-model="roomname" name="roomname" id="roomname">
            </div>
            <button type="submit" class="btn btn-default btn-sm" ng-click="createRoom()">Create room</button>
            <small  ng-if="error" class="text-danger">{{ error.create }}</small>
          </form>
        </div>
        <div id="chatpanel" ng-show="user.inroom" >
          <div id="chat">
            <form class="form-inline" role="form" ng-show="user.owns || user.inroom">
              <div class="form-group">
                <label class="sr-only" for="message">Message: </label>
                <input type="text" placeholder="Enter message" class="form-control" ng-model="message" name="message" id="message" ng-keypress="typing($event, user.inroom)" on-focus="focus(true)" on-blur="focus(false)">
              </div>
              <button type="submit" class="btn btn-default btn-sm" ng-click='send()'>Send message</button>
            </form>
            <small  ng-if="error" class="text-danger">{{ error.send }}</small>

          </div>
          <div class="row">
            <div class="col-lg-6">
              <div id="messages">
                <ul>
                  <li class="list-unstyled" ng-repeat="message in messages track by $index"  autoscroll ng-class="{dark: $index % 2 === 0}"><strong>{{ message.name }}</strong>: {{ message.message }}</li>
                </ul>
              </div>
            </div>
            <div class="col-lg-6">
              <div id="sidebar">
                <ul ng-if="isTyping">
                  <li  ng-repeat="person in typingPeople track by $index" class="text-muted list-unstyled"><small>{{ person }} is typing</small></li>
                </ul>
              </div>
            </div>
          </div>
        </div>


      </div>
    </div>
  </div>
  <div id="footer">
    <div class="container">
      <p class="text-muted">AngularChat by Tamas Piros | <a href="http://tamas.io/" target="_blank">http://tamas.io/</a> | <a href="https://twitter.com/tpiros" target="_blank">@tpiros</p>
    </div>
  </div>

  <!-- about modal -->
  <script type="text/ng-template" id="aboutModal" />
  <div class="modal-header">
    <h3>About AngularChat</h3>
  </div>
  <div class="modal-body">
    <p>Hello and thanks for visiting AngularChat.</p>
    <p>This is an experimental project for testing new JavaScript technologies.</p>
    <p>First, please enter your username. Once you've done this you have two options. You can create a room or you can join an already existing one.</p>
    <p>Please note that once you've joined a room you can't create one (basically you can be part of one room at one time). Also note that if you're a room owner and you disconnect from the server, delete or leave your room all other participants will be removed from the room as well.</p>
    <p>If you'd like to read more about the project please check out this article: <a href="http://tamas.io/angularchat/">http://tamas.io/angularchat/</a></p>
    <p>If you're interested in the code behind this project, please go to: <a href="https://github.com/tamaspiros/angularchat" target="_blank">https://github.com/tamaspiros/angularchat</a></p>
  </div>
  <div class="modal-footer">
    <button class="btn btn-warning btn-sm cancel" ng-click="cancel()">Cancel</button>
  </div>
</div>
</script>

<script src="/socket.io/socket.io.js"></script>
<script src="components/angular/angular.js"></script>
<script src="components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="components/jquery/dist/jquery.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/services.js"></script>
</body>
</html>

and the function ChatAppCtrl is

'use strict';

function ChatAppCtrl($scope, $q, $modal, socket, useragent, geolocation) {
  $scope.peopleCount = 0;
  $scope.messages = [];
  $scope.user = {}; //holds information about the current user
  $scope.users = {}; //holds information about ALL users
  $scope.rooms = []; //holds information about all rooms
  $scope.error = {};
  $scope.typingPeople = [];
  $scope.username = '';
  $scope.joined = false;
  var typing = false;
  var timeout  = undefined;

  /* ABOUT PAGE */
  $scope.about = function() {
    var modalInstance = $modal.open({
      templateUrl: 'aboutModal',
      controller: aboutModalCtrl
    });
  };

  var aboutModalCtrl = function($scope, $modalInstance) {
    $scope.cancel = function() {
      $modalInstance.dismiss('cancel');
    };
  };
  /* ABOUT PAGE END */

  $scope.setUsername = function(suggestedUsername) {
    $scope.username = suggestedUsername;
  }

  function timeoutFunction() {
    typing = false;
    socket.emit('typing', false);
  }

  $scope.focus = function(bool) {
    $scope.focussed = bool;
  }
  $scope.typing = function(event, room) {
    if (event.which !== 13) {
      if (typing === false && $scope.focussed && room !== null) {
        typing = true;
        socket.emit('typing', true);
      } else {
        clearTimeout(timeout);
        timeout = setTimeout(timeoutFunction, 1000);
      }
    }
  }

  socket.on('isTyping', function(data) {
    if (data.isTyping) {
      $scope.isTyping = data.isTyping;
      $scope.typingPeople.push(data.person);
    } else {
      $scope.isTyping = data.isTyping;
      var index = $scope.typingPeople.indexOf(data.person);
      $scope.typingPeople.splice(index, 1);
      $scope.typingMessage = '';
    }
  });

  $scope.joinServer = function() {
    $scope.user.name = this.username;
    if ($scope.user.name.length === 0) {
      $scope.error.join ='Please enter a username';
    } else {
      var usernameExists = false;
      socket.emit('checkUniqueUsername', $scope.user.name, function(data) {
        usernameExists = data.result;
        if (usernameExists) {
          $scope.error.join = 'Username ' + $scope.user.name + ' already exists.';
          socket.emit('suggest', $scope.user.name, function(data) {
            $scope.suggestedUsername = data.suggestedUsername;
          });
        } else {
          socket.emit('joinSocketServer', {name: $scope.user.name});
          $scope.joined = true;
          $scope.error.join = '';
        }
      });
    }
  }

  $scope.send = function() {
    if (typeof this.message === 'undefined' || (typeof this.message === 'string' && this.message.length === 0)) {
      $scope.error.send = 'Please enter a message';
    } else {
      socket.emit('send', {
        name: this.username,
        message: this.message
      });
      $scope.message = '';
      $scope.error.send = '';
    }

  }

  $scope.createRoom = function() {
    var roomExists = false;
    var room = this.roomname;
    if (typeof room === 'undefined' || (typeof room === 'string' && room.length === 0)) {
      $scope.error.create = 'Please enter a room name';
    } else {
      socket.emit('checkUniqueRoomName', room, function(data) {
        roomExists = data.result;
        if (roomExists) {
          $scope.error.create = 'Room ' + room + ' already exists.';
        } else {
          socket.emit('createRoom', room);
          $scope.error.create = '';
          if (!$scope.user.inroom) {
            $scope.messages = [];
            $scope.roomname = '';
          }
        }
      });
    }
  }

  $scope.joinRoom = function(room) {
    $scope.messages = [];
    $scope.error.create = '';
    $scope.message = '';
    socket.emit('joinRoom', room.id);
  }

  $scope.leaveRoom = function(room) {
    $scope.message = '';
    socket.emit('leaveRoom', room.id);
  }

  $scope.deleteRoom = function(room) {
    $scope.message = '';
    socket.emit('deleteRoom', room.id)
  }

  socket.on('sendUserDetail', function(data) {
    $scope.user = data;
  });

  socket.on('listAvailableChatRooms', function(data) {
    $scope.rooms.length = 0;
    angular.forEach(data, function(room, key) {
      $scope.rooms.push({name: room.name, id: room.id});
    });
  });

  socket.on('sendChatMessage', function(message) {
    $scope.messages.push(message);
  });

  socket.on('sendChatMessageHistory', function(data) {
    angular.forEach(data, function(messages, key) {
      $scope.messages.push(messages);
    });
  });

  socket.on('connectingToSocketServer', function(data) {
    $scope.status = data.status;
  });

  socket.on('usernameExists', function(data) {
    $scope.error.join = data.data;
  });

  socket.on('updateUserDetail', function(data) {
    $scope.users = data;
  });

  socket.on('joinedSuccessfully', function() {
    var payload = {
      countrycode: '',
      device: ''
    };
    geolocation.getLocation().then(function(position) {
      return geolocation.getCountryCode(position);
    }).then(function(countryCode) {
      payload.countrycode = countryCode;
      return useragent.getUserAgent();
    }).then(function(ua) {
      return useragent.getIcon(ua);
    }).then(function(device) {
      payload.device = device;
      socket.emit('userDetails', payload);
    });
  });

  socket.on('updatePeopleCount', function(data) {
    $scope.peopleCount = data.count;
  });

  socket.on('updateRoomsCount', function(data) {
    $scope.roomCount = data.count;
  });

  socket.on('disconnect', function(){
    $scope.status = 'offline';
    $scope.users = 0;
    $scope.peopleCount = 0;
  });
}

1 Answer 1

0

Recent versions of Angular do not allow global functions to be used as controllers, see docs under "Arguments". The solutions:

  1. (preferred) Use angular.module('chat').controller('ChatAppCtrl', ChatAppCtrl);

  2. Configure the $controllerProvider: In a coonfig block, inject the $controllerProvider and run: $controllerProvider.allowGlobals().

Sign up to request clarification or add additional context in comments.

1 Comment

Hi thanks for the reply, I tried the step one like this. 'use strict'; //var app = angular.module('chat', ['ui.bootstrap']); var app = angular.module('chat',['ui.bootstrap']).controller('ChatAppCtrl', ChatAppCtrl); it was the commented one. still it's not working, and i couldn't find the config block of the step two. kindly have a look on the code if there is any mistake.[github.com/tamaspiros/AngularChat)]

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.