[SalesForce] LWC Apex method not returning expected result

For Lightning web component, I'm following the Apex imperative pattern described here but the result in the LWC is always undefined even though I know the Apex method returns values.

I have an LWC that takes some input, then I instantiate an object from the data and pass it to an Apex method. I expect to get an array of contacts in return, but I always get undefined.

When I call the Apex method directly in execute anonymous, I get a Contact list, so I know the method is running correctly.

Is there something wrong with the object I'm passing to the Apex method, or am I doing something wrong with the result from the method call?

Here is the HTML:

<template>
    <lightning-input data-formfield="firstName" label="First Name" required></lightning-input>
    <lightning-input data-formfield="lastName" label="Last Name" required></lightning-input>
    <lightning-input data-formfield="mobile" label="Mobile" type="phone" class="spec-req"></lightning-input>
    <lightning-input data-formfield="email" label="Email" type="email" class="spec-req"></lightning-input>
    <lightning-button label="Submit" click={handleFirstSubmit}></lightning-button>
</template>

Here is the JS:

import { LightningElement, track, api, wire } from 'lwc';
import findContacts from '@salesforce/apex/TMC_ContactServices.findContacts';

export default class BatchRegistration extends LightningElement {
    @track foundContacts;
    @track submittedContact;

    // Handle the initial contact entry.
    handleFirstSubmit() {
        // Build contact record
        let submittedContact = { 'sObjectType': 'Contact' };
        submittedContact.FirstName = this.template.querySelector('lightning-input[data-formfield="firstName"]').value;
        submittedContact.LastName = this.template.querySelector('lightning-input[data-formfield="firstName"]').value;
        submittedContact.Email = this.template.querySelector('lightning-input[data-formfield="email"]').value;
        submittedContact.MobilePhone = this.template.querySelector('lightning-input[data-formfield="mobile"]').value;
        console.log('submittedContact ' + JSON.stringify(submittedContact));

        // Call the Apex method to find existing contacts
        findContacts({ con: submittedContact })
        .then(result => {
            console.log('result ' + JSON.stringify(result));
            this.foundContacts = result;
        })
        .catch (error => {
            console.log('error ' + error.message);
        });
    }
}

Here is the Apex class:

public without sharing class TMC_ContactServices {
    @AuraEnabled
    public static List<Contact> findContacts(Contact con) {
        List<Contact> foundInitialContacts = new List<Contact>();

        // CODE OMITTED FOR BREVITY
        // Use duplicate rules here to find existing contacts based on the con parameter.
        // This populates the foundInitialContacts list but it has IDs only, so we have to re-select to get the desired fields.
        ....

        // Now we select the fields we need for the duplicate list and return it.
        if (!foundInitialContacts.isEmpty()) {
            return [SELECT FirstName, LastName, Email, MobilePhone, MailingPostalCode FROM Contact
                    WHERE Id IN :foundInitialContacts];
        } else {
            return null;
        }
    }
}

Best Answer

Arrgh, I was mapping the firstName datafield into the LastName field in the submittedContact. I fixed it and it works.