Is it possible to clear force:inputField?

Theoretically it should be possible to clear values on force:inputField. But in your specific case it seems not to work as expected. force:inputField is a smart field component operating on different field types differently. For bound plain text fields the reset works while for lookups attribute updates are not rendered correctly.

Known Weakpoints

There are lots of posts here and elsewhere indicating that force:inputField has several flaws. I personally tried it about two years ago an then gave up on it. In the meantime however it looks improved a bit. But I would definitely suggest to use it carefully.

The way you are using cmp.get() and set() looks correct. But my experience with Lightning is: even small typos might end up to a ignored-behaviour with no errors so debugging is a challenge.

Also the Lightning Component Roadmap shows two planned components lightning:inputField and lightning:lookup. Now my interpretations of that is, that Salesforce is aware of the limitations of the current force:inputField and is working on a successor.

Issue Isolation

I would start to isolate the issue and extract it out of your given scenario into a new puristic test compo using only stanard objects, like Contact with the AccountId lookup. Then you'll have short code to post here in full length (as @crmprogdev suggested) and at the same time ruled out a bunch of possible side effects.

I've tried this already, but the results aren't looking very promising (see below). Therefore I would recommend to search for solutions without force:inputField.

Alternatives

Instead of force:inputField you could try to:

  • write you own custom lookup component, or look at existing stuff:
  • http://www.sfdcmonkey.com/2017/01/07/custom-lookup-lightning-component/
  • https://developer.salesforce.com/blogs/developer-relations/2015/06/salesforce-lightning-inputlookup-missing-component.html
  • http://www.jitendrazaa.com/blog/salesforce/lookup-component-in-salesforce-lightning/

I haven't tested the these examples yet.

My attempts using force:inputField

I've played around a bit using that markup

<aura:component controller="elfUHForceInputFields" implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">       
    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="Contact" type="Contact" default="{ 'sobjectType': 'Contact' }" />
    <force:inputField value="{!v.Contact.FirstName}" />
    <force:inputField value="{!v.Contact.Salutation}" />
    <force:inputField value="{!v.Contact.AccountId}" />
    <lightning:button variant="brand" label="do it" onclick="{! c.onClick }" />         
</aura:component>

With this Apex invoked in an init-handler and the result assigned to v.Contact

public class elfUHForceInputFields {
    @AuraEnabled public static Contact load(String id) {
        return Database.query( xs.soql('select *, Account.* from Contact where Id= :id') );
    }
}

My observations are

  • force:inputField bound to text fields like FirstName get populated
  • force:inputField bound to Salutation (picklist) gets populated
  • ui:input bound to Account.Name gets populated
  • force:inputField bound to AccountId (lookup) doesn't get populated

But you can use the UI to pick an Account:

  • Rendering looks ok.
  • attribute v.Contact.AccountId gets updated correctly!

Now back to you scenario in an onclick-handler after manually populating the Account lookup:

  • cmp.set('v.Contact.FirstName','test') updates the attribute and the UI
  • cmp.set('v.Contact.AccountId',null) updates the attribute but doesn't update the UI
  • same goes for setting the entire Contact.AccountId to null ==> no UI update

This inconsistent behavior looks like a bug and verifies your observation.

My idea to work around it was to dynamically create the force:inputField using $A.createComponent() in a handler and then destroy and recreate the inputField when you need to clear it.

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_dynamic_cmp_async.htm

I've tried this

   $A.createComponent(
        "force:inputField",
        {
            "value"  : cmp.getReference("v.Contact.FirstName"),
        },
        function(newCmp, status, errorMessage){
            //Add the new button to the body array
            if (status === "SUCCESS") {
                var body = cmp.get("v.body");
                body.push(newCmp);
                cmp.set("v.body", body);
            }
            else if (status === "INCOMPLETE") {
                console.log("No response from server or client is offline.")
                // Show offline error
            }
            else if (status === "ERROR") {
                console.log("Error: " + errorMessage);
                // Show error message
            }
        }
    );

Unfortunately this only brings up:

Error: An internal server error has occurred Error ID: 1690735821-95785 (-1543061012)

Conclusion

I looks like you have to implement your own lookup compo to get what you need. Possibly it's worth to test the W18 update for improvements.


After toying with force:inputField a bit, I found the following code to clear it's value.

// Clear binded value
var contractLine = component.get('v.contractLine');
contractLine.Product__c = null;
contractLine.Product__r = {'sobjectType': 'Product2'};
component.set('v.contractLine', contractLine);    

// Clear product lookup
var productLookup = component.find('Product').get('v.body')[0];
productLookup.updateValues();