+ Start a Discussion
Leonardo Brozinga ViglinoLeonardo Brozinga Viglino 

Lightning data service 'DRAFT' state help when using mobile app

Hello All,

I'm currently developing a component to use in a quick action in a record page of a Custom object I created.
My component will use Lightning data service to create records of two different custom objects.
I will call one object Main__c, and the other one Smaller__c, Smaller__c is a child of Main__c and has a lookup relationship to it.
My component is composed by one Main component, which houses other Smaller components.
Inside my Main component, I use iteration to create a list of another Smaller components, in which each one have input fields to user input and a file upload element.
Also in my Main component, I have a save button which will execute LDS(Lightning Data services) saveRecord in both Main and Smaller Components.
Whenver the user fills up the entire Smaller components list fields, he clicks the Save button. This executes saveRecord in my force:recordData located in my Main component, creating a Main__c object.
Using saveResult.state, I check what the result was, if it is 'SUCCESS' or 'DRAFT', I fire an event which will be handled by each Smaller components. This event carries the recently created Main__c ID using lightning event attributes and saveResult.recordId to get the Main__c ID.
Each Smaller component has a handler to the event generated by Main component, whenever it gets fired it will execute its force:recordData.saveRecord in order to its corresponding Smaller__c object , with the user typed in info, and uses the event parameter to get the Main__c Id to populate the Smaller__c lookup relationship fild to Main__c. Note: the Main component contains several Smaller components, and the event will be listened by each one of the Smaller component, therefore creating one Smaller__c for each.

This works perfectly when I'm testing in desktop, the problem is I need this to work in mobile app.

When I try it at mobile app, my Main__c creation saveResult always return with 'DRAFT', and its saveResult.RecordId is something weird as "a05___qkEjrVUV9AIO", yes it has 3 underscores in it '___'.
So, when the event is fired, Smaller__c creation fails because the parent Main__c wasn't succesfully created, because it is in 'DRAFT', and I'm sure he can't find "a05___qkEjrVUV9AIO" as a valid Id.

Of course, I can just not fire the event when the saveResult is 'DRAFT', but if I do so, then my Main__c object with 'DRAFT' state will eventually be created outside my lightning component runtime, but my child Smaller__c objects will never be created.

A possible solution that came to me, would be an apex trigger after Main__c is insert object that would fire the events in Smaller components. But I'm not sure it's possible to fire lighting events inside Apex Triggers.

My component works perfectly in desktop, how can I address this issue for mobile, when my parent object is in 'DRAFT' state?

Khan AnasKhan Anas (Salesforce Developers) 
Hi Leonardo,

Greetings to you!

According to this trailhead module: https://trailhead.salesforce.com/en/content/learn/modules/lightning_data_service/lightning_data_service_manipulate_records

Asynchronous Record Saving

Hypothetical situation time! So you’re using the Salesforce app, and a save attempt fails to reach the server due to connection issues. Maybe the train you’re on went into a tunnel, you accidentally roamed through that corner of the building without cell reception, or gremlins have been messing with the cell towers again. In any case, don’t worry, LDS has your back. In the event of a connection problem, Lightning Data Service stores your changes in a local cache. This is indicated by a DRAFT state in the SaveRecordResult object. A record’s DRAFT state is resolved when the connection is restored. When saving a record through LDS, the local cache isn’t updated until the save is complete. When the save is successfully completed on the server, the cache is updated to the latest version of the record from the server, and all components with a reference to that record are notified. You don’t have to worry about manually reloading the record into the cache after saving. LDS handles all the work for you.

Saves that occur when a device is offline result in a DRAFT state if you enable asynchronous save permissions, or if all of the following are true:
  • The client can’t reach the server.
  • The org has enabled offline drafts.
  • You have version 9.0 or newer of the Salesforce app.

Whenever you were trying to save a record the status is always DRAFT which means the record is not committed to the server yet, that's why it was showing that weird Record ID in logs.
You can resolve this by unchecking this option "Enable offline create, edit, and delete in Salesforce for Android and iOS." available under "Salesforce Offline" in setup.

Reference: https://developer.salesforce.com/forums?id=9060G0000005iDeQAI

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Leonardo Brozinga ViglinoLeonardo Brozinga Viglino
Hello Khan Anas,

Thanks for your reply! So unchecking "Enable offline create, edit, and delete in Salesforce for Android and iOS" solved my problem for now, since none record will be created in 'DRAFT' state anymore. However, I wouldn't call this a solution because in case my component is used in an org where this feature is required, my component will not work. I wonder that a possible solution would be Salesforce to allow mobile to create related draft records in mobile.

Thank you,
I think it's sub optimum approach to leverage LDS for child records because it would be making a server trip over the network for each child component while retrieving as well as saving. Also it would consume single SOQL / DML for each child component  wheras one SOQL or DML for all child components will be used if a custom lightning backed controller is used