Uncaught exception undefined within promise - javascript

I have trouble correcting an error in my script, the console simply states "uncaught exception: undefined". Could you help me to identify the source of the problem ?
General explanation: I am coding a "copy to clipboard" share-button for a web-app. When the button is pressed, a link get generated and copied to the user clipboard. The link generation is dependent on external factors, reports that are stored in an Oracle database. There is an array named Reports that keeps track of them, but it needs to be up to date to generate a functional sharing-link. The anonymous function getterReports does it in an asynchronous way (JQuery + AJAX).
In order to copy my data to the clipboard, I am using the method described in this link: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
A snackbar (share_bar) is displayed on the screen to indicate that the operation is over.
Here is the raw code:
function copySharingURLToClipboard() {
let share_bar = document.getElementById("modal_share");
//getterReports ensures that the "Reports" array of reports objects is properly updated beforehand (AJAX <-> Database)
getterReports().then(function () { //this ".then" ensurea that the main code is only executed after getterReports is over
let report = getSavedReport(); //finds a report object by iterating the "Reports" array
if (report == undefined) { //no saved report were found
//snackbar related code :
document.getElementById("popup_message").innerHTML = "Temporary reports cannot be shared: please save your report first.";
share_bar.style.backgroundColor = "red";
share_bar.classList.add('show');//launching the fade-in fade-out animation from the associated css class
setTimeout(function () { share_bar.classList.remove('show'); }, 4200);//removing the class after the animation is done
}
else {
let data = BaseURL + "/DisplayReportPage.aspx?id=" + report.id; //generating the string that we want to copy in the clipboard
navigator.clipboard.writeText(data).then(function () {
/* success */
//snackbar related code :
document.getElementById("popup_message").innerHTML = "URL copied to the clipboard successfully";
share_bar.style.backgroundColor = "lightgreen";
share_bar.classList.add('show');//launching the fade-in fade-out animation from the associated css class
setTimeout(function () { share_bar.classList.remove("show"); }, 4200); //removing the class after the animation (it takes 4s + eventual minor latency)
}, function () {
/* failure case */
});
}
});
}
During the execution of copySharingURLToClipboard(), the "uncaught exception: undefined" error happens in the following line, at ".then":
navigator.clipboard.writeText(data).then(function () {
My Web-app doesn't crash though, but the code is simply skipped. The error is only displayed when going step by step in devtool (otherwise the portion of the code is simply skipped without any error message). My Firefox browser is up to date.
All involved function are working fine in other part of the code. I am confident in the fact that getterReports() is working fine on its own. The same is true for the copy to clipboard part of copySharingURLToClipboard(), without the getterReports() updating the "Reports" array, it works fine (but its results are not up to date obviously):
function copySharingURLToClipboard() {
let share_bar = document.getElementById("modal_share");
//getterReports ensures that the "Reports" array is properly updated beforehand (AJAX <-> Database)
let report = getSavedReport(); //finds a report object by iterating the "Reports" array
if (report == undefined) { //no saved report were found
//snackbar related code :
document.getElementById("popup_message").innerHTML = "Temporary reports cannot be shared: please save your report first.";
share_bar.style.backgroundColor = "red";
share_bar.classList.add('show');//launching the fade-in fade-out animation from the associated css class
setTimeout(function () { share_bar.classList.remove('show'); }, 4200);//removing the class after the animation is done
}
else {
let data = BaseURL + "/DisplayReportPage.aspx?id=" + report.id; //generating the string that we want to copy in the clipboard
navigator.clipboard.writeText(data).then(function () {
/* success */
//snackbar related code :
document.getElementById("popup_message").innerHTML = "URL copied to the clipboard successfully";
share_bar.style.backgroundColor = "lightgreen";
share_bar.classList.add('show');//launching the fade-in fade-out animation from the associated css class
setTimeout(function () { share_bar.classList.remove("show"); }, 4200); //removing the class after the animation (it takes 4s + eventual minor latency)
}, function () {
/* failure case */
});
}
}
Am I missing something simple ? A syntax error maybe ?

Firefox does not allow async copy-to-clipboard functionality.
Calling navigator.clipboard.writeText() in a promise resolve or an async function does not work intentionally. The code is working properly on other browsers.
After some research, it appears that there is still no available alternative implementation on Firefox. The logic of the project as a whole needs to be adapted in order to not use asynchronous functions when copying something in the clipboard.

Related

e.source.getActiveSheet(); triggers error [duplicate]

Google Apps Script supports Triggers, that pass Events to trigger functions. Unfortunately, the development environment will let you test functions with no parameter passing, so you cannot simulate an event that way. If you try, you get an error like:
ReferenceError: 'e' is not defined.
Or
TypeError: Cannot read property *...* from undefined
(where e is undefined)
One could treat the event like an optional parameter, and insert a default value into the trigger function using any of the techniques from Is there a better way to do optional function parameters in JavaScript?. But that introduces a risk that a lazy programmer (hands up if that's you!) will leave that code behind, with unintended side effects.
Surely there are better ways?
You can write a test function that passes a simulated event to your trigger function. Here's an example that tests an onEdit() trigger function. It passes an event object with all the information described for "Spreadsheet Edit Events" in Understanding Events.
To use it, set your breakpoint in your target onEdit function, select function test_onEdit and hit Debug.
/**
* Test function for onEdit. Passes an event object to simulate an edit to
* a cell in a spreadsheet.
*
* Check for updates: https://stackoverflow.com/a/16089067/1677912
*
* See https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
*/
function test_onEdit() {
onEdit({
user : Session.getActiveUser().getEmail(),
source : SpreadsheetApp.getActiveSpreadsheet(),
range : SpreadsheetApp.getActiveSpreadsheet().getActiveCell(),
value : SpreadsheetApp.getActiveSpreadsheet().getActiveCell().getValue(),
authMode : "LIMITED"
});
}
If you're curious, this was written to test the onEdit function for Google Spreadsheet conditional on three cells.
Here's a test function for Spreadsheet Form Submission events. It builds its simulated event by reading form submission data. This was originally written for Getting TypeError in onFormSubmit trigger?.
/**
* Test function for Spreadsheet Form Submit trigger functions.
* Loops through content of sheet, creating simulated Form Submit Events.
*
* Check for updates: https://stackoverflow.com/a/16089067/1677912
*
* See https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events
*/
function test_onFormSubmit() {
var dataRange = SpreadsheetApp.getActiveSheet().getDataRange();
var data = dataRange.getValues();
var headers = data[0];
// Start at row 1, skipping headers in row 0
for (var row=1; row < data.length; row++) {
var e = {};
e.values = data[row].filter(Boolean); // filter: https://stackoverflow.com/a/19888749
e.range = dataRange.offset(row,0,1,data[0].length);
e.namedValues = {};
// Loop through headers to create namedValues object
// NOTE: all namedValues are arrays.
for (var col=0; col<headers.length; col++) {
e.namedValues[headers[col]] = [data[row][col]];
}
// Pass the simulated event to onFormSubmit
onFormSubmit(e);
}
}
Tips
When simulating events, take care to match the documented event objects as close as possible.
If you wish to validate the documentation, you can log the received event from your trigger function.
Logger.log( JSON.stringify( e , null, 2 ) );
In Spreadsheet form submission events:
all namedValues values are arrays.
Timestamps are Strings, and their format will be localized to the Form's locale. If read from a spreadsheet with default formatting*, they are Date objects. If your trigger function relies on the string format of the timestamp (which is a Bad Idea), take care to ensure you simulate the value appropriately.
If you've got columns in your spreadsheet that are not in your form, the technique in this script will simulate an "event" with those additional values included, which is not what you'll receive from a form submission.
As reported in Issue 4335, the values array skips over blank answers (in "new Forms" + "new Sheets"). The filter(Boolean) method is used to simulate this behavior.
*A cell formatted "plain text" will preserve the date as a string, and is not a Good Idea.
Update 2020-2021:
You don't need to use any kind of mocks events as suggested in the previous answers.
As said in the question, If you directly "run" the function in the script editor, Errors like
TypeError: Cannot read property ... from undefined
are thrown. These are not the real errors. This error is only because you ran the function without a event. If your function isn't behaving as expected, You need to figure out the actual error:
To test a trigger function,
Trigger the corresponding event manually: i.e., To test onEdit, edit a cell in sheet; To test onFormSubmit, submit a dummy form response; To test doGet, navigate your browser to the published webapp /exec url.
If there are any errors, it is logged to stackdriver. To view those logs,
In Script editor > Execution icon on the left bar(Legacy editor: View > Executions).
Alternatively, Click here > Click the project you're interested in > Click "Executions" icon on the left bar(the 4th one)
You'll find a list of executions in the executions page. Make sure to clear out any filters like "Ran as:Me" on the top left to show all executions. Click the execution you're interested in, it'll show the error that caused the trigger to fail in red.
Note: Sometimes, The logs are not visible due to bugs. This is true especially in case of webapp being run by anonymous users. In such cases, It is recommended to Switch Default Google cloud project to a standard Google cloud project and use View> Stackdriver logging directly. See here for more information.
For further debugging, You can use edit the code to add console.log(/*object you're interested in*/) after any line you're interested in to see details of that object. It is highly recommended that you stringify the object you're looking for: console.log(JSON.stringify(e)) as the log viewer has idiosyncrasies. After adding console.log(), repeat from Step 1. Repeat this cycle until you've narrowed down the problem.
Congrats! You've successfully figured out the problem and crossed the first obstacle.
2017 Update:
Debug the Event objects with Stackdriver Logging for Google Apps Script. From the menu bar in the script editor, goto:
View > Stackdriver Logging to view or stream the logs.
console.log() will write DEBUG level messages
Example onEdit():
function onEdit (e) {
var debug_e = {
authMode: e.authMode,
range: e.range.getA1Notation(),
source: e.source.getId(),
user: e.user,
value: e.value,
oldValue: e. oldValue
}
console.log({message: 'onEdit() Event Object', eventObject: debug_e});
}
Example onFormSubmit():
function onFormSubmit (e) {
var debug_e = {
authMode: e.authMode,
namedValues: e.namedValues,
range: e.range.getA1Notation(),
value: e.value
}
console.log({message: 'onFormSubmit() Event Object', eventObject: debug_e});
}
Example onChange():
function onChange (e) {
var debug_e = {
authMode: e.authMode,
changeType: changeType,
user: e.user
}
console.log({message: 'onChange() Event Object', eventObject: debug_e});
}
Then check the logs in the Stackdriver UI labeled as the message string to see the output
As an addition to the method mentioned above (Update 2020) in point 4.:
Here is a small routine which I use to trace triggered code and that has saved me a lot of time already. Also I have two windows open: One with the stackdriver (executions), and one with the code (which mostly resides in a library), so I can easily spot the culprit.
/**
*
* like Logger.log %s in text is replaced by subsequent (stringified) elements in array A
* #param {string | object} text %s in text is replaced by elements of A[], if text is not a string, it is stringified and A is ignored
* #param {object[]} A array of objects to insert in text, replaces %s
* #returns {string} text with objects from A inserted
*/
function Stringify(text, A) {
var i = 0 ;
return (typeof text == 'string') ?
text.replace(
/%s/g,
function(m) {
if( i >= A.length) return m ;
var a = A[i++] ;
return (typeof a == 'string') ? a : JSON.stringify(a) ;
} )
: (typeof text == 'object') ? JSON.stringify(text) : text ;
}
/* use Logger (or console) to display text and variables. */
function T(text) {
Logger.log.apply(Logger, arguments) ;
var Content = Stringify( text, Array.prototype.slice.call(arguments,1) ) ;
return Content ;
}
/**** EXAMPLE OF USE ***/
function onSubmitForm(e) {
T("responses:\n%s" , e.response.getItemResponses().map(r => r.getResponse()) ;
}

Dynamically adding data to page with aurelia after the view is rendered

I am trying to build a web app with aurelia and I couldn't find a way to add data via AJAX after everything on page has been rendered. The scenario (simplified):
There's a page, some part of which is dynamically composed from a component (say, data-table). data-table has a title, and table-rows to show the data. data-table should load it's data dynamically via an AJAX call. What I want is, loading the data after the page is rendered.
I tried using promises but it does the opposite, ie, aurelia waits until the promise is resolved before attaching the view (explained by Jeremy Danyow as well: "...In this example Aurelia will wait for the Promise returned by the activate method to resolve before binding the view to the viewmodel." (in his post titled "ES7 async/await with Aurelia")
This causes the page remain stalled until all data is loaded.
A simple code example is provided below. Here, if you navigate to this page, you won't see anything (or the page wont get attached) until all data is loaded. What I want is, to load the page and show "Table for ..." title, and at the same time start loading data in the background and show the table itself when loading completes. The desired behavior is illustrated in the following "mock" screenshots.
before the ajax requrest is completed
after the ajax request is completed
Additionally, the tables may need to be updated based on user choices (additional data may be loaded and added to the tables) or additional tables may need to be added to the page.
I don't think the desired behavior matches any of the bind/attached/detached etc. life-cycle behaviors (but could be wrong). This could be implemented utilizing a variant of body.onload (or jquery etc.) but I wonder if this is possible to do using aurelia only (or mostly).
Maybe, being able to load data after everything is attached (eg. a "postattached" callback) could help. In that case, I would load all necessary components with their already loaded data (eg. their titles) and show them. Then, in the "postattached" section I will start loading data.
Sample code:
test.ts
export class testPage {
ids: number[] = [1,2,3] // for example 1,2,3; will be dynamically loaded as well
}
test.html
<template>
<h1>Test</h1>
<div repeat.for="id of ids">
<compose view-model="./components/table" model.bind="id"></compose>
</div>
</template>
table.ts
import { Loader } from './loader';
export class table {
id: number
tableData: number[][] = []
activate(model) {
this.id = model
}
attached() {
Loader.LoadData(this.id).then((res)=>{this.tableData = res})
}
}
table.html
<template>
<h2>Table for ${id}</h2>
<div repeat.for="rows of tableData">${rows}</div>
</template>
loader.ts
export class Loader {
static LoadData(tid): Promise<number[][]> { //simple stub to imitate real data loading
let data: number[][] = []
switch (tid) {
case 1:
data.push([11, 12, 13])
data.push([14, 15, 16])
break;
case 2:
data.push([21, 22, 23])
data.push([24, 25, 26])
break;
case 3:
data.push([31, 32, 33])
data.push([34, 35, 36])
break;
}
this.sleep()
return new Promise((resolve, reject) => {
this.sleep()
resolve(data)
})
}
protected static sleep(): boolean { // just to imitate loading time
let miliseconds = Math.floor(Math.random() * (3 - 1 + 1) + 1);
var currentTime = new Date().getTime();
console.debug("Wait for a sec: " + miliseconds)
while (currentTime + miliseconds * 1000 >= new Date().getTime()) {
}
return true
}
}
edit: Corrected code which was miscarried to the example here
You should try using window.timeout to emulate the loading time. Because Javascript is single threaded, your sleep function will block all other execution on the thread.
This answer is possibly a bit over the top but explains in more detail how to write a sleep function in javascript: What is the JavaScript version of sleep()?

Uncaught TypeError: $player.jPlayer is not a function

I'm helping a friend with his site and after updating his WordPress installation to address the recent security issue, the JPlayer plugin that was handling audio on his site stopped working.
Chrome's console shows the error in the title, but I don't know JS well enough to be able to debug it properly. I'm pretty sure that the plugin itself is loaded correctly, along with JQuery, in the page header. I checked it against the plugin's instructions and it all appears fine.
I've also updated the plugin itself to ensure that it's not some compatibility issue.
I did not build his site, nor am I familiar with this particular plugin at all, I'm just trying to see if it's an easy fix or if I have to restore a backup.
I assume it has something to do with how his web designer (they had a falling out) implemented it in the main.js file, but that's about as far as I've gotten.
Help?
Really condensing and removing parts of main.js, it looks like
var $player = false,
$(document).ready(function() {
if(!$player) {
$("#jPlayer").jPlayer({
ready: function() {
$player = $(this); // IT'S BEING SET HERE !
PlaylistPlay(playlistObject,trackIndex);
}
});
} else {
PlaylistPlay(playlistObject,trackIndex);
}
});
function PlaylistPlay(lePID,trackIndex) {
playTrack(trackIndex);
}
function playTrack(index) {
$player.jPlayer("setMedia", {mp3: trackObject.mp3,oga: trackObject.oga}).jPlayer("play");
}
If you look closely at that, you'll see that there is a distinct possibility that PlaylistPlay can be called without $player being set to $(this), it's actually almost a certaintity, which means that $player is false, and doing
false.jPlayer(...
doesn't really work, see the console output that confirms the variable is false
The plugin is not initializing correctly. On $(document).ready() it's trying to initialize the plugin and it's reporting a Flash error.
Here's the significant part of the code:
$("#jPlayer").jPlayer({
...
error: function(event) {
var out = "<p id=\"noSolution\">Sorry, you need an HTML5 capable browser or flash to be able to listen to music on this website.<br /> Reason: ";
switch(event.jPlayer.error.type) {
case $.jPlayer.error.FLASH:
out += "A problem with the Flash insertion on the page.";
break;
...
}
}
...
});
Digging a bit deeper, I can trace this back to the vimeo.jplayer in the specific code block:
_flash_volume: function(a) {
try {
this._getMovie().fl_volume(a)
} catch (b) {
this._flashError(b)
}
}
That function is throwing an exception because this._getMovie() does not have a property named fl_volume.
The error you actually see is a side-effect of this failure. You could try removing the line: this._flashError(b) from the above statement and see if the error can be safely ignored.

Modernizr download file, but it is still undefined afterwards? (Only in IE9 after page postback)

I've got a jQuery plugin I made which will nicely format dates on elements with certain attributes on them. Overall it works, but I'm having some problems with Modernizr, but ONLY in IE and ONLY after a form postback.
Here's a snippet from the plugin where it uses the fantastic MomentJS library. Basically the first time the plugin is called, it will download the needed file then run the code to parse dates. If it is called any time afterwards and the library has already been downloaded, it can just go ahead and run the date parsing code.
function parseDates() {
var $items = this;
if (typeof moment !== "undefined") {
//If we are calling this at a time after page load, just run the function
setupDisplayDate();
} else {
//If the files have not been included yet, download them & call the function
//Load in a date library!
Modernizr.load({
load: SCRIPTS_PATH + "moment.min.js",
callback: setupDisplayDate
});
}
function setupDisplayDate() {
console.log("setupDisplayDate called! Moment is " + typeof moment);
$items.each(function () {
var $thisItem = $(this);
var formatter = $thisItem.data("date-format") || "MMMM Do, YYYY";
var ticks = parseInt($thisItem.data("date-ticks"), 10);
var formattedDate = moment(ticks).format(formatter);
$thisItem.text(formattedDate);
});
}
}
When I do this in IE9 only after a page postback, I get an error within the setupDisplayDate function saying that moment is not defined. What am I doing wrong?
I did find that if I do a timeout of 500ms it will work, but I shouldn't have to do that. I thought the whole point of the Modernizr.load feature was to download the code, and then make it available. It seems to download it and the fire my callback before it is available to use.
EDIT
Here's [a blog post about how IE9 will not properly dynamically added scripts: http://www.guypo.com/technical/ies-premature-execution-problem/
Any way around this?
Another Edit
It seems like the issues is actually regarding multiple calls to the load function and then the various callbacks firing out of order. There's an open issue on GitHub about it and this reproducible test case.

Functions registered with ExternalInterface.addCallback not available in Javascript

I'm working on a Flash game that needs to call some Javascript on the page and get data back from it. Calling Javascript from Flash works. Calling the Flash functions from Javascript (often) doesn't.
I'm using the Gaia framework.
What happens:
The swf is loaded in with SWFObject
There's a button in the Flash file. On click, it uses ExternalInterface.call() to call a Javascript function. This works.
The Javascript function calls a Flash function that was exposed with ExternalInterface.addCallback().
Sometimes, the Javascript produces the following error: TypeError: myFlash.testCallback is not a function.
When the error happens, it affects all functions registered with addCallback(). Gaia and some of its included libraries use addCallback(), and calling those functions from Javascript also produces the TypeError.
Waiting a long time before pressing the button in Flash doesn't solve the error.
Having Flash re-try addCallback() periodically doesn't solve the error
When the error occurs, ExternalInterface.available = true and ExternalInterface.objectID contains the correct name for the Flash embed object.
When the error occurs, document.getElementById('myflashcontent') correctly returns the Flash embed object.
Edited to add:
This issue shows up in Firefox 3.6, but not Chrome or IE8. I haven't tried older browsers.
I'm running the Debug version of the Flash player.
My calls to ExternalInterface.addCallback() are wrapped in a try...catch block. When the JS error occurs, the catch block is not triggered. It's a silent failure.
The error occurs when testing on a webhost, with the swf loaded from the same server as the page it's on.
I set allowScriptAccess = always.
Setting flash.system.Security.allowDomain("mydomain") doesn't fix the error.
From my Page class:
public class MyPage extends AbstractPage
{
// declarations of stage instances and class variables
// other functions
override public function transitionIn():void
{
send_button.addEventListener(MouseEvent.MOUSE_UP, callJS);
exposeCallbacks();
super.transitionIn();
}
private function exposeCallbacks():void
{
trace("exposeCallbacks()");
if (ExternalInterface.available) {
trace("ExternalInterface.objectID: " + ExternalInterface.objectID);
try {
ExternalInterface.addCallback("testCallback", simpleTestCallback);
trace("called ExternalInterface.addCallback");
}
catch (error:SecurityError) {
trace("A SecurityError occurred: " + error.message + "\n");
}
catch (error:Error) {
trace("An Error occurred: " + error.message + "\n");
}
}
else {
trace("exposeCallbacks() - ExternalInterface not available");
}
}
private function simpleTestCallback(str:String):void
{
trace("simpleTestCallback(str=\"" + str + "\")");
}
private function callJS(e:Event):void
{
if (ExternalInterface.available) {
ExternalInterface.call("sendTest", "name", "url");
}
else {
trace("callJS() - ExternalInterface not available");
}
}
}
My Javascript:
function sendTest(text, url) {
var myFlash = document.getElementById("myflashcontent");
var callbackStatus = "";
callbackStatus += '\nmyFlash[testCallback]: ' + myFlash['testCallback'];
//console.log(callbackStatus);
var errors = false;
try {
myFlash.testCallback("test string");
}
catch (err) {
alert("Error: " + err.toString());
error = true;
}
if (!error) {
alert("Success");
}
}
var params = {
quality: "high",
scale: "noscale",
wmode: "transparent",
allowscriptaccess: "always",
bgcolor: "#000000"
};
var flashVars = {
siteXML: "xml/site.xml"
};
var attributes = {
id: "myflashcontent",
name: "myflashcontent"
};
// load the flash movie.
swfobject.embedSWF("http://myurl.com/main.swf?v2", "myflashcontent",
"728", "676", "10.0.0", serverRoot + "expressInstall.swf",
flashVars, params, attributes, function(returnObj) {
console.log('Returned ' + returnObj.success);
if (returnObj.success) { returnObj.ref.focus(); }
});
Calls made to JS via ExternalInterface are wrapped within a try { } block and that causes subsequent JS errors to get suppressed.
A workaround for the same is to cause a function closure in JavaScript and execute the actual code after a timeout.
Example:
function myFnCalledByEI (arg1, arg2) {
setTimeout(myActualFunction () {
// You can use arg1 and arg2 here as well!
// Errors raised within this function will not be
// suppressed.
}, 0);
};
Here was our scenario once we narrowed down all the conditions:
Only on FireFox/Windows
Only when wmode=transparent
Only when using the js alert() function
In this specific scenario, ExternalInterface.call() would not fire right away. It only worked after creating a tiny delay with Timer class.
If we made wmode=window, or removed the alert() - everything worked. Try using console.log() to display debug text in firebug.
The other gotcha? Whether your js function returns an array or object vs a string. Surprisingly returning the native js array was interpreted by an array in Flash. Try outputting info about your return data like this:
var myRetVal = flash.external.ExternalInterface.call("my_js_func");
debug_txt.text = flash.utils.describeType(myRetVal).toString();
This might be similar to the issue you are experiencing.
http://www.google.com/support/forum/p/translator-toolkit-api/thread?tid=58cda1b34ae1e944&hl=en
You can see that type of error message if something wrong happened in Flash while making the call. Something like an uncaught exception.
Are you running the debug version of the player? That might give you more information about what's going on.
Also, is this consistent across browsers? I've seen old versions of IE having trouble accepting several consecutive Flash <-> JS calls.
J
I tryied your code, and It worked ok if I place an alert before everything, so, I thinkg it is something related to some kind of time you have to wait.
Have you tried this in JavaScript?
if (myFlash)
{
if (!myFlash.testCallback)
{
if (__flash__addCallback)
{
__flash__addCallback( myFlash, "testCallback" );
}
else
{
console.log("Error: Flash External Interface injected JavaScript function not found. The external interface function won't work.");
}
}
}
myFlash.testCallback("test string");
I had used this in many cases.
Again at certain places I had to redefine __flash_addCallback and _flash_removeCallback functions to minimize the errors.
Presently I do not remember what I did for __flash_addCallback, but this is what I did for the latter:
if (__flash__removeCallback)
{
__flash__removeCallback = function (instance, name) {if(instance && instance[name]) instance[name] = null;
}
We've run into the same problem, and only in Firefox.
Following the advice given by THM we were able to find a solution.
In our case, the swf being inserted was inside a div being animated into view with jQuery.slideDown(). This apparently causes it to sometimes reboot while being started. In some cases this led to the callback functions not being available.
Fixed by calling swfobject.embedSWF only after the slideDown effect had finished.
I was getting this error because I had the same Flash file on the page multiple times. Even though each one of them had a different id/name, they were all using the same callback.

Categories

Resources