AngularJS $window.open throws "Cannot read property 'arguments' of null" - angularjs

I'm creating a simple web page where i display a button which execute this code
$window.open(link, "_self");
The link variable is a simple telegram link for a channel, but this is not the problem, the problem, as the question say itself, is about arguments variable in $window.open.
This in my opinion is strange because when i logged in the console $window.open function, i received this output:
function pbWindowOpen() {
lastBlockCaller = {
caller: arguments.callee.caller,
args: arguments.callee.caller.arguments
};
try {
return newWindowOpenFn.apply(this, argument…
At this point, should not i see an argument variable inside this function? How could i solve this problem?
Passing some arguments could resolve my problem? If yes, there's an answer about why i'm having arguments null?
I've also tried with window.open but nothing changes, always the same problem

That shouldn't happen if you are running your code in a browser (in other env you may have some initialized variable window representing something else), $window is a wrapper in top of var currWindow = $window.self || $window.window and then do a perform of callong open(...) function. Hence, you neither using the native javascript code badly in a angular context, and again that would be easily mock-ableif we mock $window and create a property call self or window inside it. So it will work in the application, and will also be testable.

Related

TyperError: Cannot read property 'length' of undefined

Our team is using angularjs to develop a ServiceNow widget and we are seeing "TyperError: Cannot read property 'length' of undefined" in our console:
When we click on "at eval", it takes us to this particular snippet of code with line 321 highlighted:
We can't seem to figure out what's causing that error. We are using $watch on an array ($scope.data.list) and have read that $watchCollection might be better, but we tried that with no change. Any ideas what could be causing this error and how to get rid of it?
From the code you have posted, you haven't defined or nor declared
$scope.data.list (I'm assuming $scope.data is defined somewhere). To
resolve that, you need to at least declare your $scope.data.list first to watch over it.
Coming to the $watch part, it depends on what your requirement is.
$scope.$watchCollection looks for changes made in the array as well as elements whereas,
$scope.$watch will only look for changes made if the array is totally
assigned to a different one. Otherwise, if you want to watch deep, you can
use $scope.$watch with a boolean true variable passed as a third
argument to it.
Refer this link for the full documentation - https://www.sitepoint.com/mastering-watch-angularjs/
As of my knowledge $watch on $scope.data.list called whenever any value changed in this collection
So by looking at error it seems like $scope.data.list list in no longer exits in $scope.data. Try to find out where $scope.data is going to change.
And use below syntax for watch on collection
$scope.$watchCollection('names', function(newList,oldList) {
if(newList && newList.length) {
$scope.data.list = newList.length;
}
});

Why angularjs throw 'Illegal invocation' when using promise construction?

I invoke some promise function:
return $http.post("anyCtrl").then(location.reload);
After that I have thrown exception in browser console 'Illegal invocation' in angular.
If I invoke:
return $http.post("anyCtrl").then(function(){location.reload()});
Everything is good.
I expected that all of my code snippets should be working.
Passing location.reload as an argument works more or less the same as reassigning it. If you reassign an object's method and it's not bound, that object's this will become the object that it's assigned to. For example:
const notlocation = {};
notlocation.reload = location.reload();
notlocation.reload(); // illegal invocation
You need to invoke reload from the location object. There are a couple of ways you can do this. One is to have the parentheses with the method call explicitly as you've done:
$http.post("anyCtrl").then(() => location.reload());
Another is to use the .bind and bind it to the object you want to invoke the method:
$http.post("anyCtrl").then(location.reload.bind(location));

check supportsDisplay in a function instead of within an intent

I have a working skill that uses the function that checks whether the alexa device has a display so I can either build a template output or render output to a card:
function supportsDisplay() {
var hasDisplay =
this.event.context &&
this.event.context.System &&
this.event.context.System.device &&
this.event.context.System.device.supportedInterfaces &&
this.event.context.System.device.supportedInterfaces.Display
return hasDisplay;
}
I have a couple places where I render output so I wanted to make a function I can call to handle the visual output instead of having to rewrite the template code multiple times.
This returns an error. If I use this same function but comment out the call to the supportsDisplay function it works, so I assume the problem is in how I'm calling it:
function makeTemplate(playStatus){
if (supportsDisplay.call(this)){...}
return;
}
I also tried not making a function to check the display at all and actually just putting the code to check it directly in my function but that also didn't work.
I'm guessing part of the problem could be the this keyword (I'm very new to JS/Alexa dev and don't understand really what "this" does.
Is there a way to be able to call that supportsDisplay function from within my function? What would be the syntax do that?

How to intercept AngularJS $http logging for display in page

I want to intercept console log message from AngularJS and display them in a div on the page. I need this in order to debug ajax traffic in a PhoneGap app.
This is an example of the kind of errors I want to capture:
I tried this Showing console errors and alerts in a div inside the page but that does not intercept Angular error messages.
I also tried the solution gameover suggested in the answers. No luck with that either. Apparently $http is handling error logging differently.
I guess the answer you tried has the right idea but you're overriding the wrong methods. Reading here I can see angularJs uses $log instead of console.log, so to intercept you can try to override those.
Something like this:
$scope.$log = {
error: function(msg){document.getElementById("logger").innerHTML(msg)},
info: function(msg){document.getElementById("logger").innerHTML(msg)},
log: function(msg){document.getElementById("logger").innerHTML(msg)},
warn: function(msg){document.getElementById("logger").innerHTML(msg)}
}
Make sure to run that after importing angular.js.
EDIT
Second guess, override the consoleLog method on the LogProvider inner class on angular.js file:
function consoleLog(type) {
var output ="";
//arguments array, you'll need to change this accordingly if you want to
//log arrays, objects etc
forEach(arguments, function(arg) {
output+= arg +" ";
});
document.getElementById("logger").innerHTML(output);
}
I've used log4javascript for this purpose. I create the log object via
var log = log4javascript.getLogger('myApp')
log.addAppender(new log4javascript.InPageAppender());
I then use this in a value dependency, and hook into it where needed (e.g. http interceptor).
A more lightweight approach might be to use $rootScope.emit and then have a component on your main page which prepends these log messages to a visible div, but this will require you to change all your calls to console.log (or redefine the function in your js).
I think that this message is not even displayed from AngularJS. It looks like an exception which has not been caught in any JavaScript (angular.js just appears on top of your stack because that's the actual location where the HTTP request is being sent).
Take a look at ng.$exceptionHandler. That should be the code you seem to be interested in. If not, take a quick web search for „JavaScript onerror“ which should tell you how to watch for these kinds of errors.
I would rather user an $http interceptor.
Inside the responseError function, you can set a property on a service that will be exposed to the div's scope.

GetProperty problem

I have an ASP.net website and inside its .aspx page there is a javascript function
and from my silverlight project , i want to get a value of property in the javascript funcion
i used "eval" to evaluate the function and GetProperty to return the value i want
the problem is GetProperty work only if i call the function for the second time
but never return in the first call
javascript code:
function RETURNIMAGE() {
var x = { value: document.getElementById("ImageContainer").value };
return x; }
c# code:
string getImage = "document.getElementById('myIFrame').contentWindow.RETURNIMAGE ();";
ScriptObject imgObject = HtmlPage.Window.Eval(getImage) as ScriptObject;
var img = imgObject.GetProperty("value");
any help please?
Since it works the second time I strongly suspect that the first time the IFrame is still loading its contents. Both Silverlight and the Browser will be getting on with their various activities asynchronously from each other.
Here is something that might help to halt the code until the page loads:
A hidden object/property can be put in the frame, but make sure it is after the property to be fetched.
Then a 'while' loop can be inserted in the c# code to check that this hidden property exists (the loop breaks only when the property value is loaded correctly), then put the rest of your code after the while loop.
This solution may not be optimum, but may be used to check if it is a loading problem or not.

Resources