I have a problem using AngularJS on Safari running on Windows 7.
Problem appears on line 11413 in angular.js
function consoleLog(type) {
var console = $window.console || {},
logFn = console[type] || console.log || noop,
hasApply = false;
// Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
// The reason behind this is that console.log has type "object" in IE8...
try {
hasApply = !!logFn.apply;
} catch (e) {}
if (hasApply) {
return function() {
var args = [];
forEach(arguments, function(arg) {
args.push(formatError(arg));
});
return logFn.apply(console, args); <------------- HERE PROBLEM APPEARS
};
}
Error: angular.js:11413setting a property that has only a getter
Can't find any solution to that in google. Does anybody know how to solve this? Using latest AngularJS v1.3.3
Here is the most simple code causing error.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="angular-route.min.js"></script>
</head>
<script>
var g_app = angular.module('cc_app', ['ngRoute']);
g_app.controller('navigation_controller', ['$scope', function($scope) {
$scope.templates =
[ { name: 'template1.html', url: 'template1.html'},
{ name: 'template2.html', url: 'template2.html'} ];
$scope.template = $scope.templates[0];
}]);
</script>
<body ng-app="cc_app" ng-controller="navigation_controller">
<select ng-model="template" ng-options="t.name for t in templates">
<option value="">(blank)</option>
</select>
url of the template: <tt>{{template.url}}</tt>
<hr/>
<div class="slide-animate-container">
<div class="slide-animate" ng-include="template.url"></div>
</div>
</body>
</html>
example is taken from https://docs.angularjs.org/api/ng/directive/ngInclude
It works fine on Chrome, but causes mentioned error on Safari.
BTW: Error is caused by ng-include.
UPDATE
It works as soon as I remove jquery.
Fixed by changing ordering of script includes. Looks like a conflict.
Related
While I was experimenting with AngularJs and JavaScript, I have tried to call a $scope from an outside JavaScript function, but I got the following Error:
"Uncaught TypeError: Cannot read property 'message' of undefined" .
Here is my code :
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module('app', []);
var msg = "new message"
app.controller('ctrl', ['$scope', function ($scope) {
$scope.message = msg;
}]);
function xfunc(){
var data = angular.
element(document.querySelector('[ng-controller="ctrl"]')).
scope().message;
return data
}
if (typeof 'xfunc()' !== 'undefined') {
console.log(xfunc());
}else{
console.log("the type of is : ", + typeof 'xfunc()')
}
</script>
</head>
<body>
<div ng-app="app" ng-controller="ctrl">
{{message}}
</div>
</body>
</html>
I did call xfunc() from console and it works fine with no errors.
Please, does anyone know the cause of the error? And is it possible to do it with just pure Javascript and AngularJS, with no third party library? (if possible of course)
Thanks in advance!
the problem was that the function being called before AngularJs was bootstrapped , so the solution is that i have added :
document.addEventListener("DOMContentLoaded", function(event) {
});
to load "xfunc()" after the "body" is loaded , so here is my final code :
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module('app', []);
var msg = "new message"
app.controller('ctrl', ['$scope', function ($scope) {
$scope.message = msg;
}]);
function xfunc(){
var data = angular.
element(document.querySelector('[ng-controller="ctrl"]')).
scope().message;
return data
}
document.addEventListener("DOMContentLoaded", function(event) {
if (typeof 'xfunc()' !== 'undefined') {
console.log(xfunc());
}else{
console.log("the type of is : ", + typeof 'xfunc()')
}
});
</script>
</head>
<body>
<div ng-app="app" ng-controller="ctrl">
{{message}}
</div>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en-US" ng-app="theapp">
<head>
<meta charset="UTF-8">
<title>asd</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script type="text/javascript">
var mainScope;
angular.module('theapp', []).controller('MainCtrl', function($scope, $injector) {
$scope.demo = "test123";
$scope.scopecomp = function(){
angular.element(document).injector().invoke(function ($compile) {
$compile(document.body)($scope);
});
}
mainScope = $scope;
});
function addDiv(){
var $newDiv = $('<div>{{demo}}</div>');
$(document.body).append($newDiv);
}
function comp(){
mainScope.comp();
}
</script>
</head>
<body ng-controller="MainCtrl" ng-change="comp();">
<h1>{{demo}}</h1>
<input type="text" id="compText" />
<button onclick="addDiv();">add</button>
<button ng-click="scopecomp();">compile with ng-click (works fine)</button>
<button onclick="comp();">compile with onlick (not working)</button>
</body>
</html>
I want to run the comp() function anywhere in my project. I tried button onclick,it didn't work but ng-click works fine. What is the problem ? Why onclick doesn't work ?
New : changeContent function added.
<!DOCTYPE HTML>
<html lang="en-US" ng-app="theapp">
<head ng-controller="MainCtrl as main">
<meta charset="UTF-8">
<title>asd</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script type="text/javascript">
angular.module("theapp", []).controller("MainCtrl", MainController);
MainController.$injector = ['$timeout'];
var vm;
function MainController($timeout) {
vm = this;
vm.post = null;
function loadStuff(){
$timeout(function() {
vm.post = {
title: "Post Title",
content: "Post Content"
};
}, 1000);
}
loadStuff();
}
function changeContent(){
vm.post.content = "<div>new content </div>";
}
</script>
</head>
<body ng-controller="MainCtrl as main">
<p ng-hide="main.post">Loading...</p>
<h3>{{main.post.title}}</h3>
<p>{{main.post.content}}</p>
<button onclick="changeContent();">change</button>
</body>
</html>
New bodyController()
function bodyController($scope, $injector) {
_bodyController = this;
$scope.title = "ttt";
$scope.content = "aaa";
$scope.comp = function(){
angular.element(document).injector().invoke(function ($compile) {
$compile(document.body)($scope);
});
}
myAPP.Run(function(){
$scope.title = globalOBJ.title;
$scope.content = globalOBJ.content;
$scope.comp();
});
}
You should change your '' to this:
<body ng-controller="MainCtrl" ng-model="demo" ng-change="comp();">
If you check the url from the first line of the error log: https://docs.angularjs.org/error/$compile/ctreq?p0=ngModel&p1=ngChange. The problem is explained:
Controller 'ngModel', required by directive 'ngChange', can't be
found! Description This error occurs when HTML compiler tries to
process a directive that specifies the require option in a directive
definition, but the required directive controller is not present on
the current DOM element (or its ancestor element, if ^ was specified).
To resolve this error ensure that there is no typo in the required
controller name and that the required directive controller is present
on the current element.
The directive 'ng-change' require a 'ng-model' to work properly, that is why you are getting an compile error.
Now your second question, "Why onclick doesn't work ?". You should never manipulate the DOM from the controller, if you have to do that use a directive. When you call "scopecomp()" from the ng-click that method is invoked from "within" the angular engine, it will fire an digest cycle which will process the "html" (it's more than that, I'm trying to keep it simple) and print what you expect, but when you add "{{demo}}" directly to the DOM, that variable will not be processed.
There is no need to change the DOM manually to do what you are looking for, check the snippet below. I simulated your "database request" with a timeout function.
angular.module("app", [])
.controller("MainController", MainController);
MainController.$injector = ['$timeout'];
function MainController($timeout) {
var vm = this;
vm.post = null;
function loadStuff() {
$timeout(function() {
vm.post = {
title: "Post Title",
content: "Post Content"
};
}, 1000);
}
loadStuff();
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as main">
<p ng-hide="main.post">Loading...</p>
<h3>{{main.post.title}}</h3>
<p>{{main.post.content}}</p>
</div>
$FirebaseJS.Run(function(){
$scope.$apply(function(){
$scope.obj = globalOBJ;
});
});
Finally I got it.
I am trying to implement Modal popup on an image click by using Bootstrap Lightbox, but I'm not able to achieve the same. I followed an example which has identical code as below. I have downloaded the Lightbox components(*.lightbox.js and *.lightbox.css) and placed in the directory where my below HTML file resides. Can someone please help me out in fixing this issue.
<!doctype html>
<html ng-app="myApp">
<head>
<title>Sandesh</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="angular-bootstrap-lightbox.js"></script>
<link rel="stylesheet" href="angular-bootstrap-lightbox.css">
<link rel="stylesheet" type="text/css" href="bootstrap.min.css" />
</head>
<body ng-controller="GalleryCtrl">
<ul>
<li ng-repeat="image in images">
<a ng-click="openLightboxModal($index)">
<img ng-src="{{image.thumbUrl}}" class="img-thumbnail">
</a>
</li>
</ul>
<script>
var app = angular.module('myApp',['bootstrapLightbox'])
.controller('GalleryCtrl', function ($scope, Lightbox) {
$scope.images = [
{
'url': '9RyWebbb.jpg',
'thumbUrl': 'Thumb_9RyWebbb.jpg'
}
];
$scope.openLightboxModal = function (index) {
Lightbox.openModal($scope.images, index);
};
});
</script>
</body>
</html>
First, confirm that the name of the modu:le is "bootstrapLightbox". If it actually is, import it in the module via:
var app = angular.module('myApp',['bootstrapLightbox']);
Determine if you want to define controllers, services and directives against the variable, or against the methods:
var app = angular.module('myApp',['bootstrapLightbox']);
app.controller('GalleryCtrl', function ($scope, Lightbox) {
// etc
});
or
angular.module('myApp',['bootstrapLightbox'])
.controller('GalleryCtrl', function ($scope, Lightbox) {
// etc
});
Then, this maybe is less important, but a good tip to show: if you use some object only inside your JS code, without affecting directly the DOM, better use plain variables instead of declaring them on the $scope. Here, you use $scope to declare an array or "image" objects, but then only use it inside your lightbox instead of directly using it in the DOM.
So, I'd turn this...
$scope.images = [
{
'url': '9RyWebbb.jpg',
'thumbUrl': 'Thumb_9RyWebbb.jpg'
}
];
$scope.openLightboxModal = function (index) {
Lightbox.openModal($scope.images, index);
};
... into this:
var images = [
{
'url': '9RyWebbb.jpg',
'thumbUrl': 'Thumb_9RyWebbb.jpg'
}
];
$scope.openLightboxModal = function (index) {
Lightbox.openModal(images, index);
};
I hope it was useful for you!
Problem solved on including additional files as mentioned below:
<!doctype html>
<html ng-app="myApp">
.....
<link rel="stylesheet" type="text/css" href="ui-bootstrap-csp.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.3.3/ui-bootstrap-tpls.min.js"></script>
....
....
</html>
Also note that the order in which we include these files also matters; for example in this case the pop-up functionality doesn't work if we add 'ui-bootstrap-tpls.min.js' before 'ui-bootstrap.min.js'
Anyways thanks all for your valuable suggestions :)..cheers!
I have the below code in a html page, running it though I keep getting an error stating that "angular is not defined" I have included angular in the head so i'm not sure why it can't locate it, the url to angular i'm also able to hit directly.
<!DOCTYPE>
<html ng-app="test">
<head>
<title>
<script src="https://code.angularjs.org/1.2.25/angular.js"></script>
</title>
</head>
<body ng-controller="TestController">
<form name="CopyFile" ng-submit="copy(fileId)">
<input type="text" ng-model="fileId"/>
<input type="submit" value="Copy"/>
</form>
<div>{{ message }}</div>
<div>{{ error }}</div>
<script type="text/javascript">
(function () {
var app = angular.module("test", []);
var testController = function ($scope, $http) {
$scope.copy = function (fileId) {
$http.get("http://localhost/test/copy/prod.aspx/ToProd?fileId=" + fileId)
.then(onComplete, onError);
};
var onComplete = function (response) {
$scope.message = response;
};
var onError = function (reason) {
$scope.error = "File could not be copied " + reason;
};
};
app.controller("TestController", ["$scope", "$http"], testController);
} ());
</script>
</body>
</html>
This may not be the cause but you don't want your angular include inside of your title. It should be something more like this:
<!DOCTYPE>
<html ng-app="test">
<head>
<title>My Page</title>
<script src="https://code.angularjs.org/1.2.25/angular.js"></script>
</head>
.....
You gave <script> inside <title>?
<title>
<script src="https://code.angularjs.org/1.2.25/angular.js"></script>
</title>
Please remove it outside.
I'm trying to write a sample AngularJS, and SpringMVC project. The spring methods works fine, but I have a problem with declaraton of function in my site controller. My app should return a word from text input, but when I click the button, I've got this error:
[13:23:58.900] "Error: fnPtr is not a function
parser/_functionCall/<#http://localhost:8080/example/resources/js/Angular/angular.js:6542
ngEventDirectives[directiveName]</</</<#http://localhost:8080/example/resources/js/Angular/angular.js:13256
Scope.prototype.$eval#http://localhost:8080/example/resources/js/Angular/angular.js:8218
Scope.prototype.$apply#http://localhost:8080/example/resources/js/Angular/angular.js:8298
ngEventDirectives[directiveName]</</<#http://localhost:8080/example/resources/js/Angular/angular.js:13255
createEventHandler/eventHandler/<#http://localhost:8080/example/resources/js/Angular/angular.js:2095
forEach#http://localhost:8080/example/resources/js/Angular/angular.js:130
createEventHandler/eventHandler#http://localhost:8080/example/resources/js/Angular/angular.js:2094
"
This is my index.html:
<!DOCTYPE html>
<html lang="en" ng-app="Apken">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="resources/js/Angular/angular.js"></script>
<script src="resources/js/controler.js"></script>
</head>
<body ng-controller="theNamer">
<div class="input-append">
<input style="width:358px;" class="span2" type="text" ng-model="myName" required min="1" />
<button class="btn btn-primary" ng-disabled="!myName" ng-click="send()">Click!</button>
</div>
<ul>
<li ng-repeat="name in names">{{name}}</li>
</ul>
</body>
</html>
And controler.js:
function theNamer ($scope,$http){
$scope.myName='aa';
$scope.fetchList=new function()
{
$http.get('ca/list.json').success(function(thList){
$scope.names = thList;
});
}
$scope.send=new function()
{
$http.post('ca/set/3').success(function(){
$scope.fetchList;
});
}
$scope.fetchList;
}
var Apken = angular.module('Apken',[]);
Apken.controller('theNamer', theNamer);
I've noticed, that must be a some kind of problem with function declaration in the ng-click value. On site startup controler.js works fine, but it crashes, when I click the button.
Just wanted to add for anybody receiving this error, it can also be seen if you, like me, make the n00b mistake of creating a variable with the same name as function (the function being called from ng-click:
$scope.addTask = {};
$scope.addTask = function() {};
I have tested your code. Using AngularJS 1.0.7, the error disappears when you replace
$scope.send = new function() {
with
$scope.send = function () {
and same applies to fetchList.
I guess you mixed the two syntaxes function(*args*) { *body* } and new Function(*args*, *body*). Check on MDN: Function.
You have also to change your code in order to get your fetchList properly called:
function theNamer($scope, $http) {
$scope.myName = 'aa';
$scope.fetchList = function() {
$http.get('ca/list.json').success(function(thList) {
$scope.names = thList;
});
};
$scope.send = function() {
$http.post('ca/set/3').success(function() {
$scope.fetchList();
});
};
$scope.fetchList();
}