1

I know it is possible to include a lightning web component into a VisualForce page. It's also possible to include multiple lightning web components into a VisualForce page. Though, I cannot find a way to fireEvent and registerListener so that I can pass data between 2 lightning web components included in my VisualForce page.

I've tried by importing the following

import { currentPageReference } from 'lightning/navigation';

But this is returning me an exception, that the currentPageReference should have an @wire{currentPageReference} pageRef property. Which makes sense as we cannot access the lightning in VisualForce

I've also created my own pubsub module, which works ok when using in the lightning experience builder. So communication between the two components is working on lightning pages.

Any tips or hints on this topic?

Code to show what I have tried:

Fire event...

import { LightningElement, wire, api } from 'lwc';
import { CurrentPageReference } from "lightning/navigation";
import { registerListener, unregisterAllListeners, fireEvent } from "c/xxx_pubsub";

export default class xxx extends LightningElement {

    @wire(CurrentPageReference) pageRef;
    @api searchInput;

    handleProductSearch(event) {
        this.searchInput = event.target.value;
        fireEvent(this.pageRef, "startSearch", this.searchInput);
    }
}

Listener...

import { LightningElement, track, api, wire } from 'lwc';
import { CurrentPageReference } from 'lightning/navigation';
import { registerListener, unregisterAllListeners, fireEvent } from "c/xxx_pubsub";

connectedCallback() {
    // Some method which is called
    registerListener("startSearch", this.getSearchResult, this);
}

Thank you

Update on this topic

As Salesforce-sas suggested, I'm using the lightning messages service.

One component is using the following code.

import { LightningElement, wire } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import productsChannel from '@salesforce/messageChannel/SearchProductsChannel__c';

export default class xxx extends LightningElement {

    @wire(MessageContext) messageContext;

    handleProductSearch(event) {
        // Read the data which we'll use and store in variable
        payload = { searchInput: event.target.value };

        // "Publish data in our channel"
        publish(this.messageContext, productsChannel, payload);
    }

}

The other component, which should receive the data is as follows:

import { LightningElement, track, wire } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import getSearchResult from '@salesforce/apex/xxx.getSearchProdDetails';
import { subscribe, unsubscribe, MessageContext, APPLICATION_SCOPE } from 'lightning/messageService';
import productsChannel from '@salesforce/messageChannel/SearchProductsChannel__c';

export default class xxx extends LightningElement {

    searchInput;
    filterCriteria = null;

    @wire(MessageContext) messageContext;
    @wire(getSearchResult, {searchInput: '$searchInput'}) searchResult ({error, data}) {
        if (error) {
            console.log(error);
        } else if (data) {
            console.log(data);
        }
    }

    subscribeToChannel() {
        console.log("here 2");
        if (!this.filterCriteria) {
            this.filterCriteria = subscribe(
                this.messageContext,
                productsChannel, 
                (message) => this.handleMessage(message),
                { scope: APPLICATION_SCOPE }
            );

            console.log(this.filterCriteria);
        }
    }

    unsubscribeToChannel() {
        unsubscribe(this.filterCriteria);
        this.filterCriteria = null;
    }

    connectedCallback() {
        console.log("here");
        this.subscribeToChannel();
        //this.getSearchResult('SearchString');
    }

    getSearchResult(searchInput){
        console.log(searchInput);
        if(searchInput !== undefined){

            // Stringify the search input
            let searchInput = JSON.stringify({
                searchString: 'SearchString'
            });

            // Call the method
            getSearchResult({searchInput:searchInput}).then(result => {
                if (result && result['productList']) {
                    console.log(result);
                }
            });
        }
    }

    disconnectedCallback() {
        this.unsubscribeToChannel();
    }

    handleMessage(message) {
        console.log('biep');
        this.searchInput = message.searchInput;
    }

}

Further help is really appreciated.

Currently when right before the lwc gets injected to the DOM, I see some calls are being triggered. Though I don't get inside the handleMessage method.

Also, when firing the event handleProductSearch I don't see anything happening on the other component.

Thank you

2 Answers 2

2

You can use Message Service - GA from summer 20

Use Lightning message service to communicate across the DOM between Visualforce pages, Aura components, and Lightning web components, including components in a pop-out utility bar.

Use the Lightning message service functions to communicate over a Lightning message channel.

3
  • I've tried to implement it, but until now without success. I'll update my question. Jun 19, 2020 at 8:45
  • @JeroenBellemans the org you are testing on - is it on summer 20? Jun 19, 2020 at 15:36
  • Sorry for the late reply. But yes it is. Jun 23, 2020 at 10:15
0

Salesforce documentation: Communicate Across the DOM can be done via 2 ways: Lightning Message Service and pubsub Module.

Reference: Communicate Across the DOM

1
  • The pubsub module needs a @wire(currentPageReference) pageRef property. When being on a VisualForce page, I cannot access the lightning/navigation module and read this pageReference. I'm using the Lightning Message Service Jun 19, 2020 at 9:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .