angular / angular.js

AngularJS - HTML enhanced for web apps!
https://angularjs.org
MIT License
58.88k stars 27.53k forks source link

$log conflicts with other code that messes with console #9689

Open oliversalzburg opened 9 years ago

oliversalzburg commented 9 years ago

I converted our Cordova application to use $log only to realize afterwards, that I no longer get any log output when debugging iOS.

I realized that this is due to the fact that console.log is replaced and redirected to my debugger, but $log will still use the "old" console.log which isn't redirected.

I couldn't see a simple way to get $log to use the redirected console.log functions, so I'm asking for suggestions on how to handle this. For now, I'm just going to revert back to calling console.log directly.

petebacondarwin commented 9 years ago

It is interesting that this happens since in the $log service, we always lookup the console object on the $window object. I am wondering how Cordova is monkey-patching console... If it was doing something like:

window.console = cordovaConsole;

Then I think this should just work.

I suspect that instead they are either modifying the window object completely or the global namespace that is provided to cordova JavaScript applications is not the window object but some other container object that provides its own console object.

petebacondarwin commented 9 years ago

@oliversalzburg - perhaps you could step into the $logProvider and see what exactly the $window object is and also find out what the global object is inside a cordova app.

@ajoslin - any thoughts?

ajoslin commented 9 years ago

I think Cordova is asynchronously monkey patching it on deviceready.

You could try listening to document's deviceready event then override $log's functions again.

ajoslin commented 9 years ago

If Cordova is doing it synchronously, you could also make sure you're including Cordova before angular and that would fix it.

petebacondarwin commented 9 years ago

See this line: https://github.com/angular/angular.js/blob/master/src/ng/log.js#L136

The call to logConsole is acquiring the console object from $window on each call.

function consoleLog(type) {
  var console = $window.console || {},
  logFn = console[type] || console.log || noop,
  ...

So I think that this means that $window is not the global object that is being provided to cordova apps at runtime.

oliversalzburg commented 9 years ago

I just tried to look up the code again (I originally looked into this issue a few weeks ago) and the problem comes from the org.apache.cordova.console plugin and, more specifically, https://github.com/apache/cordova-plugin-console/blob/master/www/console-via-logger.js. But I couldn't wrap my head around specifics right now, sorry.

From what I can tell, I really have no control over inclusion order in my Cordova application, but I might be mistaken.

wesleycho commented 9 years ago

One option that could address this is to expose setting of the console.log function in the provider.

petebacondarwin commented 9 years ago

Actually, what is available is $window. So one could manually update $window.console at some point where you know that Cordova has done its monkey patching.

oliversalzburg commented 9 years ago

Interesting idea. I kinda lost track of this issue since I reported it because we moved away from $log right after we noticed this problem.

petebacondarwin commented 9 years ago

Something like:

myMod.run(function($window) {
  someCordovaObjectThingy.on('ready', function() {
    $window.console = console;
  });
});
oliversalzburg commented 9 years ago

I actually don't think that will work, because $log only accesses $window.console once, when it generates the new function that is used when using $log.method. That new function uses a direct reference to the initial window.console.log.

petebacondarwin commented 9 years ago

Oh yes, I was looking at $log.debug which seems to work differently. But we could refactor $log to cope with $window.console changing...