AngularJS is new to me (and difficult). So I would like to learn how to debug.
Currently I'm following a course and messed something up. Would like to know how to interpret the console error and solve the bug.
plnkr.co code
index.html
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ username }}
<form action="searchUser" ng-submit="search(username)">
<input type="search"
required placeholder="Username to find"
ng-model="username"/>
<input type="submit" value="search">
</form>
<div>
<p>Username found: {{user.name + error}}</p>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}"/>
</div>
</body>
</html>
script.js
(function() {
var app = angular.module("githubViewer", []);
var MainController = function($scope, $http) {
var onUserComplete = function(response) {
$scope.user = response.data;
};
var onError = function(reason) {
$scope.error = "could not fetch data";
};
$scope.search = function(username) {
$http.get("https://api.github.com/users/" + username)
.then(onUserComplete, onError);
};
$scope.username = "angular";
$scope.message = "GitHub Viewer"; };
app.controller("MainController", MainController);
}());
The console only says
searchUser:1 GET http://run.plnkr.co/lZX5It1qGRq2JGHL/searchUser? 404
(Not Found)
Any help would be appreciated.
In your form, action you have written this
<form action="searchUser"
What this does is it will try to submit to a url with currentHostName\searchUser, so in this case your are testing on plunker hence the plunker url.
You can change the url where the form is submitted. Incase you want to search ajax wise then you dont even need to specify the action part. You can let your service/factory make that call for you.
Though not exactly related to debugging this particular error, there is a chrome extension "ng-inspector" which is very useful for angularJS newbies. You can view the value each of your angular variable scopewise and their value. Hope it helps!
Here is the link of the chrome extension: https://chrome.google.com/webstore/detail/ng-inspector-for-angularj/aadgmnobpdmgmigaicncghmmoeflnamj?hl=en
Since you are using ng-submit page is being redirected before the response arrives and you provided any action URL as searchUser which is not a state or any html file so it being used to unknown address, it is async call so it will take some time you can use input types as button instead of submit.
Here is the working plunker.
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ username }}
<form >
<input type="search"
required placeholder="Username to find"
ng-model="username"/>
<input type="button" ng-click="search(username)" value="search">
</form>
<div>
<p>Username found: {{user.name + error}} {{user}}</p>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}"/>
</div>
</body>
</html>
Related
I am facing a strange problem with the below code..
whenever I remove the ng-controller="page" from the body tag, the expressions start getting evaluated. But on applying this controller on body tag, the expressions tend to get printed as text rather than being evaluated.
Below is my relevant code (Snippet):
<html ng-app="app">
<head>
<!-- links removed for brevity -->
<script>
var app = angular.module('app',[]);
app.controller('page',function($scope){
$scope.segment.name = 'asdf';
});
</script>
</head>
<body ng-controller="page" style="padding:0px;">
<!-- additional markup removed for brevity -->
<form class="navbar-form navbar-right" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Portal ID" ng-model="page.segment.name"/>
</div>
<button class="btn btn-default">Search {{page.segment.name}}</button>
</form>
</body>
</html>
I am possibly making some blunder in the above code as the below code which I wrote as proof of concept works well.
POC code (Snippet):
<html ng-app="app">
<head>
<!-- links removed for brevity -->
</head>
<body ng-controller="page">
<a>Name : {{page.segment.name}}</a>
<input type = "text" ng-model="page.segment.name"/>
</body>
<!-- links removed for brevity -->
<script>
var app = angular.module('app',[]);
app.controller('page',['$scope',function($scope){}]);
</script>
</html>
Kindly help
Thanks in advance..
You are probably getting an error in the console. I would guess it's something similar to "Cannot set property 'name' of undefined." What you are doing here is not valid:
$scope.segment.name = 'asdf';
You need to either do this:
$scope.segment = {};
$scope.segment.name = 'asdf';
Or this:
$scope.segment = { name: 'asdf' };
You have to create the segment object explicitly before you attempt to set properties on it.
I'm learning Angular through a YouTube tutorial series. In the tutorial, you create username and password inputs, and then you use a controller and ngRoute to bring up a dashboard.html page when successful credentials are used. The problem is that when clicking the button, nothing happens, whether the proper credentials are entered or not. Everything is working on the tutorial, and I have triple checked the code thoroughly, and mine looks just like the code in the tutorial. I'm sure I must be missing something though.
What I think:
There is an issue with the click event firing, so maybe there is an issue with how I am calling the function?
The tutorial uses an older angular version (1.3.14), and maybe things have changed? I'm using 1.4.9, but I looked up the api data for the ng-click directive, and all seems well. I also tried using the older version to no avail.
I'm doing something wrong with ngRoute, potentially $scope misuse?
I am inserting all of the code below. Thanks for taking a look!
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Place Title Here</title>
<meta charset = "utf-8"/>
<meta http-equiv="X-UA-compatible" content="IE-edge, chrome=1">
<meta name = "viewport" content = "width = device - width, initial-scale = 1.0"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script src="controller.js"></script>
</head>
<body ng-app="mainApp">
<div ng-view></div>
</body>
</html>
login.html
<div ng-controller="loginCtrl"></div>
<form action="/" id="myLogin">
Username: <input type="text" id="username" ng-model="username"><br>
Password: <input type="password" id="password" ng-model="password"><br>
<button type="button" ng-click="submit()">Login</button>
</form>
controller.js
var app = angular.module('mainApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'login.html'
})
.when('/dashboard', {
templateUrl: 'dashboard.html'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('loginCtrl', function($scope, $location) {
$scope.submit = function() {
var uname = $scope.username;
var password = $scope.password;
if($scope.username == 'admin' && $scope.password == 'admin') {
$location.path('/dashboard');
}
else {
alert('Nope')
}
};
});
dashboard.html
Welcome User.
Your form needs to be inside the div with ng-controller
<div ng-controller="loginCtrl">
<form action="/" id="myLogin">
Username: <input type="text" id="username" ng-model="username"><br>
Password: <input type="password" id="password" ng-model="password"><br>
<button type="button" ng-click="submit()">Login</button>
</form>
</div>
Otherwise it won't have access to the submit() function.
I am trying to validate a number input using angularjs.
The page works as desired by itself, however it does not work when I call the page with ajax.
Any help or advice would be appreciated!
Working angularjs jlgtest3.jsp ...
<div ng-app="total">
<script>
angular.module('total', [])
.controller('totalController', ['$scope', function($scope) { }]);
</script>
<form name="totalForm" ng-controller="totalController">
<input name="totalHours" ng-model="total" type="number" value="" />
<p ng-show="totalForm.totalHours.$error.number">Not valid number!</p>
</form>
</div>
</html>
Not working with ajax call (jlgtest4.jsp calling jlgtest3.jsp)...
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
function newajax() {
var xRequest1;
if(window.XMLHttpRequest)
{
xRequest1=new XMLHttpRequest();
} else {
xRequest1=new ActiveXObject("Microsoft.XMLHTTP");
}
xRequest1.onreadystatechange=function ()
{
if((xRequest1.readyState==4) && (xRequest1.status==200))
{
document.getElementById("test").innerHTML=xRequest1.responseText;
}
}
var urlencode = "jlgtest3.jsp";
xRequest1.open("post",urlencode,true);
xRequest1.send();
}
</script>
</head>
<input type="button" onclick="newajax()" value="button" />
<div id="test">
</div>
</html>
I attempted the angular ajax call as some people suggested, but I couldnt get it to work...
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<div ng-app="total">
<script>
angular.module('total', [])
.controller('totalController', ['$scope', function($scope) {
$http.POST("jlgtest3.jsp").then(function(response) {
$scope.test = response.data;
});
}]);
</script>
<div ng-controller="totalController">
<input type="button" value="button" />
{{test}}
</div>
</div>
</html>
If you're using Angular, you should consider using the $http service or even the $resource service. These both abstract ajax requests into a much simpler form. So instead of
xRequest1.open("post",urlencode,true);
xRequest1.send();
...etc...
You might have something like:
$http.POST(urlencode).then(function(response) {
document.getElementById("test").innerHTML=response.data;
// do other stuff with the response
});
And that will encapsulate essentially your entire newajax function.
As for #messerbill 's answer, you should not be making $http calls in your controller. These are better utilized within a service or factory that you then inject into your controller. Controllers are for business logic and should not deal with fetching and sending data.
you also can use a standart Ajax call but better use the $http angular way. You should call it inside of your angular controller.
XMLHttpRequest is an object used by Ajax - https://en.wikipedia.org/wiki/XMLHttpRequest
https://docs.angularjs.org/api/ng/service/$http
updated answer
Why dont you use Angular in the way its meant to be used? You should send your post inside of you angular service or controller. Don't manipulate your DOM if you use AngularJS like you did here:
document.getElementById("test").innerHTML=response.data;
istead you should do it that way:
angular.module('total', [])
.controller('totalController', ['$scope', function($scope) {
$http.POST("yourURL").then(function(response) {
$scope.test = response.data;
});
}]);
//template
<input type="button" value="button" />
<div ng-controller="totalController">
{{test}}
</div>
</html>
I have not tested it yet, but it should work - next time create a fiddle ;)
I posted this question again, but a little bit more simplified and Moncef Hassein-bey was able to answer my question Use Ajax to put external angularjs element in html page
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) { }]);
</script>
<script>
function newajax() {
var xRequest1;
xRequest1=new XMLHttpRequest();
xRequest1.onreadystatechange=function ()
{
if((xRequest1.readyState==4) && (xRequest1.status==200))
{
document.getElementById("test").innerHTML=xRequest1.responseText;
angular.bootstrap(document.getElementById('test'), ['myApp']);
}
}
xRequest1.open("post","jlgtest.html",true);
xRequest1.send();
}
</script>
<input type="button" value="button" onClick="newajax()" />
<div id="test">
</div>
</div>
</html>
Basically I needed to add the angular.bootstrap line of code, and the angular.module(... script needed to be in my main page
this is the called page code...
<html>
<div ng-app="myApp">
<form name="myForm" ng-controller="myController">
<input name="numberField" ng-model="myModel" type="number" value="" />
<p ng-show="myForm.numberField.$error.number">Not valid number!</p>
</form>
</div>
</html>
I am a beginner with MEAN Stack development. I was trying out to play around with some angular stuff but got completely messed up the the controllers.
Here is my main html file
<!--main.html-->
<html>
<head>
<title>Chirp</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="javascripts/chirpApp.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="stylesheets/style.css">
</head>
<body ng-app="chirpApp">
<div id='main' class="container" ng-controller="mainController">
<div class="col-md-offset-2 col-md-8">
<div class="clearfix">
<form ng-Submit="post()">
<input required type="text" class="form-control" placeholder="Your name" ng-model="newPost.created_by" />
<textarea required class="form-control" maxlength="200" rows="3" placeholder="Say something" ng-model="newPost.text"></textarea>
<input class="btn submit-btn pull-right" type="submit" value="Chirp!" />
</form>
<div id="post-stream">
<h4>Chirp Feed</h4>
<div class="post" ng-repeat="post in posts | orderBy:'created_at':true" ng-class-odd="'odd'" ng-class-even="'even'">
<p>{{post.text}}</p>
<small>Posted by #{{post.created_by}}</small>
<small class="pull-right">{{post.created_at | date:"h:mma 'on' MMM d, y"}}</small>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
I have created another html file for registration. here is the code for it.
<!--register.html-->
<html>
<head>
<title>Chirp</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="javascripts/chirpApp.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="stylesheets/style.css">
</head>
<body ng-app="chirpApp">
<div id='main' class="container" ng-controller="authController">
<form class="form-auth" ng-submit="register()">
<h2>Register</h2>
<p class="text-warning">{{error_message}}</p>
<input type="username" ng-model="user.username" placeholder="Username" class="form-control"><br>
<input type="password" ng-model="user.password" placeholder="Password" class="form-control"><br>
<input type="submit" value="Register" class="btn btn-primary" />
</form>
</div>
</body>
</html>
I have created two separate controllers for registration and posts. the first controller works nicely but whenever I am trying to add a second controller I am getting an error message. Here is the code for my controllers.
//chirpApp.js
var app = angular.module('chirpApp', []);
app.controller('mainController', function($scope){
$scope.posts = [];
$scope.newPost = {created_by: '', text: '', created_at: ''};
$scope.post = function(){
$scope.newPost.created_at = Date.now();
$scope.posts.push($scope.newPost);
$scope.newPost = {created_by: '', text: '', created_at: ''};
};
});
app.controller('authController', function($scope){
$scope.user = {username: '', password: ''};
$scope.error_message = '';
$scope.login = function(){
//placeholder until authentication is implemented
$scope.error_message = 'login request for ' + $scope.user.username;
};
$scope.register = function(){
//placeholder until authentication is implemented
$scope.error_message = 'registeration request for ' + $scope.user.username;
};
});
I am getting the following error in the chrome console :
Error: [ng:areq] http://errors.angularjs.org/undefined/ng/areq?p0=authController&p1=not%20a%20function%2C%20got%20undefined
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:6:453
at tb (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:18:250)
at Oa (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:18:337)
at $get (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:61:288)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:48:476
at q (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:7:367)
at S (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:48:342)
at h (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:43:59)
at h (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js:43:76)
main.html works fine and the data is being binded successfully.
The issue is with the register.html page. I suppose the authController is not getting binded
Can anyone suggest me the best way of implementing the same? And why the controller is getting undefined?
Try the following checklist:
angularjs lib is included in
ng-app=".." directive is in index.html
..path/to/module and other controllers in index.html
module and controllers defined correctly (spelling, syntax etc)
Controller example (if not using global angular var:
app.controller('AppController', ['$http', '$scope', '$log',
function($http, $scope, $log) {
// TODO: implement
}
]);
Hope this helps.
Here is the plunker of your files
http://embed.plnkr.co/6jNXImBddYqjK23FCWUy/preview
Your application works as expected. Please check your core files is loaded or not.
Hope this helps
your code
When you create a new controller with the AngularJS Controller Sub-Generator you have to reboot Grunt.
I have a simple view with an input text field in which the user enter his name and a controller must retrieve that value an assign to employeeDescription variable. The problem is that the ng-model value (from the input) doesn't come to the controller, I just tried using $watch like Radim Köhler explains Cannot get model value in controller method in angular js but doesn't work. I just think it must be simple.
Also a just try by retrieving the name variable (ng-model) from the $scope, like $scope.employeeDescription = $scope.name; but doesn't retrieve value and the Google chrome console doesn't give me any output about that. Any solution?
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
</head>
<body ng-app='angularApp'>
<div ng-controller='nameController'>
<div>
Name <input type="text" ng-model='name' />
</div>
Welcome {{employeeDescription}}
</div>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
app.js
(function(angular) {
var myAppModule = angular.module('angularApp', []);
myAppModule.controller('nameController', function($scope) {
$scope.employeeDescription = name;
});
})(window.angular);
Your code should fail, cause the 'name' variable in the controller is never defined. You have two variables defined in your code: $scope.employeeDescription and $scope.name (defined in the ng-model of the input). Note that '$scope.name' is being defined, not 'name'.
My suggestion is to leave only one variable:
<div>
Name <input type="text" ng-model='employeeDescription' />
</div>
myAppModule.controller('nameController', function($scope) {
$scope.$watch('employeeDescription', function() {
console.log($scope.employeeDescription);
});
});