Error: [ng:areq] Argument 'ChatAppCtrl' is not a function, got undefined - angularjs

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">Home</li>
<li>About</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">
{{ peopleCount }} online <b class="caret" ng-if="peopleCount > 0"></b>
<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">
{{ roomCount }} room<span ng-if="roomCount === 0 || roomCount > 1">s</span> <b class="caret" ng-if="roomCount > 0"></b>
<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 | http://tamas.io/ | <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: http://tamas.io/angularchat/</p>
<p>If you're interested in the code behind this project, please go to: https://github.com/tamaspiros/angularchat</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;
});
}

Recent versions of Angular do not allow global functions to be used as controllers, see docs under "Arguments". The solutions:
(preferred) Use angular.module('chat').controller('ChatAppCtrl', ChatAppCtrl);
Configure the $controllerProvider: In a coonfig block, inject the $controllerProvider and run: $controllerProvider.allowGlobals().

Related

ngRepeat:dupes when trying to fetch from database

I am constantly getting the mentioned error no matter what I try. The error stops when I comment out the "fetchCourses()" in courses.js file. I am guessing the error is somewhere in the http request but I cannot figure it out.
Here are my code snippets.
courses.js (controller)
var app = angular.module("app");
app.controller('coursesCtrl', ['$scope', 'Courses', '$routeParams', function ($scope, Courses, $routeParams) {
function fetchCourses() {
Courses.getCourses({}).then(function (res) {
$scope.courses = res.data;
}, function (err) {
console.log(err);
});
}
fetchCourses();
$scope.modal = {
title: "Modal",
btnText: "Ok",
save: function () {
if ($scope.modal.type == 'course_delete') {
Courses.deleteCourse($scope.modal.req).then(function (res) {
if (res.status == 200) {
$scope.courses.splice($scope.modal.req.index, 1);
$("#course_modal").modal("hide");
}
}, function (err) {
console.log(err);
});
} else if ($scope.modal.type == 'course_create') {
Courses.createCourse($scope.modal.req).then(function (res) {
$scope.courses.unshift(res.data);
$("#course_modal").modal("hide");
}, function (err) {
console.log(err);
});
} else if ($scope.modal.type == 'course_edit') {
$scope.courses[$scope.modal.req.index] = $scope.modal.req.course;
$("#course_modal").modal("hide");
$scope.modal.req.course = null;
}
},
type: "default",
req: {},
};
$scope.createCourse = function () {
$("#course_modal").modal("show");
$scope.modal.title = "Create course";
$scope.modal.btnText = "Create";
$scope.modal.type = "course_create";
$scope.modal.req = {};
};
$scope.editCourse = function (index) {
$("#course_modal").modal("show");
$scope.modal.title = "Edit course";
$scope.modal.btnText = "Ok";
$scope.modal.type = "course_edit";
$scope.modal.req.index = index;
};
$scope.deleteCourse = function (index) {
$("#course_modal").modal("show");
$scope.modal.title = "Delete course";
$scope.modal.btnText = "Yes";
$scope.modal.type = "course_delete";
$scope.modal.req.index = index;
};
}]);
Route.js
var Students = require('../../models/students');
var Courses = require('../../models/courses');
var Departments = require('../../models/departments');
var Exams = require('../../models/exams');
var ObjectId = require('mongoose').Types.ObjectId;
var bodyParser = require('body-parser');
module.exports = function (app) {
app.use(bodyParser.urlencoded({
extended: true
}));
app.post('/getCourses', (req, res) => {
Courses.find({}).exec(function (err, documents) {
res.send(documents);
console.log(documents);
});
});
app.post('/createCourse', (req, res) => {
var data = {
coursesName: req.body.coursesName,
coursesProfessor: req.body.coursesProfessor,
coursesDepartment: req.body.coursesDepartment,
coursesNumStudents: req.body.coursesNumStudents,
};
Courses.create(data, function (err, document) {
if (err) return res.status(500).send({
message: "Sorry! There was a problem creating a course."
});
res.send(document);
console.log(document);
});
});
};
menu.js (aka header)
var menu = angular.module("menu", []);
menu.controller('menuCtrl', ['$scope', '$location', function ($scope, $location) {
/*
if (notloggedin){
window.location.replace("/");
}
*/
$scope.logout = function () {
window.location.replace("/");
}
$scope.url = $location.url();
console.log($location.url());
}]);
menu.service('Courses', ['$http', function ($http) {
var Headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
var transformReq = function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
this.getCourses = function (req) {
return $http({
method: 'POST',
url: '/getCourses',
headers: Headers,
transformRequest: transformReq,
data: req
});
}
this.createCourse = function (req) {
return $http({
method: 'POST',
url: '/createCourse',
headers: Headers,
transformRequest: transformReq,
data: req
});
}
}]);
And the courses.html
<div class="wrapper">
<div ng-include="'header/menu.html'"></div>
<div class="main-panel">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar bar1"></span>
<span class="icon-bar bar2"></span>
<span class="icon-bar bar3"></span>
</button>
<a class="navbar-brand" href="#">Courses</a>
</div>
</div>
</nav>
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="header">
<h4 class="title">Courses List</h4>
<p class="category">Here is a list of all courses</p>
<button class="btn btn-success" style="float:right" ng-click="createCourse()">Create Course</button>
</div>
<div class="content table-responsive table-full-width">
<table class="table table-striped">
<thead>
<th>Name</th>
<th>Professor</th>
<th>Department</th>
<th>Num of Students</th>
<th>#</th>
</thead>
<tbody>
<tr ng-repeat="c in courses">
<td>{{c.coursesName}}</td>
<td>{{c.coursesProfessor}}</td>
<td>{{c.coursesDepartment}}</td>
<td>{{c.coursesNumStudents}}</td>
<td>
<a href="" ng-click="editCourse($index)">Edit
</a> /
<a href="" ng-click="deleteCourse($index)">Delete
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="course_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h5 class="modal-title" id="modalLabel">{{modal.title}}</h5>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<form ng-if="modal.type == 'course_create' || modal.type == 'course_edit'">
<div class="form-group">
<label for="coursesName">Name</label>
<input type="text" class="form-control" ng-model="modal.req.course.coursesName" ng-disabled>
</div>
<div class="form-group">
<label for="coursesProfessor">Professor</label>
<input type="text" class="form-control" ng-model="modal.req.course.coursesProfessor" ng-disabled>
</div>
<div class="form-group">
<label for="coursesDepartment">Department</label>
<input type="text" class="form-control" ng-model="modal.req.course.coursesDepartment" ng-disabled>
</div>
<div class="form-group">
<label for="coursesNumStudents">Number of Students</label>
<input type="text" class="form-control" ng-model="modal.req.course.coursesNumStudents" ng-disabled>
</div>
</form>
<div ng-if="modal.type == 'course_delete'">
Are you sure you want to delete this course?
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-success" ng-click="modal.save()">{{modal.btnText}}</button>
</div>
</div>
</div>
</div>
This means that $scope.courses have some values which are duplicate. Duplicate keys are banned because AngularJS uses keys to associate DOM nodes with items.
So in this case you can use track by $index So repeated items will be tracked by its index.
<tr ng-repeat="c in courses track by $index">{{value}}</tr>

how to get specific item that selected?

screenshot attached.
I learning angularJS.
And i can't find a way to remove the selected item that the 'Remove' button was click on.
Is there any way to do it ?
code attached:
<ul class="unstyled">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
<button class="btn" ng-click="removeTodo()">Remove</button>
</li>
</ul>
var app = angular.module("app" , []);
app.controller("MyCtrl" , function($scope){
$scope.todos = [
{"text" :"Learn AngularJS","done":false},{"text" :"build an app","done":false}];
$scope.removeTodo = function(index) {
$scope.todos.splice(index,1);
}
$scope.removeTodo2 = function(todo) {
var index = getByValue( $scope.todos,todo);
$scope.todos.splice(index,1);
}
$scope.addTodo = function(todo){
var toDoObject = {"text":todo,"done":false};
$scope.todos.push(toDoObject);
};
$scope.done = function(todo){
angular.forEach($scope.todos,function(index,todo1){
if(todo == todo1)
$scope.todos[index].done = !$scope.todos[index].done;
})
}
function getByValue(arr, value) {
for (var i=0, iLen=arr.length; i<iLen; i++) {
if (arr[i].text == value) return i;
}
}
});
.done{
text-decoration: line-through;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<ul class="unstyled">
<li ng-repeat="todo in todos track by $index">
<input type="checkbox" ng-model="todo.done" >
<span ng-class="{'done' : todo.done == true}">{{todo.text}}</span>
<button class="btn" ng-click="removeTodo($index)">Remove</button>
<button class="btn" ng-click="removeTodo2(todo.text)">Remove2</button>
</li>
</ul>
<input type="text" ng-model="todo">
<input type="button" ng-click = "addTodo(todo)" value="Add">
</div>

SyntaxError: Unexpected token u Angularjs

//Define angular app
var app = angular.module('ToDoApp', []);
//controllers
app.controller('taskController', function($scope) {
$scope.today = new Date();
$scope.saved = localStorage.getItem('taskItems');
$scope.taskItem = (localStorage.getItem('taskItems') !== null) ?
JSON.parse($scope.saved) : [{
description: "Why not add a task?",
date: $scope.today,
complete: false
}];
localStorage.setItem('taskItems', JSON.stringify($scope.taskItem));
$scope.newTask = null;
$scope.newTaskDate = null;
$scope.categories = [{
name: 'Personal'
}, {
name: 'Work'
}, {
name: 'School'
}, {
name: 'Cleaning'
}, {
name: 'Other'
}];
$scope.newTaskCategory = $scope.categories;
$scope.addNew = function() {
if ($scope.newTaskDate == null || $scope.newTaskDate == '') {
$scope.taskItem.push({
description: $scope.newTask,
date: "No deadline",
complete: false,
category: $scope.newTaskCategory.name
})
} else {
$scope.taskItem.push({
description: $scope.newTask,
date: $scope.newTaskDate,
complete: false,
category: $scope.newTaskCategory.name
})
};
$scope.newTask = '';
$scope.newTaskDate = '';
$scope.newTaskCategory = $scope.categories;
localStorage.setItem('taskItems', JSON.stringify($scope.taskItem));
};
$scope.deleteTask = function() {
var completedTask = $scope.taskItem;
$scope.taskItem = [];
angular.forEach(completedTask, function(taskItem) {
if (!taskItem.complete) {
$scope.taskItem.push(taskItem);
}
});
localStorage.setItem('taskItems', JSON.stringify($scope.taskItem));
};
$scope.save = function() {
localStorage.setItem('taskItems', JSON.stringify($scope.taskItem));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ToDoApp">
<div class="container">
<div class="content" ng-controller="taskController">
<h1>Welcome to your to do List</h1>
<p class="tagline">By Flintdesignz
</p>
<form>
<div class="row">
<div class="inputContainer">
<input type="text" id="description" class="taskName" placeholder="I need to..." ng-model="newTask">
</div>
</div>
<div class="row">
<div class="inputContainer"> <i class="fa fa-caret-down selectArrow"></i>
<select id="category" class="taskCategory" ng-model="newTaskCategory" ng-options="obj.name for obj in categories">
<option class="disabled" value="">Category</option>
</select>
</div>
</div>
<div class="row">
<div class="inputContainer">
<input type="date" id="dueDate" class="taskDate" ng-model="newTaskDate">
</div>
</div>
<div class="row buttons_holder">
<button class="taskAdd" ng-click="addNew()"><i class="fa fa-plus icon"></i>Add task</button>
<button class="taskDelete" ng-click="deleteTask()"><i class="fa fa-trash-o icon"></i>Remove Tasks</button>
</div>
</form>
<!-- TaskList Starts Here -->
<ul class="taskList">
<li class="taskItem" ng-repeat="taskItem in taskItem track by $index" ng-model="taskItem">
<input type="checkbox" class="taskCheckbox" ng-model="taskItem.complete" ng-change="save()">
<span class="complete-{{taskItem.complete}}">{{taskItem.description}}</span> <span class="category-{{taskItem.category}}">{{taskItem.category}}</span> <strong class="taskDate complete-{{taskItem.complete}}"><i class="fa fa-calendar"></i>{{taskItem.date | date : 'mediumDate'}}</strong>
</li>
</ul>
<!-- TaskList Ends HEre -->
</div>
<!-- Content Ends Here -->
</div>
<!-- container -->
</div>
Building a Todo App that adds tasks and deletes them aswell and getting the above error. Below is my html and my angular code. I have checked other blogs and still no valid answer.

How to delete data inside the list using bootstrap modal?

I just want to delete the data inside the table using bootstrap modal, but it seems so hard to find the right way how to do this, here's my sample code. Inside my modal I have an href code that use to delete the data
, it is working outside the modal. I just want to know any solution make this working. thanks.
var app = angular.module('app', ['ui.bootstrap']);
var student = [{
name: 'Andrew'
}, {
name: 'Butler'
}, {
name: 'Cameron'
}, {
name: 'Delo'
}, {
name: 'Emman'
}, {
name: 'Ferbs'
}];
app.filter('startFrom', function() {
return function(input, start) {
if (input) {
start = +start; //parse to int
return input.slice(start);
}
return [];
}
});
app.controller('customersCtrl', function($scope, $timeout) {
$scope.list = student;
$scope.currentPage = 1; //current page
$scope.entryLimit = 10; //max no of items to display in a page
$scope.filteredItems = $scope.list.length; //Initially for no filter
$scope.totalItems = $scope.list.length;
$scope.setPage = function(pageNo) {
$scope.currentPage = pageNo;
};
$scope.filter = function() {
$timeout(function() {
$scope.filteredItems = $scope.filtered.length;
}, 10);
};
$scope.sort_by = function(predicate) {
$scope.predicate = predicate;
$scope.reverse = !$scope.reverse;
};
});
app.filter('startsWithA', function() {
return function(items, letter) {
console.log(items, letter)
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.name.substring(0, 1))) {
filtered.push(item);
}
}
console.log(filtered);
return filtered;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.js"></script>
<div ng-app="app">
<div class="container" ng-controller="customersCtrl">
<div class="row">
<div class="col-12">
<h2 id="titleHead"><center>Student List</center></h2>
</div>
<div class="option-panel">
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form">
<div class="input-group">
<input type="text" ng-model="search" ng-click="filter()" placeholder="Search student" class="form-control" placeholder="Search" name="search">
</div>
</form>
</div>
</div>
<div class="nav navbar-default">
<div class="tab-panel">
<nav>
<ul>
<li class="active" name="active"><a ng-click="letter = '[AB]'">A-B</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[CD]'">C-D</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[EF]'">E-F</a>
</li>
</ul>
</nav>
</div>
</div>
<div id="no-more-tables">
<table class="col-md-12 table-bordered table-condensed cf" ng-show="filteredItems > 0">
<thead class="cf">
<tr>
<th>
<center>Name
<a ng-click="sort_by('first_name');"></a>
</center>
</th>
</tr>
</thead>
<tbody color="#">
<tr ng-repeat="data in filtered = (list | filter:search |orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit |startsWithA:letter |limitTo:entryLimit ">
<td data-title="Name" class="text-center">{{data.name}} <a type="button" class="btn btn-xs btn-primary" style="width: 40%;" href="#" data-toggle="modal" data-target="#myModal" >Delete</a>
</td>
</tr>
</tbody>
</table>
<div class="col-md-12" ng-show="filteredItems == 0">
<div class="col-md-12">
<center>
<h4>No results found</h4>
</center>
</div>
</div>
<div class="col-md-12" ng-show="filteredItems > 0">
<center>
<div pagination="" page="currentPage" on-select-page="setPage(page)" boundary-links="true" total-items="filteredItems" items-per-page="entryLimit" class="pagination-small" previous-text="«" next-text="»"></div>
</center>
</div>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Delete Student</h4>
</div>
<div class="modal-body">
<p>Do you want to delete this student?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" class="btn btn-primary" href="<?php echo base_url(); ?>index.php/students/edit/studentform/{{data.id}}" >Yes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
First I would suggest using $http service, or similar, for removing a record. Also, You'll notice that I made a change to the way your controller was organized by using the controller as syntax, and assigning everything to the controller, and not to the scope. That way you can pass on the controllers scope to directives and such more easily.
The idea is that you preserve an ID of the selected item, so that you can use it later on when you trigger the server delete action.
This can be done in many different ways, this is just one of the ways.
Hope this helps.
var app = angular.module('app', ['ui.bootstrap']);
var student = [{
id: 0,
name: 'Andrew'
}, {
id: 1,
name: 'Butler'
}, {
id: 2,
name: 'Cameron'
}, {
id: 3,
name: 'Delo'
}, {
id: 4,
name: 'Emman'
}, {
id: 5,
name: 'Ferbs'
}];
app.filter('startFrom', function() {
return function(input, start) {
if (input) {
start = +start; //parse to int
return input.slice(start);
}
return [];
}
});
app.controller('customersCtrl', function($http, $timeout) {
var vm = this,
itemId = null;
/**
* Store a selected item's ID
* #param id
*/
vm.getItemId = function (id) {
itemId = id;
};
/**
* Remove the selected item from the list
*/
vm.deleteItemFunction = function () {
console.log('remove', itemId);
// And then something like this
$http.delete('/students/edit/studentform/' + itemId).success(function () {
console.log('successfully removed');
});
};
vm.list = student;
vm.currentPage = 1; //current page
vm.entryLimit = 10; //max no of items to display in a page
vm.filteredItems = vm.list.length; //Initially for no filter
vm.totalItems = vm.list.length;
vm.setPage = function(pageNo) {
vm.currentPage = pageNo;
};
vm.filter = function() {
$timeout(function() {
vm.filteredItems = vm.filtered.length;
}, 10);
};
vm.sort_by = function(predicate) {
vm.predicate = predicate;
vm.reverse = !vm.reverse;
};
});
app.filter('startsWithA', function() {
return function(items, letter) {
console.log(items, letter)
var filtered = [];
var letterMatch = new RegExp(letter, 'i');
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (letterMatch.test(item.name.substring(0, 1))) {
filtered.push(item);
}
}
console.log(filtered);
return filtered;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.js"></script>
<div ng-app="app">
<div class="container" ng-controller="customersCtrl as customer">
<div class="row">
<div class="col-12">
<h2 id="titleHead"><center>Student List</center></h2>
</div>
<div class="option-panel">
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form">
<div class="input-group">
<input type="text" ng-model="search" ng-click="customer.filter()" placeholder="Search student" class="form-control" placeholder="Search" name="search">
</div>
</form>
</div>
</div>
<div class="nav navbar-default">
<div class="tab-panel">
<nav>
<ul>
<li class="active" name="active"><a ng-click="letter = '[AB]'">A-B</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[CD]'">C-D</a>
</li>
<li class="active" name="active"><a ng-click="letter = '[EF]'">E-F</a>
</li>
</ul>
</nav>
</div>
</div>
<div id="no-more-tables">
<table class="col-md-12 table-bordered table-condensed cf" ng-show="customer.filteredItems > 0">
<thead class="cf">
<tr>
<th>
<center>Name
<a ng-click="customer.sort_by('first_name');"></a>
</center>
</th>
</tr>
</thead>
<tbody color="#">
<tr ng-repeat="data in filtered = (customer.list | filter:search |orderBy : customer.predicate : customer.reverse) | startFrom:(customer.currentPage-1)* customer.entryLimit |startsWithA:letter |limitTo: customer.entryLimit ">
<td data-title="Name" class="text-center">
{{data.name}}
<a type="button" class="btn btn-xs btn-primary" style="width: 40%;" href="#" ng-click="customer.getItemId(data.id)" data-toggle="modal" data-target="#myModal">Delete</a>
</td>
</tr>
</tbody>
</table>
<div class="col-md-12" ng-show="customer.filteredItems == 0">
<div class="col-md-12">
<center>
<h4>No results found</h4>
</center>
</div>
</div>
<div class="col-md-12" ng-show="customer.filteredItems > 0">
<center>
<div pagination="" page="customer.currentPage" on-select-page="customer.setPage(page)" boundary-links="true" total-items="customer.filteredItems" items-per-page="customer.entryLimit" class="pagination-small" previous-text="«" next-text="»"></div>
</center>
</div>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Delete Student</h4>
</div>
<div class="modal-body">
<p>Do you want to delete this student?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
<button type="button" class="btn btn-primary" ng-click="customer.deleteItemFunction()">Yes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

AngularJS Factory and Parse.com User Authentication

I am playing around with AngularJS using Parse.com as it's backend and am having an issue when I try go authenticate and deuthenticate with Parse. I am abe to do both these functions, but my views don't update.
app.factory('hsUser', ['$http', function($http){
var dataObject = null;
return {
get: function()
{
var tmpData = Parse.User.current();
console.log(tmpData);
if(tmpData && dataObject == null)
{
dataObject = {};
keys = Object.keys(tmpData);
keys.forEach(function(value)
{
dataObject[value] = tmpData[value];
});
console.log(dataObject);
}
return dataObject;
},
authenticate: function(username, password)
{
console.log('auth');
Parse.User.logIn(username, password, {
success: function(userData) {
dataObject = {};
keys = Object.keys(userData);
keys.forEach(function(value)
{
dataObject[value] = userData[value];
});
},
error: function(userData, errorData) {
console.log(errorData);
}
});
},
deauthenticate: function()
{
Parse.User.logOut();
dataObject = Parse.User.current();
},
doRegister: function(registration)
{
console.log(registration);
return {
success: true
}
}
}
}]);
Here are my controllers.
app.controller('HeaderController', ['hsConfig','hsUser', function( hsConfig, hsUser)
{
this.config = hsConfig.get();
this.user = hsUser.get();
}]);
app.controller('AuthController', ['hsUser', function( hsUser)
{
this.user = hsUser.get();
this.authUser = {
emailAddress: "testinguser",
password: "testinguser",
remember: false,
}
this.authenticate = function()
{
hsUser.authenticate(this.authUser.emailAddress, this.authUser.password);
}
this.deauthenticate = function()
{
this.user = hsUser.deauthenticate();
console.log('Deauthenticated')
}
}]);
Here is the HTML for the directive that creates the navbar
<div class="header" ng-controller="HeaderController as headCtrl">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<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="/">{{ headCtrl.config.brand }}</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right" ng-hide="headCtrl.user">
<li class="dropdown" ng-controller="AuthController as authCtrl">
<a class="dropdown-toggle" href data-toggle="dropdown">
Sign In
<strong class="caret"></strong>
</a>
<div class="dropdown-menu auth-form-container" style="padding: 15px; padding-bottom: 0px;" >
<form role="form" ng-submit="authCtrl.authenticate();">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" placeholder="Enter email" ng-model="authCtrl.authUser.emailAddress" >
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" placeholder="Password" ng-model="authCtrl.authUser.password">
</div>
<div class="form-group checkbox">
<label>
<input type="checkbox" ng-model="authCtrl.authUser.remember"> Remember Me
</label>
</div>
<div class="form-group">
<button class="btn btn-primary btn-full">Sign In</button>
</div>
</form>
</div>
</li>
<li class="divider-vertical"></li>
<li>Register</li>
</ul>
<ul class="nav navbar-nav navbar-right" ng-show="headCtrl.user">
<li>Profile</li>
<li class="divider-vertical"></li>
<li ng-controller="AuthController as authCtrl">
<a href ng-click="authCtrl.deauthenticate();">Sign Out</a>
</li>
</ul>
</div>
</div>
</nav>
</div>
The entire project including Parse keys can be found here. I'll delete the keys once I figure out wtf my problem is.
https://github.com/thenetimp/hackerspace
If anyone can point me into what I am doing wrong and explain it so I can understand what I need to do with other Models I would greatly appreciate it.
whenever you update the model outside of angulars context, I.e in the callback of a promise, you need to use $scope.apply to notify angular.

Resources