0

I want to retrieve(get) the data of another component.

What I want to do is: Get the data from 'iHaveData_cmp' component, and show it in 'iWantData_cmp' component.

I've tried this.template.querySelector(c-target-component).MethodToGetTheData(); to call the @api method from the target component, but it didn't work. (it constantly failed to get the target component itself)

Do I have to use MessageChannel or binding those two components as parent-child is the only way to accomplish this?

What I tried so far:

iHaveData_cmp.html

<template>
    <div>
        <lightning-input label="This is the data" value={data} read-only="true"></lightning-input>
    </div>
</template>

iHaveData_cmp.js

import { LightningElement, api } from 'lwc';

export default class IHaveData_cmp extends LightningElement {
    data = 1000;

    @api passData(){
        return this.data;
    }
}

iWantData_cmp.html

<template>
    <div>
        <lightning-input label="I show the data that I received" value={getData} read-only="true"></lightning-input>
    </div>
</template>

iWantData_cmp.js

import { LightningElement } from 'lwc';

export default class IWantData_cmp extends LightningElement {
    get getData(){
        let result = this.template.querySelector('c-i-have-data_cmp').passData();
        return result;
        // returns an error message below:
        // iWantData_cmp:13878 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'passData')
        // at get getData [as getData] (iWantData_cmp:13878:70)
        // at tmpl$l (iWantData_cmp:13862:25)
        // at app:2703:23
        // at ReactiveObserver.observe (app:2902:9)
        // at isUpdatingTemplate (app:2654:11)
        // at runWithBoundaryProtection (app:5339:7)
        // at evaluateTemplate (app:2639:5)
        // at invokeComponentRenderMethod (app:2816:41)
        // at renderComponent (app:3013:20)
        // at rehydrate (app:5030:24)
    }
}
2
  • 3
    Could you please edit the question adding the code (html and js) of both components? By the way, c-target-component should be enclosed in quote: this.template.querySelector('c-target-component'). Keep in mind that hiding too many info will reduce the chance of getting the proper help.
    – RubenDG
    Commented Nov 29, 2022 at 8:29
  • @RubenDG Hi, I updated my question. Commented Nov 30, 2022 at 0:26

2 Answers 2

1

Since iHaveData_cmp is not a child (isn't in the template) of iWantData_cmp, this.template.querySelector('c-i-have-data_cmp') returns null, that's why you got the error:

Cannot read properties of null

If the components are in the same lightning page you could use Lightning Message Service to let them communicate.
You should define and deploy a Message Channel Metadata. I.E.

<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <masterLabel>MissingHomeChannel</masterLabel>
    <isExposed>true</isExposed>
    <description>Something</description>
    <lightningMessageFields>
        <fieldName>meaningfulName</fieldName>
        <description>Optional description</description>
    </lightningMessageFields>
</LightningMessageChannel>

Then import the channel in both components:

import dataChannel from '@salesforce/messageChannel/MissingHomeChannel__c';

If iHaveData_cmp can pass the data as soon as they are available, it should publish a message on the channel and iWantData_cmp should subscribe to that channel.
Instead, if you want to retrieve the data from the other component on user input, both components should publish and subscribe to the channel.

1
  • Thank you for the clear explanation! Commented Dec 1, 2022 at 1:50
0

A component can only access components that are within it's outer template tags. So if you wanted to get data from that I_Have_Data_Cmp Component, you'd need to have a structure like this:

<template>
  <div>
    <lightning-input label="I show the data that I received" value={getData} read-only="true"></lightning-input>
  </div>
  <c-i-have-data-cmp></c-i-have-data-cmp>
</template>
1
  • I see... Thank you. I have one more question though: If I want them to be completely seperated and independent (= If I don't want to put <iHaveData_cmp> inside of <iWantData_cmp>'s template), what should i do? Commented Nov 30, 2022 at 5:17

You must log in to answer this question.

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