3

I've got an application scoped bean pushing json objects to a channel like this:

        <o:socket channel="controllerEventChannel" onmessage="function(message) {

                var controllerId = message.controllerId;
                var deviceId = message.deviceId;
                var companyKey = message.companyKey;

                onMessage([
                    { name: 'controllerId', value: controllerId },
                    { name: 'deviceId', value: deviceId },
                    { name: 'companyKey', value: companyKey }
                    ]);
        }"
        />

<p:remoteCommand name="onMessage" actionListener="#{controllerGroupDashboardBean.refreshListener()}"
                         update="MainForm:showList MainForm:equipmentView MainForm:mapEquipmentView"/>

But I'm tired of repeating myself and would much rather pass a json array to the channel which could be passed directly to the remote command like this:

        <o:socket channel="controllerEventChannel" onmessage="function(message) {
                onMessage(message);
        }"
        />

<p:remoteCommand name="onMessage" actionListener="#{controllerGroupDashboardBean.refreshListener()}"
                         update="MainForm:showList MainForm:equipmentView MainForm:mapEquipmentView"/>

However, this does not seem to work. I extract the parameters like this:

Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        
String companyKey = params.get("companyKey");
String controllerId = params.get("controllerId");
String deviceId = params.get("deviceId");

Every parameter resolves to null and, weirdly, the map seems to contain the parameter "undefined" mapped to "" (i.e. blank string).

Anyone?

matsa
  • 346
  • 5
  • 16

1 Answers1

3

I'm using OmniFaces commandScript for that, without any problems.

Edit:

To get request parameters, use OmniFaces for neater code:

String myParam = Faces.getRequestParameter("myJsonField", String.class);

Edit2:

<!-- When browser receive notification, this commandScript will be called -->
    <h:form id="myCommandScriptForm">
        <o:commandScript name="onNotification" actionListener="#{myBean.onNotification}" render="@none" />
    </h:form>

And in socket something like this:

<o:socket channel="my-channel" onmessage="function(notificationEvent) {onNotification(notificationEvent);}" />

In MyBean something like:

Long entityId = Faces.getRequestParameter("entityId", Long.class);

If you wanna be fancy you can update from MyBean (notice i have render="@none" in XHTML, this is because i can conditionaly determine what to update in bean):

public void onNotification() {
    if (myList.contains(myEntity)) {
        PrimeFaces.current().ajax().update(":myWrapperJsfElement");
    }
}
Nikola
  • 554
  • 1
  • 4
  • 20
  • This looks like what Im trying to do except with OmniFaces CommandScript. Isn't that tag functionally the same as PrimeFaces RemoteCommand? I will try it tomorrow and get back to you. Thanks! Oh, and what do you pass to the pushcontext? – matsa Jun 21 '23 at 17:24
  • This is indeed the way. See also "UI update design hints" section of `` documentation: https://showcase.omnifaces.org/push/socket#ui. The issue with `` is that it doesn't support taking parameters as a `Map` but basically only as a `List>`. They do so in order to support multiple parameter values by the same name, which isn't possible with a `Map`. See also https://stackoverflow.com/a/18510102 – BalusC Jun 22 '23 at 13:26
  • So, theoretically, if you want to keep using ``, then you have got to push the data in `List>` format instead of `Map`. But of course, the `` is more fit for your specific situation ;) – BalusC Jun 22 '23 at 13:31
  • I'm using OmniFaces push, not PrimeFaces. As BalusC said, showcase explains it in detail. Works realy nice. I'm pushing POJOs, they're transformed to JSON under the OmniFaces hood. – Nikola Jun 22 '23 at 20:21
  • PrimeFaces Push is removed in PF 6.3 so if you have time, migrate to OmniFaces. – Nikola Jun 22 '23 at 20:27