2

I have a method in my Apex controller that takes two parameters, a String and a Map< String, String>. For the plain String it evaluates correctly for me to pass a variable ‘$myVariable’ and the Apex controller receives the value, but when it is embedded as a value in a map, it doesn’t evaluate it – it just passes the string ‘$myVariable’

LWC JS controller snippet:

// strToPass is received from the parent component, ex. "test value"
@api strToPass;

@wire(myApexMethod, {strParam: '$strToPass', mapStringParam:{‘key’: '$strToPass'}})
        wiredInitData({ error, data }){
        if(data){
            this.data = data;
        }
        else if(error){
            this.error = error;
        }
    }

Apex controller:

public static void myApexMethod(String strParam, Map<String, String> mapStringParam){
    System.debug(‘strParam: ‘ + strParam);
    System.debug(‘mapStringParam: ‘ + mapStringParam);
}

Results of debug statements:

strParam: test value
mapStringParam: '$strToPass'

Things I've tried that haven't worked:

// This produced the same results as above:
@wire(myApexMethod, {strParam: '$strToPass', mapStringParam:{key:'myKey', value:'$strToPass'}})

// The Apex method received null here for the map parameter:
mapValues = [{key: 'myKey', value: 'myValue' }];
@wire(myApexMethod, {strParam: '$strToPass', mapStringParam: '$mapValues'})

Seems like it's just got to be a syntax issue here, but I can't figure it out...

2
  • could you please create an object. let obj = {'fruit': 'Apple'} let data = JSON.stringify(obj); Change parameter type map to String in apex class, and parse the String in Apex method, could you try with that.
    – Sarvesh
    Sep 12, 2019 at 14:28
  • @sarveshkumar - yes if this doesn't work I can change the Apex method parameter, but I wanted to confirm that I wasn't missing something small before going that route
    – dmorse
    Sep 12, 2019 at 15:55

1 Answer 1

3

Added based on comments

You need to modify the dynamic property mapStringParam in change handler of strToPass so that wire service is invoked whenever dynamic property is changed. Below is code:

@api
get strToPass() {
    return this._strToPass;
}
set strToPass(value) {
    this._strToPass = value;
    this.mapStringParam = { key: this.strToPass };
}

@wire(myApexMethod, { mapStringParam: '$mapStringParam' })
wiredInitData({ error, data }) {
    if (data) {
        this.data = data;
    } else if (error) {
        this.error = error;
    }
}

OLD Answer

When you say strParam: '$strToPass' that means strToPass is dynamic property but when you say mapStringParam:{key:'myKey', value:'$strToPass'}, strToPass is deeply located inside object which will no more be dynamic and it will just consider it as string.

When you want wire service to be dependent on any dynamic property like myDynamicProp, it should be directly mentioned with $ at 1st level:

myApexParam: '$myDynamicProp'

So, you can change your JS as follows:

@track mapStringParam = { key: 'test value' };
@track strToPass = 'test value';

@wire(myApexMethod, {strParam: '$strToPass', mapStringParam: '$mapStringParam'})
    wiredInitData({ error, data }){
    if(data){
        this.data = data;
    }

Whenever you change mapStringParam.key, it will re-invoke this wire service. else if(error){ this.error = error; } }

4
  • Thanks @salesforce-sas that makes sense. Re-reading this I accidentally left out a part when I was trying to make it simpler to write up and explain here, but the value that I want to pass is actually an @ api annotated property that I'm receiving from a parent component. So I tried to replace the hard-coded 'test value' in the mapStringParam with the "this.strToPass" but the strToPass didn't seem to be populated in time before the mapStringParm was being constructed. I'll update the question, and if you have further thoughts would love to hear!
    – dmorse
    Sep 12, 2019 at 15:40
  • Not sure if I understand your comment correctly.. If this answer solves what you asked in question, then mark this answer solved and ask another question so that comunity can have a look at your query Sep 12, 2019 at 15:43
  • What I need is for 'test value' to be a value passed from the parent instead of a hard-coded string. Replacing the string 'test value' with 'this.strToPass' to make it dynamic did not seem to work
    – dmorse
    Sep 12, 2019 at 15:47
  • Amazing - your update works perfectly! Thanks so much for sharing!!
    – dmorse
    Sep 12, 2019 at 16:51

You must log in to answer this question.

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