Let's consider a Lightning component with a single button and which uses a CometD / Streaming API to handle some server actions. A button click calls a server-side controller's action which inserts a PushTopic's object. After receiving a Streaming API event I'd like to fire an application-type event. To make a case simplier, I handle that event inside of the same component.
The problem is that when I try to configure the event (at the line evt.setParams({testObject : testObject});
), I receive browser's exception:
TypeError: Cannot read property 'setParams' of undefined
In my opinion it looks like the event is not visible and I'm really out of ideas how to make it work. Code below:
TestComponent.cmp:
<aura:component controller="TestController" implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
<ltng:require scripts="{!$Resource.JsCometd}" afterScriptsLoaded="{!c.doInit}" />
<aura:registerEvent name="testEvent" type="c:TestEvent"/>
<aura:handler event="c:TestEvent" action="{!c.onTestEvent}"/>
<ui:button label="Click Me" press="{!c.buttonClicked}"/>
</aura:component>
TestComponentController.js:
({
// Button click handler
buttonClicked : function(component, event, helper) {
console.log("Button clicked.");
var action = component.get("c.insertTestObject");
action.setParams({testFieldValue : "testValue"});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
console.log("Test object inserted!");
} else if (state === "ERROR") {
console.log("An error has occurred while test object inserting");
}
});
$A.enqueueAction(action);
},
// Event handler
onTestEvent : function(component, event, helper) {
var testObject = event.getParam("testObject");
console.log(testObject);
},
// CometD / Streaming API init
doInit : function(component, event, helper) {
let cometd = new org.cometd.CometD();
function onMessage(message) {
console.log('Platform event received. ' + JSON.stringify(message));
var testObject = message.data.sobject;
// Invoking an event
var evt = $A.get("e.c:TestEvent");
// ----------------- HERE IS THE EXCEPTION THROWN ----------------
evt.setParams({testObject : testObject});
evt.fire();
}
function initCometd() {
let channelUrl = '/topic/TestPushTopic';
cometd.handshake($A.getCallback(function(handshakeReply) {
console.log('handshake response');
console.log(handshakeReply);
if(handshakeReply.successful) {
console.log('Connected to CometD.');
let newSubscription = cometd.subscribe(channelUrl, onMessage);
}
}));
}
function onSessionId(sessionId) {
cometd.configure({
url: '/cometd/41.0/',
requestHeaders: { Authorization: "OAuth " + sessionId },
appendMessageTypeToURL: false
});
cometd.websocketEnabled = false;
console.log('CometD configured.');
setTimeout(initCometd, 1000);
}
function commonActionResponse(successCallback, errorCallback, incompleteCallback) {
return function(response) {
var state = response.getState();
console.log("State: " + state);
if (state === "SUCCESS" && successCallback) {
successCallback(response.getReturnValue());
}
else if (state === "INCOMPLETE") {
if(incompleteCallback) {
incompleteCallback(response);
}
console.log(`incomplete: ${JSON.stringify(state)}`);
}
else if (state === "ERROR") {
var errors = response.getError();
if(errorCallback) {
errorCallback(errors);
return;
}
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error messagee: " +
errors[0].message);
}
console.log(errors);
} else {
console.log("Unknown error");
}
}
}
}
let sessionAction = component.get("c.getSessionId");
sessionAction.setCallback(this, commonActionResponse(onSessionId));
$A.enqueueAction(sessionAction);
}
})
TestController.cls:
public with sharing class TestController {
@AuraEnabled
public static String getSessionId() {
return UserInfo.getSessionId();
}
@AuraEnabled
public static TestObject__c insertTestObject(String testFieldValue) {
TestObject__c testObject = new TestObject__c(TestField__c = testFieldValue);
insert testObject;
return testObject;
}
}
TestEvent.evt:
<aura:event type="APPLICATION">
<aura:attribute name="testObject" type="TestObject__c"/>
</aura:event>