[SalesForce] Unable to pass parameters to wired property in LWC

Unable to pass parameters to wired property in LWC.

I have a standalone app

<aura:application  extends="force.slds">
    <c:abc a="a" b="a,b,c" c="c" />
</aura:application>

and Lightning Web Component abc.

Listing of abc.html

<template>
    {d}  {e} 
    <template if:true={deWired}>
        Data: {deWired.data}
        Error:  {deWired.error}
    </template> 
</template>

Listing of abc.js

import { LightningElement, wire, track, api } from 'lwc';
import getDE from '@salesforce/apex/ABCCont.getDE';
export default class Abc extends LightningElement {
    @api a;
    @api b;
    @api c;

    @wire(getDE, { a:this.a, b:this.b.split(','), c:this.c})
    deWired = {};

    @track d;
    @track e;
    @track error;
    connectedCallback() {
        getDE({ a:this.a, b:this.b.split(','),c:this.c}).then(result=>{
                this.d = result.d;
                this.e = result.e;
            }).catch(error => {
                this.error = error;
            });
    }
}

I am trying to use wired property deWired and wire it to the method which requires three parameters which I want to pass from another app or component which references this component. However, when I try to do this, I receive an error

This page has an error. You might just need to refresh it.
Failed to initialize a component [Cannot read property 'a' of undefined]
Failing descriptor: {c:App}

enter image description here

When I comment out lines

@wire(getDE, { a:this.a, b:this.b.split(','), c:this.c})
deWired = {};

it works like a charm. So looks like the problem is with wired property. Is there any way to use a wired property here? Are we obliged to use only Imperative Apex in this case?

Apex controller is irrelevant here, but just for reference listing of dummy ABCCont

public inherited sharing class ABCCont {
    @AuraEnabled(cacheable=true)
    public static Map<String, Object> getDE(String a, List<String> b, String c) {
        return new Map<String, Object>{'d'=>'d','e'=>'e'};
    }
}

Best Answer

Per the documentation here you want to mark your @wire methods differently.

Also from the doc:

In the wire adapter’s configuration object, prefix a value with $ to reference a property of the component instance. The $ prefix tells the wire service to treat it as a property of the class and evaluate it as this.propertyName. The property is reactive. If the property’s value changes, new data is provisioned and the component rerenders.

The right syntax is:

 @wire(getDE, { a: '$a', b: '$b', c: '$c' })
    deWired;

You also shouldn't need to call it in your connectedCallback. You can also edit your deWrired syntax to perform callback actions

@wire(getDE, { a: '$a', b: '$b', c: '$c' })
    deWired({ error, data }) {
        if (data) {
            this.d = data.d;
            this.e = data.e;
        } else if (error) {
            this.error = error;
        }
    }
Related Topic