3

I have a quick way of entering multiple records where user can add rows(record) to add. I am using lightning:recordEditForm component in aura:iteration. When i add multiple rows everything is working just fine. However, when I use only one row to enter it gives me error

$controller$save [component.find(...).forEach is not a function]

This happens only if there is one record to add. Now if I use component.find('editForm'.submit(); I can enter one record but it is not working for multiple records.

My lightning cmp:

<aura:iteration items="{!v.venList}" var="ven" indexVar="index">
                        <tr>
                        <lightning:recordEditForm objectApiName="Vendor_Invoice__c" aura:id="editForm" onsuccess="{!c.handleSuccess}">
                            <lightning:messages />
                            <td>
                                {!index + 1}
                           </td>
                            <td>
                                <lightning:inputField class="slds-size_1-of-12" fieldName="Vendor_Name__c" />
                             </td>
                            <td>
                                <lightning:inputField class="slds-size_2-of-12" fieldName="Name" />
                            </td>
                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="Bill_Cycle__c" />
                             </td>
                            <td>
                                <lightning:inputField class="slds-size_1-of-12" fieldName="Vendor_Customer_Service_Number__c" />
                             </td>
                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="Vendor_Repair_Number__c" />
                             </td>
                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="Last_Download__c" />
                            </td>
                            <td>
                                  <lightning:inputField class="slds-size_1-of-12" fieldName="Initial_Bill_Date__c" />
                            </td>

                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="Online_Access__c" />
                             </td>
                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="X180_Monitored__c" />
                             </td>
                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="Location_Name__c" />
                             </td>
                            <td>
                                 <lightning:inputField class="slds-size_1-of-12" fieldName="Location_Address__c" />
                            </td>
                            <td style="display :none">
                                <lightning:inputField fieldName="Account__c" value="{!v.recordId}"/>
                            </td>
                            <td>
                                <a onclick="{!c.removeRow}" data-record="{!index}">
                                    <lightning:icon iconName="utility:delete" size="small" alternativeText="Delete"/>
                                    <span class="slds-assistive-text">Delete</span>
                                </a>
                            </td> 
                            </lightning:recordEditForm>
                        </tr>
                    </aura:iteration>

Javascript Controller

 save: function(component, event, helper) {

         component.find("editForm").forEach(form => form.submit());  
  }

I have tried the following solutions: Is it possible to mass-save many lightning:recordEditForms with only ONE button?

Multi Insert with recordEditForm

I cannot understand why it is giving this error. Thanks in advance!

2

Normally, that happens because forEach is an Array method, hence the error forEach is not a function.

component.find, returns an Array-like collection, but not an array in which you can invoke the forEach method.

find() returns different types depending on the result.

  • If the local ID is unique, find() returns the component.
  • If there are multiple components with the same local ID, find() returns an array of the components.
  • If there is no matching local ID, find() returns undefined.

I went ahead, and added multiple forms on a lgnt component and successfully created multiple records by iterating, I did not however, create my recordEditforms dynamically within an aura iteration.

the only difference I spot at this time are the missing braces in your function:

component.find("editForm").forEach( form =>{
        form.submit();

    })
  • is there a way around where it will work with adding single record as well? – Nikhil Prashar Apr 3 '19 at 13:47
  • I have tried component.find('editfor').array.prototype.forEach(); however, it is saying prototype is not a function – Nikhil Prashar Apr 3 '19 at 14:42
  • according to the link that you listed, it says that it can be parsed to array with that notation. i am very new to this so that is why I am trying to understand how this works – Nikhil Prashar Apr 3 '19 at 17:51
  • it states "Although NodeList is not an Array, it is possible to iterate over it with forEach(). It can also be converted to a real Array using Array.from().However, some older browsers have not implemented NodeList.forEach() nor Array.from(). This can be circumvented by using Array.prototype.forEach() ". Since I am using IE browser i tried Array.prototype.forEach() – Nikhil Prashar Apr 3 '19 at 18:07
  • the original document that you linked about NodeList was more informative. I dont understand how to use HTML Collection, all I understood that it is a generic collection type like array. But sticking to your original comment, that component.find returns nodelist, I tried doing "var arr = Array(component.find('editForm')); arr.forEach(form => form.submit());" – Nikhil Prashar Apr 3 '19 at 18:34
2

There is a trick which is very much hidden in the documentation highlighted by @glls already in the answer.

Here is what the documentation says: find documentation

So we can handle this with concat method of array:

var editForms = c.find('editForm');
var forms = [].concat(editForms || []);
/* Now here the forms will always be an array, and won't break your code anymore. */

forms.forEach(form => form.submit()); 
  • That makes alot of sense. Thanks a lot! Just to understand it better. If we have multiple component of same name and want to do something action e.g. sum all the components then can we do form => form.sum(forms)? – Nikhil Prashar Apr 3 '19 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.