We're using talker.js in an angular SPA that loads an iframe after clicking on an item from a list. Upon click, we launch an iframe containing an application that is required to setup a talker instance to communicate with the parent. The parent app controls when the iframe is present, but when we navigate away from the iframe, the window and event listeners are still present via window["frameName"]. If we navigate away from the iframe while waiting for a message to be responded to, the Talker instance gets nulled out BUT the event listener is still alive so the _receiveMessage method still gets called and throws an exception.
Talker.prototype.destroy = function () {
if (this.rejectTimeout) {//see below on this
clearTimeout(this.rejectTimeout);
}
if (this._listener) {
window.removeEventListener("message", this._listener, false);
this._listener = null;
}
};
We also have a number of scenarios that are fire and forget type of messages where the outer iframe just tells the inner one something and does not require a response. It would be nice to have a send and sendAsyc method where the sendAsync method creates the promise and requires a response and send just sends the message without creating the promise. The issue happens when we send a message without expecting a response so the promise in the setTimeout gets rejected after the timeout expires. Apart from setting our timeout to something astronomical, we end up with a lot of rejected promises with the timeout message. Would you consider doing something like this:
Talker.prototype.sendAsync = function(namespace, data, responseToId) {
var message = new Talker.OutgoingMessage(this, namespace, data, responseToId);
var promise = pinkySwearPromise();
this._sent[message.id] = promise;
this._queue.push(message);
this._flushQueue();
this.rejectTimeout = setTimeout(function() {
promise(false, [new Error(TALKER_ERR_TIMEOUT)]); // Reject the promise
}, this.timeout);
return promise;
};
Talker.prototype.send = function(namespace, data, responseToId) {
var message = new Talker.OutgoingMessage(this, namespace, data, responseToId);
this._postMessage(message);
};
and then in the destroy method we would clear the this.rejectTimeout timer. At the moment we are doing these things in our version of talker.js but it might be handy for others who could potentially run into this issue.
Thanks,
Jake
We're using talker.js in an angular SPA that loads an iframe after clicking on an item from a list. Upon click, we launch an iframe containing an application that is required to setup a talker instance to communicate with the parent. The parent app controls when the iframe is present, but when we navigate away from the iframe, the window and event listeners are still present via window["frameName"]. If we navigate away from the iframe while waiting for a message to be responded to, the Talker instance gets nulled out BUT the event listener is still alive so the _receiveMessage method still gets called and throws an exception.
We also have a number of scenarios that are fire and forget type of messages where the outer iframe just tells the inner one something and does not require a response. It would be nice to have a
sendandsendAsycmethod where thesendAsyncmethod creates the promise and requires a response andsendjust sends the message without creating the promise. The issue happens when we send a message without expecting a response so the promise in the setTimeout gets rejected after the timeout expires. Apart from setting our timeout to something astronomical, we end up with a lot of rejected promises with thetimeoutmessage. Would you consider doing something like this:and then in the destroy method we would clear the
this.rejectTimeouttimer. At the moment we are doing these things in our version of talker.js but it might be handy for others who could potentially run into this issue.Thanks,
Jake