function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Michael Friedman 7Michael Friedman 7 

Lightning Component Upsert - Attempted to upsert a null list

I am using the Expense__c tracker app as a template to create a custom lightning component for adding new Events. When I click save on the form, the log in the developer console returns an error: Attempted to upsert a null list.

Here is my Component:
 
<aura:component controller="EventController" implements="force:appHostable,flexipage:availableForAllPageTypes" access="global">
<aura:attribute name="allDay" type="Boolean" default="False"/>
<aura:attribute name="events" type="Event[]"/>
<aura:attribute name="newEvent" type="Event"
                 default="{ 'sobjectType': 'Event',
                         'Subject': 'Default Subject',
                         'OwnerId': '005j000000BRyZ1AAL',
                         'StartDateTime': 'now()',
                         
                         'WhoId': '005j000000BRyZ1AAL',
                         'WhatId': '00Q63000001qAPqEAM',
                         'Consult_Amount__c': '123.10',
                         'Event_Status__c': 'Completed',
                         'Event_Type__c': 'Lunch',
                         'DurationInMinutes': '30'
                       }"/>


<!--Assigned To Form Element -->
<ui:inputSelect label="Assigned To" multiple="false" required="true">
    <ui:inputSelectOption text="All Primary" label="All Contacts" value="true"/>
    <ui:inputSelectOption text="All Primary" label="All Primary"/>
    <ui:inputSelectOption text="All Secondary" label="All Secondary"/>
</ui:inputSelect>
    
<!--Subject Form Element -->	
<ui:inputText label="Subject"  placeholder="Enter Subject" value="{!v.newEvent.Subject}"/>
    
<!--All Day Event Form Element -->
<ui:inputCheckbox label="All Day Event" value="{!v.newEvent.IsAllDayEvent}" />

<!--Renders Date or DateTime UI Input based on All Day Event Check Box -->    
    <aura:if isTrue="{!v.newEvent.IsAllDayEvent}">
        
<!--Start/End Date Form Elements -->
<ui:inputDate aura:id="startdate" label="Start Date" value="{!v.newEvent.StartDateTime}" displayDatePicker="true" />
<ui:inputDate aura:id="enddate" label="End Date" value="{!v.newEvent.EndDateTime}" displayDatePicker="true" />
        <aura:set attribute="else">
            
<!--Start/End DateTime Form Elements -->
<ui:inputDateTime aura:id="startdatetime" label="Start Date" class="field" value="{!v.newEvent.StartDateTime}" displayDatePicker="true" />
<ui:inputDateTime aura:id="enddatetime" label="End Date" class="field" value="{!v.newEvent.EndDateTime}" displayDatePicker="true" />    
    </aura:set>
    </aura:if>
    
<!--Invitee Form Element -->
<ui:inputSelect label="Invitees Of This Event" multiple="True" required="true">
    <ui:inputSelectOption text="All Primary" label="All Contacts" value="true"/>
    <ui:inputSelectOption text="All Primary" label="All Primary"/>
    <ui:inputSelectOption text="All Secondary" label="All Secondary"/>
</ui:inputSelect>
    
<!--Event Type Form Element -->
<ui:inputSelect label="Event Type" multiple="False" required="true">
    <ui:inputSelectOption text="All Primary" label="All Contacts" value="true"/>
    <ui:inputSelectOption text="All Primary" label="All Primary"/>
    <ui:inputSelectOption text="All Secondary" label="All Secondary"/>
</ui:inputSelect>
    
<!--Event Status Type Form Element -->
<ui:inputSelect label="Event Status Type" multiple="False" required="true">
    <ui:inputSelectOption text="Completed" label="Completed" value="true"/>
    <ui:inputSelectOption text="Canceled" label="Canceled"/>
    <ui:inputSelectOption text="No/Show" label="No/Show"/>
</ui:inputSelect>
    
<!--Rescheduled from Prior Consult Form Element -->
<ui:inputCheckbox label="Rescheduled from Prior Consult" value=""/>

<!--Is Paid Consult Form Element -->
<ui:inputCheckbox label="Is Paid Consult" value=""/>

<!--Consult Amount Form Element -->	
<ui:inputText label="Consult Amount" value="Consult Amount" required="true"/>
    
<!--Related To Form Element -->
<ui:inputSelect label="Related To" multiple="False" required="true">
    <ui:inputSelectOption text="Matter" label="Matter" value="true"/>
    <ui:inputSelectOption text="Prospect" label="Prospect"/>
</ui:inputSelect>

<!--Save Event Button-->
    <ui:button label="Save" press="{!c.createEvent}"/>
    
</aura:component>
Here is my JS Controller:
 
({
	createEvent : function(component, event, helper) {
    // Validate form fields
    // Pass form data to a helper function
    var newEvent = component.get("v.newEvent");
    helper.createEvent(component, newEvent);
}
})

Here is my Helper:
 
({
	createEvent: function(component, event) {
    //Save the event and update the view
    this.upsertEvent(component, event, function(a) {
        var events = component.get("v.events");
        
        events.push(a.getReturnValue());
        
        component.set("v.events", events);
       
    });
},
upsertEvent : function(component, event, callback) {
  var action = component.get("c.saveEvent");
  action.setParams({ 
      'event': event
  });
  if (callback) {
      action.setCallback(this, callback);
  }
  $A.enqueueAction(action);
}
})
Here is my Apex Controller:
public with sharing class EventController {
@AuraEnabled
    public static List<Event> getEvents() {
        String runningUser = UserInfo.getUserId();
        List<Event> events =  Database.query(
                'SELECT Id, Subject, WhoId, WhatId, EndDateTime, StartDateTime, Matter_Type__c, Color_Code__c, Type, Event_Type__c, OwnerId FROM Event WHERE OwnerId =  :runningUser AND (StartDateTime = LAST_N_DAYS:45 OR StartDateTime = NEXT_N_DAYS:45)');

        //Add isAccessible() check
        return events;
    }
    @AuraEnabled
    // Retrieve all primary contacts
    public static List<Event> getConsult() {
        List<Event> consultEvents = 
             [SELECT Id, Subject, WhoId, WhatId, EndDateTime, StartDateTime, ActivityDate, OwnerId, Type FROM Event WHERE Event_Type__c = 'Consult' AND OwnerId = '005j000000BRyZ1'];

        //Add isAccessible() check
        return consultEvents;
    }

  @AuraEnabled
public static Event saveEvent(Event event) {
    // Perform isUpdateable() check here 
    
   
    					
    upsert event;
    return event;
} 
    

  
    
}
The extra code in the controller is for another part of the app. It looks like the data is being passed to the Apex controller from the component and that the Apex controller is set up the same way as the example.

Any ideas on how to troubleshoot would be appreciated.


 
Best Answer chosen by Michael Friedman 7
_Zach Boyd_Zach Boyd
Nice find! That actually does work for binding attributes on the lightning component and passing the correct values to your controller, but I also needed to update the saveEvent method parameter to also be an SObject. I just casted it to the Event object in case there were any actions that needed to be taken on the properties. Try this snippet of code.
 
@AuraEnabled
public static Event saveEvent( SObject eventObj ) {
        
        Event event = (Event) eventObj;
        
        upsert event;
        return event;
        
}

 

All Answers

_Zach Boyd_Zach Boyd
I don't see anything wrong with your code, but I did come across this blog post that is related. It looks like there might be a bug with the Event object in Lightning components. I setup a simple example and was able to replicate your exact scenario. I then tested by changing to the Account object type and everything saved succesfully.

http://thekedarjoshi.blogspot.com/2016/03/event-auraattribute-type-in-lightning_39.html
Michael Friedman 7Michael Friedman 7
Zach, thanks for looking at this and for finding that blog post - I hadn't seen that yet. One question: I already have the attribute for Event as an array and am still having an issue saving. Does that suggest the bug goes deeper that just the way lightning handles the Event attribute? In any case, I will try my component out with a different object and see if I can find a workaround. Thanks, again! Michael Friedman Consultant VennScience 603.433.8500 (Office)
_Zach Boyd_Zach Boyd
Your welcome. Here is another link describing your exact issue and they solved it by passing the individual attributes into the Apex controller method and then created the Event object. That would be a guaranteed way to work, but definitely not ideal.

http://salesforce.stackexchange.com/questions/89194/auraattribute-not-working-for-event-object
Michael Friedman 7Michael Friedman 7
Another good idea. I will test that out. I had also opened a case with Salesforce support and they pointed me to a known bug listed here: https://success.salesforce.com/issues_view?id=a1p30000000eQHpAAM There is a workaround, but I haven't gotten it to work yet. Michael Friedman Consultant VennScience 603.433.8500 (Office)
_Zach Boyd_Zach Boyd
Nice find! That actually does work for binding attributes on the lightning component and passing the correct values to your controller, but I also needed to update the saveEvent method parameter to also be an SObject. I just casted it to the Event object in case there were any actions that needed to be taken on the properties. Try this snippet of code.
 
@AuraEnabled
public static Event saveEvent( SObject eventObj ) {
        
        Event event = (Event) eventObj;
        
        upsert event;
        return event;
        
}

 
This was selected as the best answer
Michael Friedman 7Michael Friedman 7
Zach, that did it. Looks like it is saving now as expected. Thanks again for you help with this.