20

I was trying to test if my ng-click binding was working -- but I seem to be running into a more-fundamental problem -- how to see what is happening (or not).

My usual 'crude' debugging methods, alert() and console.log(), do not seem to be available.

Is it possible to get access to these functions or something like them from within an Angular app?

The plnkr example below seems to show the click event 'working' -- effecting objects in my component -- but my function calls to alert() and log() seem to be getting ignored.

With that said, is there a way to get some kind of error message when I call a probably-nonexistent function? The Chrome console log does not seem to show anything.

https://embed.plnkr.co/Dvadi8mWlUqTUW865UsI/

I think the 'possibly-duplicate' question is similar, but it does not not actually talk about alert() or log() in the title, and the various partial answers seem generally geared towards Angular 1.x and controllers -- I do not have a controller.

So part of this question is -- do I need a controller? It looks like there might be an easy way to 'decorate' my app, but I only have modules and classes right now, no explicit controller.

Thank you.


I think the best answer is at bottom -- 'ng-click' must be provided an expression, not a function call.

and here is some properly formatted code to show how to call these basic functions in Angular2 (for other newbies out there):

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    //template:`<h2>Hello, world</h2>` ,
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'Quiz Tool';
    quiz = new Quiz();

    doAlert(){
        console.log('log: test log, yo...'); // black
        console.debug('debug: test log, yo...'); // blue
        console.warn('warn: test log, yo...'); // yellow
        console.info('info: test log, yo...'); // black (with 'i' icon)
        console.error('error: test log, yo...'); // red
        alert('test...');
    }
}

and call the doAlert() method from your HTML:

<button (click)="doAlert();count = count + 1" ng-init="count=0">Increment</button>

Thank you!

Peter Smith
  • 534
  • 2
  • 8
  • 19
  • 5
    Both of that is basic JS provided tools. It should be available! – Smit Mar 06 '17 at 03:31
  • 1
    Possible duplicate of [Why does ng-click not work in case-1, but does in case-3?](http://stackoverflow.com/questions/23725312/why-does-ng-click-not-work-in-case-1-but-does-in-case-3) – Sachila Ranawaka Mar 06 '17 at 03:47
  • 2
    `alert()` and `console.log()` are part of the global context. JavaScript expressions are evaluated against the `global` window. In AngularJS, expressions are evaluated against a `scope` object. See [AngularJS Expressions vs. JavaScript Expressions](https://docs.angularjs.org/guide/expression#angularjs-expressions-vs-javascript-expressions). – georgeawg Mar 06 '17 at 04:03
  • ok, so i'm using Angular2, so no real/explicit controller yet. it seems you can call both these functions from within a function of your component -- somehow they're available there but not in your browser window, i.e. from your DOM/html element -- so write simple wrapper functions and call `doAlert()` and `doLog()`: `@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { doAlert(){ alert('test...'); } doLog(){ console.log('test log, yo...'); } } ` – Peter Smith Mar 07 '17 at 18:56

5 Answers5

20

ng-click must be call an expression. AngularJS expressions do not have direct access to global variables like window, document or location. This restriction is intentional. It prevents accidental access to the global state – a common source of subtle bugs.

digit
  • 4,479
  • 3
  • 24
  • 43
17

alert() and console.log(), do not seem to be available.

Both alert() and console.log() are evaluated against the global window object. On the other hand ng-click is an AngularJS Expression and is evaluated against the scope associated with it which does not have any direct access to the window object. Thus they are not available inside scope.

AngularJS Expressions vs. JavaScript Expressions

Context: JavaScript expressions are evaluated against the global window. In AngularJS, expressions are evaluated against a scope object.

AngularJS provides a service called $log for that purpose. You can use $log service like the following:

var myApp = angular.module('myApp',[]);

myApp.controller('myController', ['$scope', '$log', function($scope, $log){
  $scope.TestClick = function(){
    $log.log('You have clicked');
  }
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myController">
  <input type="button" value="Click" ng-click="TestClick()"/>
</div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
4

Both of that is basic JS provided tools. It should be available!

If you wish to console or alert from HTML, it probably not a good way to do it. Nor i think it is possible.

You may choose to attach your HTML to a controller and then move the Console.log or alert to that controller. And It will work as expected.


AngularJS Expressions vs. JavaScript Expressions

AngularJS expressions are like JavaScript expressions with the following differences:

  • Context: JavaScript expressions are evaluated against the global window. In AngularJS, expressions are evaluated against a scope object.

- AngularJS Developer Guide - AngularJS Expressions vs. JavaScript Expressions

Smit
  • 2,078
  • 2
  • 17
  • 40
4

A quick and dirty way to get access to alert and console.log from within a (click) or similar handler, is to alias alert and console into the @Component object:

@Component({
  // ...
})
export class MyComponent {
    constructor() {
        // ...
        this.console = window.console
        this.alert = window.alert
    }
}
DomQ
  • 4,184
  • 38
  • 37
2

When you call alert or console.log from ng-click, it looks for that method on the $scope or an angular expression, and it's not there.

In your example only count = count + 1 is expression and others are neither function or expression. That's why only count get increased and console or alerts not working.

If you need to use alerts and console logs then use it inside the scope method.

Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80