Critical Update Bug? “Add a Namespace Prefix to Query Parameters and pageReference.state Properties”

This critical update is breaking several of my lightning components that use the URL to receive parameters. It is stripping out parameters, however none of my fields or parameters are part of a managed package. They aren’t “query parameters”. Not sure why anything related to pageReferences would even affect my lightning components since I’m pretty certain the lightning framework doesn’t care about “pageReference.state” at all.

This feels like a bug to me. If I tell that to salesforce support (which I’m about to do anyway) they are going to tell me that I don’t have developer support. AKA, probably useless as is usually the case.

Here is an example of the URL that gets produced when I have the critical update off:
https://hs–deviv.lightning.force.com/lightning/n/RecordCreatePage?Object=Account&RecTypeId=01241000000VE0hAAG&ReturnRecId=0013C000009sJ9NQAU&Name=Test2018-09-28&ParentId=0013C000009sJ9NQAU&Account_Type__c=Franchise&BillingCity=Austin&BillingCountryCode=US&BillingPostalCode=78701&BillingStateCode=TX&BillingStreet=123%20Some%20Street2018-09-28&ShippingCity=Austin&ShippingCountryCode=US&ShippingPostalCode=78701&ShippingStateCode=TX&ShippingStreet=123%20Some%20Street2018-09-28&POS_Type__c=a0F3C0000007OyoUAE&Concept__c=a033C000001LHOGQA4&OwnerId=00541000000k4fPAAQ&Customer_Success_Manager__c=null&Sales_Rep__c=null

Here is clicking the exact same link with the update on:
https://hs–deviv.lightning.force.com/lightning/n/RecordCreatePage?Account_Type__c=Franchise&POS_Type__c=a0F3C0000007OyoUAE&Concept__c=a033C000001LHOGQA4&Sales_Rep__c=null

So, a whole bunch of seemingly random parameters just get deleted upon navigation. Doesn’t seem like that’s something the update is supposed to do. Any thoughts? Anybody else having this issue?

Just realized – this isn’t a URL button like I thought. It’s housed in a lightning component on the lightning record page.

Component:

<aura:component implements="force:appHostable,force:lightningQuickActionWithoutHeader,flexipage:availableForAllPageTypes,force:hasRecordId" access="global" >

<aura:attribute name="record" type="Account"/>

<force:recordData aura:id="accountLoader"
                  recordId="{!v.recordId}"
                  layoutType="FULL"     
                  targetRecord="{!v.record}"                        
                  targetFields="{!v.simpleRecord}"    
                  targetError="{!v.recordError}"
                  />    

<div class="slds-box slds-theme_default">      
    <div class="slds-text-heading_small">
        Data Coordinator Panel
    </div>    

    <br/>
     <ui:button label="Create Store" press="{!c.gotoURL}" />
</div>

Controller:

({
gotoURL : function(component, event, helper) {
    var a = component.get('v.record');    
    function fullEncode(str){
            // Put some special URL encoding in here since apostrophes explode the whole world
       return encodeURIComponent(str).replace(new RegExp('\'', 'g') , 'xxapostrophexx');
    }


    var urlString = '/one/one.app#/n/RecordCreatePage?Object=Account&RecTypeId=01241000000VE0hAAG';
        urlString += '&ReturnRecId=' + fullEncode(a.fields.Id.value);
        urlString += '&Name=' + fullEncode(a.fields.Name.value);
        urlString += '&ParentId=' + fullEncode(a.fields.Id.value);
        urlString += '&Account_Type__c=' + fullEncode(a.fields.Account_Type__c.value);
        urlString += '&BillingCity=' + fullEncode(a.fields.BillingCity.value);
        urlString += '&BillingCountryCode=' + fullEncode(a.fields.BillingCountryCode.value);
        urlString += '&BillingPostalCode=' + fullEncode(a.fields.BillingPostalCode.value);
        urlString += '&BillingStateCode=' + fullEncode(a.fields.BillingStateCode.value);
        urlString += '&BillingStreet=' + fullEncode(a.fields.BillingStreet.value);
        urlString += '&ShippingCity=' + fullEncode(a.fields.ShippingCity.value);
        urlString += '&ShippingCountryCode=' + fullEncode(a.fields.ShippingCountryCode.value);
        urlString += '&ShippingPostalCode=' + fullEncode(a.fields.ShippingPostalCode.value);
        urlString += '&ShippingStateCode=' + fullEncode(a.fields.ShippingStateCode.value);
        urlString += '&ShippingStreet=' + fullEncode(a.fields.ShippingStreet.value);
        urlString += '&POS_Type__c=' + fullEncode(a.fields.POS_Type__c.value);
        urlString += '&Concept__c='+ fullEncode(a.fields.Concept__c.value);
        urlString += '&OwnerId=' + fullEncode(a.fields.OwnerId.value);
        urlString += '&Customer_Success_Manager__c=' + fullEncode(a.fields.Customer_Success_Manager__c.value);
        urlString += '&Sales_Rep__c=' + fullEncode(a.fields.Sales_Rep__c.value);

    var urlEvent = $A.get("e.force:navigateToURL");
    urlEvent.setParams({
      "url": urlString
    })
    urlEvent.fire();
}

})

Answer

When the critical update mentions query parameters it’s referring the the values in the URL after the ?, so BillingCity=, Sales_Rep__c=, etc. The terminology is a bit inconsistent, see this question for an extended discussion on the matter. So if anything the bug in this case is that it’s not stripping all your url parameters.

My guess is that this is intended to prevent components in a different name space from reading the content of URL parameters from components in different spaces. While it appears that merely including a double underscore in the parameter name works for you now, it’s likely that will get fixed in the future and everything will get stripped. In general the “default” namespace is indicated by c__, so I expect the correct way to do this — if you’re manually building the url — is to prefix each of you’re parameters with c__ and they won’t get stripped.

That said, in general you’d want to try and let Salesforce handle figuring out the URL structure for you, so if they change the URL structure or behavior in the future you’re component continues to work. In comparison in visualforce the “more” official way to nagivate to an account would be using the URLFOR method, i.e. <apex:outputLink value="{!URLFOR($Action.Account.View, account.id)}"/> as opposed to building the link yourself <apex:outputLink value="\{!account.Id}"/>.

I’m not much of an expert in lighting, but based on little digging I think you want to use lighting:navigation to accomplish this and pass through the attributes in PageReference.state as outlined in this answer

This can now be accomplished via lightning:navigation documented
here.

Summary

The target/ to component must implement lightning:isUrlAddressable
interface and the source/ from component needs to include
lightning:navigation, generate URL for a given pageReference (in
this case to a custom component) and finally call the navigate
method with that pageReference.

Here is a sample:

Target/ To Component

Component – myTarget.cmp

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId,lightning:isUrlAddressable">
    <lightning:card iconName="standard:settings" title="Navigation Example">
        <lightning:formattedText class="slds-p-left_small" value="This is your target component."/>
    </lightning:card>
</aura:component>

Source/ From Component

Component

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">
    <lightning:navigation aura:id="navService"/>
    <lightning:button label="Navigate to Target Component" onclick="{!c.navigate}" />
</aura:component>

Controller JS

({
    navigate : function(component, event, helper) {
        var navService = component.find("navService");
        var pageReference = {
            "type": "standard__component",
            "attributes": {
                "componentName": "c__myTarget"
            }, 
            "state": {}
        };
        navService.navigate(pageReference);
    }
})

Attribution
Source : Link , Question Author : Jake Hebert , Answer Author : Ralph Callaway

Leave a Comment