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;}
    }

}
jkurant
  • 45
  • 7

0 Answers0