4

What would be the best way to share @wire between two lightning web components?

I went through this article but I figured that @wire is not going to work outside of a LWC. At least I couldn't trigger the method.

In this case would it make sense to make a new "helper" LWC just so that it can perform the wire work. Then load that "helper" LWC in my other 2 components and pass the data from @wire to them?

4
  • 3
    You can "extend" components. Have you tried that?
    – sfdcfox
    Aug 5, 2019 at 22:44
  • @sfdcfox I cannot find a link to this. If it's not too much to ask can you give me a link so I can read the documentation. From the sound of it it should be what I am looking for!
    – Arthlete
    Aug 5, 2019 at 23:50
  • 1
    or use a service components that then triggers an event that the other components listen for or use the pub sub model and have your other elements subscribe to the event. That way you have the service compnent that does the work and just notifies any components that listens for it's results Aug 6, 2019 at 0:31
  • Okay I found this(developer.salesforce.com/docs/component-library/bundle/…) and this(developer.salesforce.com/blogs/developer-relations/2015/03/…). @GarethJordan - That was my initial idea as well. I was asking for opinions on what people consider the best approach. Thanks for your input.
    – Arthlete
    Aug 6, 2019 at 3:05

1 Answer 1

3

You can use pubsub for sending data across components - whether wire service or any other event.

Below is listener component:

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

export default class Poc extends LightningElement {
    @track myResponse;
    @wire(CurrentPageReference) pageRef;

    connectedCallback() {
        registerListener('wiredResponse', this.getWiredResponse, this);
    }
    disconnectedCallback() {
        unregisterAllListeners(this);
    }
    getWiredResponse(response) {
        this.myResponse = response;
    }
}

HTML:

<template>
    <template if:true={myResponse}>
        <template if:true={myResponse.data}>
            <div> data - {myResponse.data} </div>
        </template>
        <template if:true={myResponse.error}>
            <div>error - {myResponse.error}</div>
        </template>
    </template>
</template>
  1. You should download and save pubsub module from HERE

  2. Register listener on init (connectCallback) and implement the method to which the response has to be passed. Here its getWiredResponse in which the response from wire service is assigned to myResponse.

  3. Also unregister in disconnected callback.


Firing component:

JS:

import { LightningElement, track, wire } from 'lwc';
import check from '@salesforce/apex/poc.check';
import { CurrentPageReference } from 'lightning/navigation';
import { fireEvent } from 'c/pubsub';

export default class PocTable extends LightningElement {
    @wire(CurrentPageReference) pageRef;

    @track checkResp;

    @wire(check)
    getcheckResp(result) {
        this.checkResp = result;
        console.log('poc table wire => ', JSON.stringify(this.checkResp));
        fireEvent(this.pageRef, 'wiredResponse', this.checkResp);
    }
}

HTML:

<template>
    <template if:true={checkResp.data}>
        <div> checkResp data - {checkResp.data} </div>
    </template>
    <template if:true={checkResp.error}>
        <div> checkResp error - {checkResp.error}</div>
    </template>
</template>
  1. In this you will need fireEvent import and you can fire the event whenever necessary. In this case inside wire service.

In both listener and firing component should have CurrentPageReference.

@wire(CurrentPageReference) pageRef;

IMPORTANT:

  1. When Wire service is implemented on any standard methods like getRecord, it uses Lighning data service, so you dont need any custom functionality to optimise code here.

  2. When wire service is used to invoke apex methods, we should be using Cacheable=true on methods mandatorily. So, even if you use wire service on same method in multiple components, the apex method will return the response only once and the wire service will share the same data resource from client cache. So, it is not really logical/needed to handle the optimisation. If 1 wire output is the input for another wire service in another component, then it makes more sense to implement the same wire service in target component. pubsub is application event and so it should not really be used in this case.

  3. Component extension will not work on wire service. This is because wire service is already optimised and LWC does not really need it that way.

4
  • Thanks, this is a very thorough answer. I have a question regarding the fireEvent. You are feeding it this.checkResp. Does this.checkResp have to be a primitive value as Salesforce were advising in their documentation, for customEvent, to only pass primitive values to avoid passing value by reference? As stated here.
    – Arthlete
    Aug 6, 2019 at 14:46
  • If its Object or array it will be passed by reference. So, the same rules apply => better to pass the clone. Aug 6, 2019 at 14:54
  • Are you saying that if I want to pass an Object through the event that it would be safe as long as I pas its clone instead?
    – Arthlete
    Aug 6, 2019 at 15:01
  • The only problem in any event if you dont clone it, the modification in target component will change the object in source component also. So, if you are sure it will never be modified and only be used for reading data, then its not a problem. Aug 6, 2019 at 15:03

You must log in to answer this question.

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