+ Start a Discussion
vickySFDCvickySFDC 

Hi All,

This two VF tags I am really confusing

Can anyone give examples <apex:actionsupport> and <apex:actionfunction> tags and give some examples?

 

 

Thanks,

 

Vicky

Best Answer chosen by Admin (Salesforce Developers) 
asish1989asish1989

HI

A component that provides support for invoking controller action methods directly from JavaScript code using an AJAX request. An <apex:actionFunction> component must be a child of an<apex:form> component.

 

Used when we need to perform similar action on varioud events. Een though you can use it in place of actionSupport as well where only event is related to only one control.

Example

<!-- Page: -->
	<apex:page controller="exampleCon">
	<apex:form>
		<!-- Define the JavaScript function sayHello-->
		<apex:actionFunction name="sayHello" action="{!sayHello}" rerender="out"
		status="myStatus"/>
	</apex:form>
	
	<apex:outputPanel id="out">
		<apex:outputText value="Hello "/>
		<apex:actionStatus startText="requesting..." id="myStatus">
		<apex:facet name="stop">{!username}</apex:facet>
		</apex:actionStatus>
	</apex:outputPanel>
	
	<!-- Call the sayHello JavaScript function using a script element-->
	<script>window.setTimeout(sayHello,2000)</script>
	<p><apex:outputText value="Clicked? {!state}" id="showstate" /></p>
	<!-- Add the onclick event listener to a panel. When clicked, the panel triggers
	the methodOneInJavascript actionFunction with a param -->
	<apex:outputPanel onclick="methodOneInJavascript('Yes!')" styleClass="btn">
		Click Me
	</apex:outputPanel>
	
	<apex:form>
		<apex:actionFunction action="{!methodOne}" name="methodOneInJavascript"
		rerender="showstate">
			<apex:param name="firstParam" assignTo="{!state}" value="" />
		</apex:actionFunction>
	</apex:form>
</apex:page>

/*** Controller ***/
public class exampleCon {
	String uname;
	public String getUsername() {
		return uname;
	}
	public PageReference sayHello() {
		uname = UserInfo.getName();
		return null;
	}
	public void setState(String n) {
		state = n;
	}
	public String getState() {
		return state;
	}
	public PageReference methodOne() {
		return null;
	}
	private String state = 'no';
}

 

.ActionSupport : A component that adds AJAX support to another component, allowing the component to be refreshed asynchronously by theserver when a particular event occurs, such as a button click or mouseover.

 

Used when we want to perform an action on a perticular eventof any control like onchange of any text box or picklist.

 

Example

<apex:page controller="exampleCon">
	<apex:form>
		<apex:outputpanel id="counter">
			<apex:outputText value="Click Me!: {!count}"/>
				<apex:actionSupport event="onclick"
				action="{!incrementCounter}"
			rerender="counter" status="counterStatus"/>
		</apex:outputpanel>
		
		<apex:actionStatus id="counterStatus"
			startText=" (incrementing...)"
			stopText=" (done)"/>
	</apex:form>
</apex:page>


/*** Controller: ***/
public class exampleCon {
	Integer count = 0;
	public PageReference incrementCounter() {
		count++;
		return null;
	}
	public Integer getCount() {
		return count;
	}
}

 If this post answers your questions please mark it as solved and hit kudos button if it helps you

 

Thanks

 

TbomTbom 

Silly question here but:  Does the unique MyDomain qualify for both production and sandbox instances? I would think so, but just want to double check out there.

 

So I could:

Register "crazydomain" in the sandbox and have:

https://crazydomain--crazydev.cs3.my.salesforce.com

 

And register "crazydomain" in Production and have:

https://crazydomain.my.salesforce.com 

 

(of course, I'd have to reserve/register in both places)

Best Answer chosen by Admin (Salesforce Developers) 
TbomTbom

CORRECTION -- THIS IS NOT FINE!

 

SFDC just confirmed my hunch today at Dreamforce '12.

 

You can NOT specify the MyDomain you want to use in Production in Sandbox first!

You MUST specify/reserve in Production first!!  Otherwise you'll lose it and you sandbox will be stuck with something like:

google.devbox-cs1.salesforce.com

and your beloved Production will have to be something lame like:

google1.my.salesforce.com

 

 

 

Trainee DevTrainee Dev 
I'd like to describe this case in detail: First , we have created an custom sObject which OWD is Private Second, we have an approval process on this sObject and user created an record and submit for approval Third, his manager reassigned user's request to another person who has no right to view user's record because OWD is private and also has no role hierarchy with this user My question is : Can we add custom logic when manager reassign this approval to another person? So that we can apex sharing this record to person.

Appreciate for any help
Best Answer chosen by Trainee Dev
Deepali KulshresthaDeepali Kulshrestha
Hi Trainee,
Greetings to you!

I have read your problem - "Can we add custom logic when manager reassign this approval to another person?"
- No, you can not add custom logic when manager reassigns this approval to another person.
- I am referring a link below, on this page press Ctrl+f and search ("Delegate approvers cannot reassign approval request")
Please check this link it will solve all your queries related to the reassign approval process
https://www.salesforcetutorial.com/approval-process-example-in-salesforce/

I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks and Regards,
Deepali Kulshrestha
Siva NalamSiva Nalam 
When using lightning datatable and displaying a date field, its showing a day less than the value in the backend object.

Controller:
component.set('v.Columns',[
                {label:'Transport. mode', fieldName:'Mode_of_Transportation__c', type:'text', editable: false,initialWidth:180},
                {label:'Ground Company', fieldName:'Ground_Transportation_Company__c', type:'text', editable: false,initialWidth:210},
                {label:'Inv./Chg. date', fieldName:'Charge_Invoice_Date__c', initialWidth:150, type:'date', editable: false , typeAttributes:{month:'2-digit',day:'2-digit',year:'numeric'}}
            ]

Datatable:

            <lightning:datatable aura:id="OppExpGTDataTable"
                                 data="{! v.Opp_Expenses_GTXYZ }" 
                                 columns="{! v.Columns }" 
                                 keyField="Id"
                                 onsave ="{!c.onSave}"
                                 hideCheckboxColumn="true"
                                 onrowaction="{! c.handleRowAction }"/>

Using a custom pop up, we are creating records into database capturing date values. Its getting stored in database properly, when displaying in UI, its showing a day less. In out of the box fields, its showing correctly again. How to format the field in lightning datatable/controller? Appreciate your help..
Best Answer chosen by Siva Nalam
Siva NalamSiva Nalam
I found a solution:

If we use type:'date-local' instead of type:'date', its showing correct date. For the benefit of others, here is the link that helped:

https://salesforce.stackexchange.com/questions/221698/help-with-working-with-lightningdatatable/244352#244352

 
Travis CanalesTravis Canales 
Hello All,

I am very new to Lightning development and salesforce in general.

I am trying to make a simple component that consists of tabs with a graph in each one. I have directly copied and pasted the example of a simple tabset from (https://developer.salesforce.com/docs/component-library/bundle/lightning:tabset/example

My issue is that the styling looks like it is entirely missing. Below is a picture of the result: 
User-added image

I have noticed that I am getting an error that may or may not be related to this but I have been unable to find anything about it other than to modify our CSP which doesn't sound right to me. paste of the  error below: 

Refused to run the JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-[removed as im not sure if this is sensitive]' chrome-extension: 'unsafe-inline' 'unsafe-eval' https://sfdc.azureedge.net *.cs19.visual.force.com https://ssl.gstatic.com/accessibility/". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

This error is repeated each time I click on an item in the tabset.

Has anyone had this issue or know what is possibly causing it? Any help would be greatly appreciated.

Thanks,
Travis
Best Answer chosen by Travis Canales
Khan AnasKhan Anas (Salesforce Developers) 
Hi Travis,

Greetings to you!

You need to extend force:slds in application. The Salesforce Lightning Design System provides a look and feel that’s consistent with Lightning Experience. Your application automatically gets Lightning Design System styles and design tokens if it extends force:slds. 

To extend force:slds:
<aura:application extends="force:slds">
    <c:Your_Component_Name />
</aura:application>

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
Best Answer chosen by prachi arya
Khan AnasKhan Anas (Salesforce Developers) 
Hi Prachi,

Greetings to you!

You will have to build a custom lookup field to achieve this. First, create a reusable lookup lightning component. Then, use this component in another component to display related contacts.

Below is the sample code which I have tested in my org and it is working fine. Kindly modify the code as per your requirement.

1. Reusable Custom Lookup: (Source: http://sfdcmonkey.com/2017/07/17/re-usable-custom-lookup/)

Apex: LookupReusableController.apxc
public class LookupReusableController {
    
    @AuraEnabled
    public static List < sObject > fetchLookUpValues(String searchKeyWord, String ObjectName) {
        system.debug('ObjectName-->' + ObjectName);
        String searchKey = searchKeyWord + '%';
        
        List < sObject > returnList = new List < sObject > ();
        
        // Create a Dynamic SOQL Query For Fetch Record List with LIMIT 5   
        String sQuery =  'select id, Name from ' +ObjectName + ' where Name LIKE: searchKey order by createdDate DESC limit 5';
        List < sObject > lstOfRecords = Database.query(sQuery);
        
        for (sObject obj: lstOfRecords) {
            returnList.add(obj);
        }
        return returnList;
    }
}

Event: LookupReusable_Event.evt
<aura:event type="COMPONENT" description="by this event we are pass the selected sObject(lookup list record) in the parent component">
    <aura:attribute name="recordByEvent" type="sObject"/>
</aura:event>

Child Component: LookupReusable_Child.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global">
    <aura:attribute name="oRecord" type="sObject" />
    <aura:attribute name="IconName" type="string"/> 
    
    <!--Register the component level event-->
    <aura:registerEvent name="oSelectedRecordEvent" type="c:LookupReusable_Event"/>
    
    <li role="presentation" class="slds-listbox__item" onclick="{!c.selectRecord}">
        <span id="listbox-option-unique-id-01" class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option">
            <span class="slds-media__figure">
                <span class="slds-icon_container" title="Description of icon when needed">
                    <lightning:icon iconName="{!v.IconName}" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/>
                    <span class="slds-assistive-text">Description of icon</span>
                </span>
            </span>    
            <span class="slds-media__body">  
                <span class="slds-listbox__option-text slds-listbox__option-text_entity">{!v.oRecord.Name}</span>
            </span>
        </span>
    </li>
</aura:component>

Child Controller: LookupReusable_ChildController.js
({
    selectRecord : function(component, event, helper){      
        // get the selected record from list  
        var getSelectRecord = component.get("v.oRecord");
        // call the event   
        var compEvent = component.getEvent("oSelectedRecordEvent");
        // set the Selected sObject Record to the event attribute.  
        compEvent.setParams({"recordByEvent" : getSelectRecord });  
        // fire the event  
        compEvent.fire();
    },
})

Parent Component: LookupReusable_Parent.cmp
<aura:component controller="LookupReusableController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global">
    <!--declare attributes--> 
    <aura:attribute name="selectedRecord" type="sObject" default="{}" description="Use,for store SELECTED sObject Record"/>
    <aura:attribute name="listOfSearchRecords" type="List" description="Use,for store the list of search records which returns from apex class"/>
    <aura:attribute name="SearchKeyWord" type="string"/>
    <aura:attribute name="objectAPIName" type="string" default=""/>
    <aura:attribute name="IconName" type="string" default=""/>
    <aura:attribute name="label" type="string" default=""/>
    <aura:attribute name="Message" type="String" default=""/>
    
    <!--declare events hendlers-->  
    <aura:handler name="oSelectedRecordEvent" event="c:LookupReusable_Event" action="{!c.handleComponentEvent}"/>
    
    
    <!-- https://www.lightningdesignsystem.com/components/lookups/ --> 
    
    <div onmouseleave="{!c.onblur}" aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single">
        <label class="slds-form-element__label" for="lookup-348">{!v.label}</label>
        <!--This part is for display search bar for lookup-->  
        <div class="slds-form-element__control">
            
            <div class="slds-input-has-icon slds-input-has-icon--right">
                <!-- This markup is for when an record is selected -->
                <div aura:id="lookup-pill" class="slds-pill-container slds-hide">
                    <lightning:pill class="pillSize" label="{!v.selectedRecord.Name}" name="{!v.selectedRecord.Name}" onremove="{! c.clear }">
                        <aura:set attribute="media">
                            <lightning:icon iconName="{!v.IconName}" size="x-small" alternativeText="{!v.IconName}"/>
                        </aura:set>
                    </lightning:pill>
                </div>
                <div aura:id="lookupField" class="slds-show">
                    <lightning:icon class="slds-input__icon slds-show" iconName="utility:search" size="x-small" alternativeText="search"/>
                    <span class="slds-icon_container  slds-combobox__input-entity-icon" title="record">
                        <lightning:icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" iconName="{!v.IconName}" size="x-small" alternativeText="icon"/>
                        <span class="slds-assistive-text"></span>
                    </span>
                    <ui:inputText click="{!c.onfocus}" updateOn="keyup" keyup="{!c.keyPressController}" class="slds-lookup__search-input slds-input leftPaddingClass" value="{!v.SearchKeyWord}" placeholder="search.."/>
                </div>   
            </div>
        </div>
        <!--This part is for Display typehead lookup result List-->  
        <ul style="min-height:40px;margin-top:0px !important" class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid slds-lookup__menu slds" role="listbox">
            <lightning:spinner class="slds-hide" variant="brand" size="small" aura:id="mySpinner"/>
            <center> {!v.Message}</center>
            <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec">
                <c:LookupReusable_Child oRecord="{!singleRec}" IconName="{!v.IconName}"/>
            </aura:iteration>
        </ul>
    </div>
</aura:component>

Parent Controller: LookupReusable_ParentController.js
({
    onfocus : function(component,event,helper){
        $A.util.addClass(component.find("mySpinner"), "slds-show");
        var forOpen = component.find("searchRes");
        $A.util.addClass(forOpen, 'slds-is-open');
        $A.util.removeClass(forOpen, 'slds-is-close');
        // Get Default 5 Records order by createdDate DESC  
        var getInputkeyWord = '';
        helper.searchHelper(component,event,getInputkeyWord);
    },
    onblur : function(component,event,helper){       
        component.set("v.listOfSearchRecords", null );
        var forclose = component.find("searchRes");
        $A.util.addClass(forclose, 'slds-is-close');
        $A.util.removeClass(forclose, 'slds-is-open');
    },
    keyPressController : function(component, event, helper) {
        // get the search Input keyword   
        var getInputkeyWord = component.get("v.SearchKeyWord");
        // check if getInputKeyWord size id more then 0 then open the lookup result List and 
        // call the helper 
        // else close the lookup result List part.   
        if( getInputkeyWord.length > 0 ){
            var forOpen = component.find("searchRes");
            $A.util.addClass(forOpen, 'slds-is-open');
            $A.util.removeClass(forOpen, 'slds-is-close');
            helper.searchHelper(component,event,getInputkeyWord);
        }
        else{  
            component.set("v.listOfSearchRecords", null ); 
            var forclose = component.find("searchRes");
            $A.util.addClass(forclose, 'slds-is-close');
            $A.util.removeClass(forclose, 'slds-is-open');
        }
    },
    
    // function for clear the Record Selaction 
    clear :function(component,event,heplper){
        var pillTarget = component.find("lookup-pill");
        var lookUpTarget = component.find("lookupField"); 
        
        $A.util.addClass(pillTarget, 'slds-hide');
        $A.util.removeClass(pillTarget, 'slds-show');
        
        $A.util.addClass(lookUpTarget, 'slds-show');
        $A.util.removeClass(lookUpTarget, 'slds-hide');
        
        component.set("v.SearchKeyWord",null);
        component.set("v.listOfSearchRecords", null );
        component.set("v.selectedRecord", {} );   
    },
    
    // This function call when the end User Select any record from the result list.   
    handleComponentEvent : function(component, event, helper) {
        // get the selected Account record from the COMPONETN event 	 
        var selectedAccountGetFromEvent = event.getParam("recordByEvent");
        component.set("v.selectedRecord" , selectedAccountGetFromEvent); 
        
        var forclose = component.find("lookup-pill");
        $A.util.addClass(forclose, 'slds-show');
        $A.util.removeClass(forclose, 'slds-hide');
        
        var forclose = component.find("searchRes");
        $A.util.addClass(forclose, 'slds-is-close');
        $A.util.removeClass(forclose, 'slds-is-open');
        
        var lookUpTarget = component.find("lookupField");
        $A.util.addClass(lookUpTarget, 'slds-hide');
        $A.util.removeClass(lookUpTarget, 'slds-show');  
        
    },
})

Parent Helper: LookupReusable_ParentHelper.js
({
    searchHelper : function(component,event,getInputkeyWord) {
        // call the apex class method 
        var action = component.get("c.fetchLookUpValues");
        // set param to method  
        action.setParams({
            'searchKeyWord': getInputkeyWord,
            'ObjectName' : component.get("v.objectAPIName")
        });
        // set a callBack    
        action.setCallback(this, function(response) {
            $A.util.removeClass(component.find("mySpinner"), "slds-show");
            var state = response.getState();
            if (state === "SUCCESS") {
                var storeResponse = response.getReturnValue();
                // if storeResponse size is equal 0 ,display No Result Found... message on screen.                }
                if (storeResponse.length == 0) {
                    component.set("v.Message", 'No Result Found...');
                } else {
                    component.set("v.Message", '');
                }
                // set searchResult list with return value from server.
                component.set("v.listOfSearchRecords", storeResponse);
            }
            
        });
        // enqueue the Action  
        $A.enqueueAction(action);
        
    },
})

Parent CSS: LookupReusable_Parent.css
.THIS .leftPaddingClass {
    padding-left: 2rem;
}

.THIS .pillSize{
    width:100%;
}

Application: LookupReusable.app
<aura:application extends="force:slds">
    <!-- Create attribute to store lookup value as a sObject--> 
    <aura:attribute name="selectedLookUpRecord" type="sObject" default="{}"/>
    
    <c:LookupReusable_Parent objectAPIName="account" IconName="standard:account" selectedRecord="{!v.selectedLookUpRecord}" label="Account Name"/>
    <!-- here c: is org. namespace prefix-->
</aura:application>

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Now, you have to create another lightning component to display related contacts using reusable custom lookup component.

2. Related Contacts: (Source: Developed by me :P)

Apex:  LookupRelatedContactC .apxc
public class LookupRelatedContactC {
    
    @AuraEnabled
    public static List<Contact> getCon(List<String> accId) {
        return [SELECT Id, Name, Phone FROM Contact WHERE AccountId=:accId];
    }
}

Component: LookupRelatedContact.cmp
<aura:component controller="LookupRelatedContactC"
                implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    
    <aura:attribute name="selectedLookUpRecord" type="sObject" default="{}"/>
    <aura:attribute name="data" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    
    <aura:handler name="change" value="{!v.selectedLookUpRecord}" action="{!c.selectedLookupChanged}"/> 
    <c:LookupReusable_Parent objectAPIName="account" IconName="standard:account" 
                             selectedRecord="{!v.selectedLookUpRecord}" 
                             label="Accounts"/>
    
    <br/><br/>
    
    <lightning:datatable columns="{! v.columns }"
                         data="{! v.data }"
                         keyField="id"
                         hideCheckboxColumn="true"/>
</aura:component>

Controller: LookupRelatedContactController.js
({ 
    selectedLookupChanged:function(component, event, helper) { 
        
        component.set('v.columns', [
            {label: 'Contact Name', fieldName: 'Name', editable: true, type: 'text'},
            {label: 'Phone', fieldName: 'Phone', type: 'phone'}
        ]);
        
        var aId = component.get("v.selectedLookUpRecord").Id;
        
        var action=component.get('c.getCon');
        action.setParams({accId : aId});
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var rows1 = response.getReturnValue();
                console.log('rows1 ->> ' + rows1);
                component.set("v.data", rows1);
            }
        });
        $A.enqueueAction(action);
    } 
})

Application: App_LookupRelatedContact.app
<aura:application extends="force:slds">
    <c:LookupRelatedContact/>
</aura:application>

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
Jolene C WhiteJolene C White 
The standard value set for Contract.Status causes an error 'Field:null is not a picklist'.   I am guessing this because the current structure for the standard value set doesn't contain a value for the StatusCode, which is required for every Contract.Status value.  Has anyone solved this issue?  Is it on the roadmap to be addressed?  Can we do anything other than put it into the .forceignore?
 
Here is a similar question: 
https://success.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000HTp1SAG&fId=0D53A00003NmQ4cSAF
Best Answer chosen by Jolene C White
Jolene C WhiteJolene C White
We did try adding the statusCategory tag, but that didn't work.  We have a standard value set, but I believe this is a known issue that Salesforce has never fixed.    I've posted this in Ideas -- please vote!  https://success.salesforce.com/ideaView?id=0873A000000TzsWQAS
PronowPronow 

Hello there,

 

In my project, on an object I have two fields. One is an auto-update and other is a formula field. Auto-update field contains 'Current Date' value ( 'TODAY()' ). Formula field is number type, calculating difference in days between a custom DATE field and above auto-update DATE field.

 

I am trying to trigger, a workflow rule that will fire when value of formula field would be 30 or 60.

 

Please help me out as the workflow is not getting triggered when the above formula evaluates to true.

 

Thank you in advance.

Best Answer chosen by Admin (Salesforce Developers) 
PronowPronow

Thank you for your response.

 

However, I guess you did not get the actual problem that I faced. The workflow is supposed to fire when the auto-update field i.e. Current date will change. The other field is formula field calculating No. of days between two dates. One is Cutom date field and other is Current date.

 

Even if I try to fire a workflow to update either Current date or No. of days, you need to update that particular record.

 

So, as a conclusion I found a solution to write a Schedular that will fire everyday, and it will calculate no. of days and update it. This will cause all dependent workflows to fire.

 

I implemented this solution in my project, and its working fine and uninterrupted now.

 

Thank you for your knowledge sharing.

Basil DobekBasil Dobek 
Hi, I'm trying to create a new empty project using the Salesforce CLI and I receive the message "ERROR running force:project:create  Cannot read property 'create' of undefined".    Does anyone know what might be causing this or how to further troubleshoot it? 

The command I'm entering in the terminal is "sfdx force:project:create --projectname VSCodeQuickStart".   I've tried "sfdx force:project:create --projectname VSCodeQuickStart --manifest" as well.


Thank you


 
Best Answer chosen by Basil Dobek
Khan AnasKhan Anas (Salesforce Developers) 
Hi Basil,

Greetings to you!

Please make sure you are using the latest version of salesforcedx. Try to update the CLI
sfdx update

If the problem still persists, uninstall the salesforcedx and reinstall it.

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
Michele Losch 4Michele Losch 4 
I'm unable to complete step 2 of the Apex Specialist Superbadge. Below is the code
 
public with sharing class WarehouseCalloutService {

    private static final String WAREHOUSE_URL = 'https://th-superbadge-apex.herokuapp.com/equipment';
    
    // complete this method to make the callout (using @future) to the
    // REST endpoint and update equipment on hand.
    @future(callout=true)
    public static void runWarehouseEquipmentSync(){
    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setEndpoint(WAREHOUSE_URL);
    request.setMethod('GET');
    HttpResponse response = http.send(request);
    
        if(response.getStatusCode()== 200){
            
            List<Object> results = (List<Object>) JSON.deserializeUntyped(response.getBody());

            List<Product2> LstProduct = new List<Product2>();
            for(Object o : results)
            { 
                Map<String, Object> mapobj = (Map<String, Object>)o;
                Product2 product = new Product2();

                Integer maintenanceperiod = (Integer)mapobj.get('maintenanceperiod');               
                Integer Lifespan = (Integer)mapobj.get('lifespan');
                Integer Cost = (Integer)mapobj.get('cost');
                Boolean replacement = (Boolean)mapobj.get('replacement');
                Integer quantity = ((Integer)mapobj.get('qIntegerntity'));
                product.Name  = (String)mapobj.get('name'); 
                product.Maintenance_Cycle__c = Integer.valueof(maintenanceperiod);
                product.Cost__c = Cost;
                product.Current_Inventory__c = quantity;
                product.Lifespan_Months__c = Lifespan; 
                product.Replacement_Part__c = replacement;
                product.Warehouse_SKU__c = (String) mapobj.get('sku');
                product.ProductCode = (String)mapobj.get('_id');       
                LstProduct.add(product);
            }
            System.debug(LstProduct);
            upsert LstProduct;
            
            
        }
    }

}
This is the error: Challenge Not yet complete... here's what's wrong: 
The runWarehouseEquipmentSync method does not appear to have run successfully. Could not find a successfully completed @future job for this method. Make sure that you run this method at least one before attempting this challenge. Since this method is annotated with the @future method, you may want to wait for a few seconds to ensure that it has processed successfully.

When I run the test the the code coverage is 0%. Any suggests to pass this challenge? Thank you!



 
Best Answer chosen by Michele Losch 4
Ashish KeshariAshish Keshari
Hi Michele, 
I would say - did you tried running the method from Debug - Anonymous block/window to make sure that the method does not have any issues or the logs would help. I also notice this line of code could be an issue as we do not have any key such as "qIntegerntity":
Integer quantity = ((Integer)mapobj.get('qIntegerntity'));
Here is my piece of code - WarehouseCalloutService
public with sharing class WarehouseCalloutService {

    private static final String WAREHOUSE_URL = 'https://th-superbadge-apex.herokuapp.com/equipment';
    
    // complete this method to make the callout (using @future) to the
    // REST endpoint and update equipment on hand.
    @future(callout=true)
    public static void runWarehouseEquipmentSync(){
        Http http = new Http();
		HttpRequest request = new HttpRequest();
		request.setEndpoint(WAREHOUSE_URL);
		request.setMethod('GET');
		HttpResponse response = http.send(request);
		// If the request is successful, parse the JSON response.
		if (response.getStatusCode() == 200) {
    		// Deserialize the JSON string into collections of primitive data types.
    		List<Object> equipments = (List<Object>) JSON.deserializeUntyped(response.getBody());
            List<Product2> products = new List<Product2>();
            for(Object o :  equipments){
                Map<String, Object> mapProduct = (Map<String, Object>)o;
                Product2 product = new Product2();
                product.Name = (String)mapProduct.get('name');
                product.Cost__c = (Integer)mapProduct.get('cost');
                product.Current_Inventory__c = (Integer)mapProduct.get('quantity');
                product.Maintenance_Cycle__c = (Integer)mapProduct.get('maintenanceperiod');
                product.Replacement_Part__c = (Boolean)mapProduct.get('replacement');
                product.Lifespan_Months__c = (Integer)mapProduct.get('lifespan');
                product.Warehouse_SKU__c = (String)mapProduct.get('sku');
                product.ProductCode = (String)mapProduct.get('_id');
                products.add(product);
            }
            if(products.size() > 0){
                System.debug(products);
                upsert products;
            }
		}
    }

}