I'm trying to listen to a MessageEvent sent with postMessage in my Angular 2 component.
My first attempt was simply doing:
window.addEventListener("message", this.handlePostMessage.bind(this));
And then in ngOnDestroy:
window.removeEventListener("message", this.handlePostMessage.bind(this));
However this didn't work as expected. If I navigated to another route and back, there would be two event listeners registered.
So instead I've been trying to decorate the method with HostListener, but I can't get this working when using prerendering (Angular Universal with .NET Core using the asp-prerender-module).
#HostListener('window:message', ['$event'])
private handlePostMessage(msg: MessageEvent) {
...
}
That gives me the following error on page load:
Exception: Call to Node module failed with error: Prerendering failed because of error: ReferenceError: MessageEvent is not defined
Is there a workaround for this?
You're getting this error because MessageEvent is not defined. You must import whatever file defines this.
My #HostListeners look like this:
#HostListener("window:savePDF", ["$event"]) savePDF(event) {
this.savePDFButtonPushed();
}
and you can read more about them here:
https://angular.io/guide/attribute-directives
However, I'm currently experiencing the same issue you are -- that if I navigate to another route and back, I now receive two events. And that is using #HostListener. :-( However I haven't upgraded Angular in a while (currently using 4.4.6), so maybe they've fixed it since that release.
**Edit: Just upgraded to Angular 5.1.0. The 'duplicate events' #HostListener issue remains. :-(
Edit #2: I tried also using window.addEventListener like you tried, and also had the same issue, despite using window.removeEventListener in ngOnDestroy().
This lead me to dig a little deeper, where I found some code I had added to listen to messages from a child iFrame. Any chance you have something similar in your code?
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to messages from child window ("unsign" and "savePDF") and pass those along as events to Angular can pick them up in its context
eventer(messageEvent,function(e) {
window.dispatchEvent( new Event( e.data ) );
},false);
This had been in my page's constructor. I protected it so it only executed the first time the page was constructor, and now all is well.
Related
I am trying to open two views in succession, both as modals in an Appgyver project. when i do supersonic.ui.modal.hide() and supersonic.ui.modal.show(some_view), the second view does not show. If I throw in an alert('here') in between the modal.hide() and modal.show(), it seems to work. What is the problem here? It's the same with supsersonic.ui.layers.pop() and supersonic.ui.layers.push(another_view) in succession.
Usage sample:
}else if (option === 'chooseLocation'){
$scope.currentOption = "location you chose.";
$scope.f = true;
supersonic.ui.modal.hide().then(function(){
supersonic.ui.modal.show("chooseLocation");
$localStorage.locationOption = 'lastUsed';
});
}
another snippet that i tried this morning that's not related to modals, but also doesn't work:
supersonic.ui.layers.popAll().then(function(){
var view = new supersonic.ui.View("searchresults#index?"+paramText);
supersonic.ui.layers.push(view);
});
The error I get on the log screen:
landing#drawer 11:23:29.382 error
"supersonic.ui.layers.popAll rejected: {}"
This seems to be a bug in the Supersonic API.
The Javascript success callback is invoked when the native wrapper has received the API call. This is invalid behaviour. The Javascript success callback should be invoked when the native wrapper has completed the API call (expected behaviour).
As a workaround, use Use Steroids.js events such as didclose to determine when the native API call has completed.
See Steroids modals and Steroids layers for further documentation.
I have filed a new bug in AppGyver Github issues
I'm having issues getting PubNub's subscribe message handler to fire. I'm working on a web client that will listen for messages from mobile apps. Up until recently, this code worked fine. I could send a message from my phone and see the web app get auto-updated. But in the last few days, the web app is no longer getting updated.
It's an Angular app that I've been writing in CoffeeScript. I have a MessageService that handles all the bootstrapping for PubNub. The subscribe method of my service is passed an entity id arg to set as the channel name to listen on, and passes a function reference via the messageHandler argument.
angular.module('exampleApp').service 'MessageService', ($http, $interval) ->
pubnub = null
subscribePromise = null
config =
subscribe_key: 'demo'
# Sanity check. This gets triggered upon connection with the correct
# channel name/entity id.
connectionHandler = ->
_.forOwn arguments, (arg) -> console.log arg
return {
getChats: (id) ->
# Calls an API to fetch all of the chat messages. These aren't transmitted over
# PubNub because we do other fun things to adhere to HIPAA compliance.
return $http.get 'path/to/api/endpoint/' + id
subscribe: (id, messageHandler) ->
pubnub = pubnub or PUBNUB.init config
pubnub.subscribe({
channel: id
message: (data) ->
if not not subscribePromise
$interval.cancel subscribePromise
subscribePromise = null
messageHandler data
connect: connectionHandler
})
# Interval-based workaround to function in spite of PubNub issue
subscribePromise = $interval messageHandler, 10000
}
Here's an example of the messageHandler implementation in one of my controllers.
angular.module('exampleApp').controller 'MessageCtrl', (MessageService) ->
$scope.messageId = 'some entity id'
# This message handler never gets fired, despite passing it to pubnub.subscribe
onMessageUpdated = (data) ->
console.log data
MessageService.getChats($scope.messageId).then (messages) -> $scope.messages = messages
MessageService.subscribe $scope.messageId, onMessageUpdated
Like I mentioned, this code was working not long ago, but out of the blue, the message handler stopped firing at all. Haven't touched it in more than a month. The thing that's driving me nuts is that I can open up the dev console in PubNub and watch the messages come in from the phones, but for some reason, that message handler never seems to get called.
I'm using the "edge" version of pubnub.js, so I'm wondering if there was some recent update that broke my implementation. Anything else you folks can see that I may be missing or doing wrong? Any help is appreciated.
// Edit
Just a quick update. I've tried rolling back as far as 3.5.47 and still no change in behavior. I coded a quick workaround using Angular's $interval service to allow the app to at least function while I get this issue figured out. Updated code example above w/ relevant changes.
Quick update. After moving on to some other tasks and circling back to this after a year or so, we decided to take another stab at the problem. The interval-based polling was working fine for our initial implementation as described above, but we now have need for a more robust set of features.
Anyway, we ended up grabbing the latest stable version of the JS client (3.7.21), and so far it appears to have fixed our issue.
I have an AngularJS application that I intend to have receive communications via SignalR from the server, most notably when data changes and I want the client to refresh itself.
The following is my hub logic:
[HubName("update")]
public class SignalRHub : Hub
{
public static void SendDataChangedMessage(string changeType)
{
var context = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>();
context.Clients.All.ReceiveDataChangedMessage(changeType);
}
}
I use the following within my API after the data operation has successfully occurred to send the message to the clients:
SignalRHub.SendDataChangedMessage("newdata");
Within my AngularJS application, I create a service for SignalR with the following javascript that's referenced in the HTML page:
angular.module('MyApp').value('signalr', $.connection.update);
Within the root for the AngularJS module, I set this up with the following so that it starts and I can see the debug output:
$(function () {
$.connection.hub.logging = true;
$.connection.hub.start();
});
$.connection.hub.error(function(err) {
console.log('An error occurred: ' + err);
});
Then I've got my controller. It's got all sorts of wonderful things in it, but I'll show the basics as relate to this issue:
angular.module('MyApp').controller('MyController', function($scope, signalr) {
signalr.client.ReceiveDataChangedMessage = function dataReceived(changeType) {
console.log('DataChangedUpdate: ' + changeType);
};
});
Unfortunately, when I set a breakpoint in the javascript, this never executes though the rest of the program works fine (including performing the operation in the API).
Some additional (hopefully) helpful information:
If I set a breakpoint in the SignalRHub class, the method is successfully called as expected and throws no exceptions.
If I look at Fiddler, I can see the polling operations but never see any sign of the call being sent to the client.
The Chrome console shows that the AngularJS client negotiates the websocket endpoint, it opens it, initiates the start request, transitions to the connected state, and monitors the keep alive with a warning and connection lost timeout. There's no indication that the client ever disconnects from the server.
I reference the proxy script available at http://localhost:port/signalr/hubs in my HTML file so I disregard the first error I receive stating that no hubs have been subscribed to. Partly because the very next message in the console is the negotiation with the server and if I later use '$.connection.hub' in the console, I'll see the populated object.
I appreciate any help you can provide. Thanks!
It's not easy to reproduce it here, but it's likely that the controller function is invoked after the start of the connection. You can verify with a couple of breakpoints on the first line of the controller and on the start call. If I'm right, that's why you are not called back, because the callback on the client member must be defined before starting the connection. Try restructuring your code a bit in order to ensure the right order.
My Ext (Sencha) page throws this JS error when it initialises:
Uncaught TypeError: Cannot read property 'value' of null - ext-all-debug.js:89797
it errors on this line:
startUp: function () {
var me = this;
me.currentToken = me.hiddenField.value
Because 'hiddenField' is null.
Without pasting the entire page content (it's very big, and under NDA), can anyone tell what I should look for that might be on my page that's causing this?
Looks you're using the History and haven't created the appropriate hidden/iframe elements that it needs. Have a look at the history example for the version you're using.
When using a Restful Store the remove command is throwing an error (Line 1717 of ext-base-debug Error: Invalid argument) when it tries make the DELETE ajax request. Specifically the error is occurring in the asyncRequest method in ext-base when o.conn.send(postData || null); is called. I created a standard Ajax request and used the DELETE method along with the same URL and it worked fine. All other actions in the Store (Create, Read, and Update) work fine.
The EXT JS example RESTful store throws an error as well located here: http://www.sencha.com/deploy/dev/examples/restful/restful.html
It looks like :
Problem with jQuery.ajax with 'delete' method in ie
I tracked down the problem which stemmed from using the ext-basex user extension. If you are using ext-basex try overriding the forceActiveX boolean by adding this to your overrides: Ext.lib.Ajax.forceActiveX = true;