0

I have two event handlers, one is fired when the user types a keystroke that I capture with the onkeyup event and the other is fired when they check or uncheck a checkbox which I capture with a onchange event.

This is in the context of a Salesforce Lightning Web Component.

I want the list of accounts to be refreshed when either event fires, so I took the code out of the event handler and put it into a method and called the method from both handlers, but it won't work outside the event handlers. I access nothing from the event handlers in the method. First I set local variables and then I call the method.

Can anyone tell me why this doesn't work?

Here is the "html" for the Lightning Web Component

accountTypeAheadSearch.html:

<template>
  <article class="slds-card slds-var-p-around_small">
    <h1>Account Type-Ahead Search Demo LWC</h1>
    <div>
      <lightning-input label="Search for account" id="searchFor" onkeyup={handleKeyUp} value={searchString}></lightning-input>
      <lightning-checkbox-group label="Show contacts" id="showContactsCheckbox" onchange={handleShowContactChange}
        options={contactsOptions} value={showContactsValue}
      >
      </lightning-checkbox-group>
    </div>

    <template if:true={showResults}>
      <h2>Search Results:</h2>
      <template for:each={searchResults} for:item="searchResult">
        <c-account-type-ahead-search-link indentlevel='0' key={searchResult.key} link={searchResult.link} name={searchResult.name}>
        </c-account-type-ahead-search-link>
        <template for:each={searchResult.contacts} for:item="searchContact">
          <c-account-type-ahead-search-link indentlevel='1' key={searchContact.key} link={searchContact.link} name={searchContact.name}>
          </c-account-type-ahead-search-link>
        </template>
      </template>
      <template if:false={searchResults.length}>
        <h2>No matching accounts</h2>
      </template>
    </template>
  </article>
</template>

Here is the JavaScript controller: accountTypeAheadSearch.js:

import { LightningElement, api } from 'lwc';
import getMatchingAccounts from '@salesforce/apex/AccountTypeAheadSearchHelper.getMatchingAccounts';

export default class AccountTypeAheadSearch extends LightningElement {

  searchString = '';
  @api searchResults = [];
  @api showResults = false;
  showContacts = false;
  showContactsValue = ['showContactsYes'];

  connectedCallback() {
    console.log('connectedCallback BEGIN');
    this.showResults = false;
    this.showContacts = true;
    console.log('connectedCallback END');
  }

  get contactsOptions() {
    return [
      { label: 'Show Contacts', value: 'showContactsYes' }
    ];
  }

  handleShowContactChange(event) {
    const val = event.target.value;
    if (val == 'showContactsYes') {
      this.showContacts = true;
    } else {
      this.showContacts = false;
    }
    getMatchingAccounts({ searchString: this.searchString, showContacts: this.showContacts })
      .then(result => {
        this.showResults = true;
        this.searchResults = result;
      })
      .catch(error => {
        this.showResults = false;
        console.log('Error in handleKeyUp');
        console.log(error);
      });
  }

  refreshSearchResults() {
    getMatchingAccounts({ searchString: this.searchString, showContacts: this.showContacts })
      .then(result => {
        this.showResults = true;
        this.searchResults = result;
      })
      .catch(error => {
        this.showResults = false;
        console.log('Error in handleKeyUp');
        console.log(error);
      });
  }

  handleKeyUp(event) {
    const val = event.target.value;
    this.searchString = val;
    if (this.searchString) {
      getMatchingAccounts({ searchString: this.searchString, showContacts: this.showContacts })
        .then(result => {
          this.showResults = true;
          this.searchResults = result;
        })
        .catch(error => {
          this.showResults = false;
          console.log('Error in handleKeyUp');
          console.log(error);
        });
    } else {
      this.showResults = false;
    }

  }


} 

As you can see, I have copied the same code in the two event handlers in a method called refreshSearchResults, but when I try this, it doesn't work.

  handleShowContactChange(event) {
    const val = event.target.value;
    if (val == 'showContactsYes') {
      this.showContacts = true;
      refreshSearchResults();
    } else {
      this.showContacts = false;
    }
  }

  handleKeyUp(event) {
    const val = event.target.value;
    this.searchString = val;
    if (this.searchString) {
      refreshSearchResults();
    } else {
      this.showResults = false;
    }

  }

The handleKeyUp method does nothing and produces no error and the handleShowContactChange method gives an error I cannot understand:

[NoErrorObjectAvailable] Script error. a()@https://static.lightning.force.com/na213/auraFW/javascript/QPQi8lbYE8YujG6og6Dqgw/aura_prod.js:992:196 {anonymous}()@https://static.lightning.force.com/na213/auraFW/javascript/QPQi8lbYE8YujG6og6Dqgw/aura_prod.js:992:389 Le()@https://static.lightning.force.com/na213/auraFW/javascript/QPQi8lbYE8YujG6og6Dqgw/aura_prod.js:13:42189 y.dispatchEvent()@https://static.lightning.force.com/na213/auraFW/javascript/QPQi8lbYE8YujG6og6Dqgw/aura_prod.js:13:13675 y.handleChange()@https://creative-shark-5y8u3x-dev-ed.lightning.force.com/components/lightning/checkboxGroup.js:1:4152

I think the Apex code is not relevant, but here it is, just in case:

public with sharing class AccountTypeAheadSearchHelper {

    /**
     * Given a searchString, returns an array of MatchingAccountsWrappers for the LWC to consume
     *
     * @param searchString a part of the name of the account to search for
     *
     * @return an array of MatchingAccountsWrappers
     */
    @AuraEnabled
    public static MatchingAccountsWrapper[] getMatchingAccounts(String searchString, Boolean showContacts) {
        String searchSpec = '%' + searchString + '%';
        List<Account> accountsFound;
        if (showContacts) {
            accountsFound = [
                SELECT Id, Name,
                    (SELECT Id, Name FROM Contacts ORDER BY Name) 
                FROM Account 
                WHERE Name LIKE :searchSpec 
                ORDER BY Name];
        } else {
            accountsFound = [
                SELECT Id, Name
                FROM Account 
                WHERE Name LIKE :searchSpec 
                ORDER BY Name];
        }

        List<MatchingAccountsWrapper> matchingAccounts = new List<MatchingAccountsWrapper>();
        for (Account ma : accountsFound) {

            MatchingAccountsWrapper mar = new MatchingAccountsWrapper(ma.Id, ma.Name, showContacts ? ma.Contacts: null);
            matchingAccounts.add(mar);
            system.debug('#@# matching account.name = ' + ma.Name);
        }
        return matchingAccounts;
    }

    private class MatchingAccountsWrapper {

        public MatchingAccountsWrapper(String k, String n) {
            key = k;
            name = n;
        }

        public MatchingAccountsWrapper(String k, String n, List<Contact> c) {
            key = k;
            name = n;
            relatedContacts = c;
        }

        public MatchingAccountsWrapper(Account a) {
            key = a.Id;
            name = a.Name;
        }

        @AuraEnabled
        public string key {get; set;}

        @AuraEnabled
        public string name {get; set;}

        @AuraEnabled
        public string link {get {
            return URL.getSalesforceBaseUrl().toExternalForm() + '/' + this.key;
        } set;}

        private List<Contact> relatedContacts {get; set;}

        @AuraEnabled
        public List<MatchingContactsWrapper> contacts {get {
            if (relatedContacts != null) {
                List<MatchingContactsWrapper> matchingContacts = new List<MatchingContactsWrapper>();
                for (Contact matchingContact : relatedContacts) {
                    MatchingContactsWrapper mac = new MatchingContactsWrapper(matchingContact);
                    matchingContacts.add(mac);
                }
                return matchingContacts;
            } else {
                return null;
            }
        } set;}
    }

    private class MatchingContactsWrapper {

        public MatchingContactsWrapper(Contact c) {
            key = c.Id;
            name = c.Name;
        }

        @AuraEnabled
        public string key {get; set;}

        @AuraEnabled
        public string name {get; set;}

        @AuraEnabled
        public string link {get {
            return URL.getSalesforceBaseUrl().toExternalForm() + '/' + this.key;
        } set;}
    }

}
2
  • 2
    you should be calling this.refreshSearchResults() Commented Jul 17, 2022 at 0:47
  • Thank you, @JaromandaX! That fixed it. I knew it was something "simple" like that, but I was stumped for far too long! Commented Jul 17, 2022 at 1:46

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.