ExternalInterface.call() not getting return value - javascript

I have a Javascript function that returns the innerHTML of a div. I am attempting to call this function from Actionscript and store the return value. I know that the Javascript function is being called because there is an alert that displays the return data, The data that is returned to Actionscript, however, is null. I am not sure what is causing this. Here is a code example of what I am attempting to do:
Javascript:
function JSFunc () {
var x = document.getElementById("myDiv");
alert(x.innerHTML);
return x.innerHTML;
}
Actionscript:
import flash.external.*;
if (ExternalInterface.available) {
var retData:Object = ExternalInterface.call("JSFunc");
if(retData != null) {
textField.text = retData.toString();
} else {
textField.text = "Returned Null";
}
} else {
textField.text = "External Interface not available";
}
Like I said earlier, the alert shows up with the contents of the div but the text in the textfield is always "Returned Null", meaning that the ExternalInterface is available. I should add that I can only test this in IE7 and IE8. Any advice on what to do would be much appreciated.

This is a working sample based on the code you provided. You can right click it to view the source. I suspect the problem lies in the HTML for 'myDiv' or when you are making the actionscript call.

The source of the problem that I have been having has to do the object tag that I was using to embed the flash movie. I was using a tag that followed this example http://www.w3schools.com/flash/flash_inhtml.asp, I changed it to match this example: http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_4150 and then I made sure that I added id to the object and everything worked.

Try adding as String to the call:
textField.text = ExternalInterface.call("JSFunc") as String;

I also noticed you got a typo in your code => textField != textfield

Try to get the object back from your external interface call without casting it first, and take a look at it in the debugger. If it is not a string, trying to cast it to a string will result in null. This should be a string, but it doesn't hurt to see what you are actually getting back before you try to work with it.

It seems to me that your problem is that from javascript you are returning a string, the innerHTML property of your myDiv element. In actionscript you have datatyped the variable that the ExternalInterface call returns to as an Object, but it is a String. Maybe you have already caught this, but I can't tell as you haven't amended your code.
//The following is an Object
var x = document.getElementById("myDiv");
/*
You are returning the innerHTML property of x, a string, but on the
flash end your expecting an object in your actionscript.
*/
return x.innerHTML;
//The following seems incorrect to me.
var retData:Object = ExternalInterface.call("JSFunc");
//Should be
var retData:String = ExternalInterface.call("JSFunc");
Hope this was helpful, take care.

You should use the import statement
import flash.external.*;

Related

How to convert a string parameter into Object type in JavaScript?

I am making a function in the Data-Type "Object",
Code:
Object.exists = function(obj){
if(typeof(obj)==="object"){
return true;
}else{
return false;
}
}
Its purpose is to check whether an object exists or not. Everything works fine if the object entered exists, but if I try to check an object which does not exist(I am trying to develop a function and am currently checking it), it throws an error. The code to check and the error msg:
Object.exists(demo); //Note: demo is not an object
//Error:
Uncaught ReferenceError: demo is not defined
at <anonymous>:1:15
and if I try to add demo in quotes, then it does not work and shows false even if I try to add an existing object. If I try
if(typeof(obj)==="object"){
return true;
}else{
return false;
}
}
the code above without the function and the object doesn't exist, no error is thrown.
So I tried to work out my dumb brain and thought that can I use eval(), but I don't think so. Is there any other way I can convert the parameter(even if it is a string) into an object for the if statement?
I just found out the answer,
used eval() and it worked!
The code:
Object.exists = function(obj){
var type = eval("typeof("+obj+")");
console.log(type);
}
When you try an object which exists, it logs object, but if you try anything other, it logs it's type.

Setting Variable Assignments with property display

I'm still a novice when it comes to JavaScript and was trying to make my code more cleaner and was wondering why the top scenario works but the bottom doesn't? Am I missing something?
var partner = document.getElementById('partner');
var providedBy = document.getElementById('providedBy');
partner.style.display = "none";
providedBy.style.display = "none";
But this does not?
var partner = document.getElementById('partner');
var providedBy = document.getElementById('providedBy');
collection = partner + providedBy;
collection.style.display = "none";
In the console it gives me error saying Cannot set Property 'display' of undefined. Am I supposed to define it somewhere first? I console logged the new variable and it returned both div elements.
collection is of type string as the + operator automatically call for both their toString() function.
Now what you are trying is to access a property of collection.style which does not exist because you are operating on a string. That's the reason for the error message you are getting.
You could do something like:
var collection = [];
collection.push(document.getElementById('partner'));
collection.push(document.getElementById('providedBy'));
collection.forEach(function(element) {
element.style.display = 'none';
}
which would be something I think you are trying to archive.
just to complement the accepted answer, I think you should understand why you get this error.
For what i understand from your code, you are trying to set the css of both variables partner and providedBy to display : none.
Your first piece of code works because you do this separately, while in your second code you try to add with the (+) operator both nodes, which evaluates to the string "[object HTMLDivElement][object HTMLInputElement]".
Then you try to call .style on that string which evaluates to undefined, and then you try to call display on that undefined value, this is where you get the error.
You could leave your code just like that since there are not too many variables, but if you wanted to do something that worked on multiple variables you could
create an array
push your objects into the array
create a function that loops over the elements of the array and set their style.display = "none" to individually.
In JavaScript you have to declare all of your variables. Secondly, you can't point to two objects at once by using the + operator. JavaScript interprets this as trying to concatenate the two objects, which it can't do in this way. It will return the string [object Object][object Object]
In order to affect two Objects at the same time you would need to create a function or use an existing method.

detect pagination condition in javascript

I want to get the condition of action pagination that's why i define this in my grid i want how can i define variable to test if the action is paginator or not :
settings.ClientSideEvents.EndCallback = "function (s,e){Test123(s,e)}";
And now when i want to test if action is pagination i display an alert:
function Test123(s, e) {
debugger;
var xx = ListeClient.cpPageChanged;
alert(xx);
}
it display undefined
How can i resolve this issue
You almost certainly don't want quotes around your function definition, because you almost never eval a string in Javascript (but I don't know what API you're working with, so I can't say for sure):
settings.ClientSideEvents.EndCallback = function (s,e){Test123(s,e)};
The other problem could be that this line
var xx = ListeClient.cpPageChanged;
is undefined. Then your problem is that cpPageChanged is not a property of ListeClient, so you might just have a typo.

document.getElementsByTagName:Cannot read property 'style' of undefined

I wanna make a varible shortcut $$() so that i can use shortcut like $() [jquery] to save code in my project(ALL MY CODE IS PURE JAVASCRIPT).
when i put the string of id or class, it works all right, but when i put the tagName, it shows Cannot read property 'style' of undefined, it seems that the code is right,help,thanks
One more, is that way to defined a shortcut variable $$() to use in pure javascript environment right way? or is there any best practice to define a global variable like this?
window.onload = function(){
function $$(ele){
var pattern1 = /#/g;
var pattern2 = /\./g;
var pattern3 = /!/g;
var matches = ele.match(/[^#\.!]/g);//array
var elementS = matches.join("");
//alert(matches+elementS);
// console.log(document.getElementsByTagName(elementS));
var spaceExist = /\s/.test(elementS)
if(pattern1.test(ele)){
return document.getElementById(elementS);
}else if(pattern2.test(ele)){
//console.log(elementS);
return document.getElementsByClassName(elementS);
}else if(pattern3.test(ele)){
alert('hi');
console.log(elementS);
return document.getElementsByTagName(elementS);
}else if(spaceExist){
return document.querySelectorAll(elementS);
}
}
$$('#hme').style.backgroundColor = 'red';
$$('.myp')[0].style.backgroundColor = 'green';
$$('!h2')[0].style.display = 'none';//this not work,shows Cannot read property 'setAttribute' of undefined
}
<h1 id="hme">hi,friend</h1>
<p class="myp">mmdfdfd</p>
<h2>hhhhhh</h2>
Have you stepped through your code? Look at pattern #2:
var pattern2 = /./g;
That pattern will match any character at all given that's what the period represents in regular expressions - ref: http://www.regular-expressions.info/dot.html.
Therefore, this conditional is satisfied and returns its result:
else if(pattern2.test(ele)){
return document.getElementsByClassName(elementS);
}
Given there appears to be no element with a class name of h2 (which is the value of elementS), the return value is undefined.
Given that undefined has no properties, interrogating for the style property will produce the error you are seeing.
My advise is use one shortcut since you already using querySelectorAll:
window.$ = document.querySelectorAll.bind(document)
or if you rather need first element
window.$ = document.querySelector.bind(document)
this way you'll be able to do everything you are doing with normal css selectors and not obfuscated !tag for just tag
If speed actually matters, you will save some ticks by just having two aliases:
window.$ = document.querySelector.bind(document)
window.$el = document.getElementById.bind(document)
and calling $el when you need it specifically, instead of trying to make method polymorph.
Mister Epic's answer spots the main issue. Your h2 call is getting caught in that if statement, and that's why your error is happening. You need to make sure it doesn't get caught there, either by creating another pattern, or specifying in your second if statement that your 'ele' doesn't contain an '!'.
After that, in your third if statement:
else if(pattern3.test(ele)){
alert(hi); <---
console.log(elementS);
return document.getElementsByTagName(elementS);
The problem with this is you're going to alert(hi), but hi isn't defined. Make sure you wrap it in quotes.
Should be looking good after that.

IE6 alerting an array does not show anything

First of all, the full code is at work so I'm reciting from memory.
There is a js file with containing an object defined like this:
function SomeObject(someArg) {
this.someMember = someVar.split(".");
...
this.someFunc = function() {
return this.someMember;
}
...
}
There is another js file which uses this object and has a function that looks something like this:
someOtherFunc(SomeObject):
var someOtherVar = SomeObject.someFunc();
var length = someOtherVar.length;
....
Now when I add an alert(SomeObject.someFunc()) at the beginning of someOtherFunc all I see is an empty box. However, when I alert SomeObject.someFunc().length I get 1 (because the array has one element). Yet, I have a "length is an undefined..." where var length is defined. Also, when I alert SomeObject.someFunc()[0] I have the value of the element shown (it's a string).
I know it's IE6 (don't ask) and I couldn't provide much context, but I'm still hoping this issue is somewhat known or has some explanation or a workaround.

Categories