• JustinShankle
  • NEWBIE
  • 10 Points
  • Member since 2016
  • Developer
  • Coastal Cloud

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 2
    Replies
I had so much trouble with this one section that I feel like I have to post this to help out those who are struggling as much as me. Three hours for a simple controller... The problem is the way trailhead tests the challenge is hard for them and they have very strict criteria that is not implicit in the challenge directions.

camingList.cmp
<aura:component >
    
	<aura:attribute name="newItem" type="Camping_Item__c"  default="{'sobjectType': 'Camping_Item__c', 'Quantity__c': 0, 'Price__c': 0.00}" required="true"/>
	<aura:attribute name="items" type="Camping_Item__c[]"/>
	<lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="standard:scan_card" alternativeText="My Campign Items"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping Items</h1>
                <h2 class="slds-text-heading--medium">My Camping Items</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
    <!-- / PAGE HEADER -->

    <!-- NEW EXPENSE FORM -->
    <lightning:layout >
        <lightning:layoutItem padding="around-small" size="6">

        <!-- CREATE NEW EXPENSE -->
    <div aria-labelledby="newitemform">

        <!-- BOXED AREA -->
        <fieldset class="slds-box slds-theme--default slds-container--small">

        <legend id="newitemform" class="slds-text-heading--small 
          slds-p-vertical--medium">
          Add Camping Item
        </legend>
  
        <!-- CREATE NEW EXPENSE FORM -->
        <form class="slds-form--stacked">          
            <lightning:input aura:id="itemform" label="Item Name"
                             name="itemname"
                             value="{!v.newitem.Name}"
                             required="true"/> 
            <lightning:input type="itemform" aura:id="itemform" label="Amount"
                             name="itemprice"
                             min="0.1"
                             formatter="currency"
                             step="0.01"
                             value="{!v.newitem.Price__c}"
                             messageWhenRangeUnderflow="Enter an amount that's at least $0.10."/>
            <lightning:input aura:id="itemform" label="Quantity"
                             name="itemquantity"
                             value="{!v.newitem.Quantity__c}"
							 min="1"
							 type="number"
							 required="true"
							 messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
                             />
            <lightning:input type="checkbox" aura:id="itemform" label="Packed?"  
                             name="packed"
							 class="slds-checkbox"
                             checked="{!v.newitem.Packed__c}"/>
            <lightning:button label="Create Camping Item" 
                              class="slds-m-top--medium"
                              variant="brand"
                              onclick="{!c.clickCreateItem}"/>
        </form>
        <!-- / CREATE NEW EXPENSE FORM -->
  
      </fieldset>
      <!-- / BOXED AREA -->

    </div>
    <!-- / CREATE NEW EXPENSE -->

        </lightning:layoutItem>
    </lightning:layout>
    <!-- / NEW EXPENSE FORM -->
	
	<div class="slds-card slds-p-top--medium">
        <header class="slds-card__header">
            <h3 class="slds-text-heading--small">Camping</h3>
        </header>
        
        <section class="slds-card__body">
            <div id="list" class="row">
                <aura:iteration items="{!v.items}" var="cmp">
                    <c:campingListItem item="{!cmp}"/>
                </aura:iteration>
            </div>
        </section>
	</div>
</aura:component>

campingList.Controller
({
		handleAddItem: function(component, event, helper) {
    var addItm = event.getParam("item");
    helper.createItem(component, addItm);

},

    createItem: function(component, newItem) {
    var action = component.get("c.clickCreateItem");
    action.setParams({
        "item": newItem
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            var items = component.get("v.items");
            items.push(response.getReturnValue());
            component.set("v.items", items);
        }
    });
    $A.enqueueAction(action);
},
    clickCreateItem: function(component, event, helper) {
		
        var validItem = component.find('itemform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        
        
        // ... hint: more error checking here ...

        // If we pass error checking, do some real work
        if(validItem){
            // Create the new expense
            var newItem = component.get("v.newItem");
            console.log("Create Camping Item: " + JSON.stringify(newCamping));
            handleAddItem(component, newItem);
        }
		component.set("v.newItem",{'sobjectType':'Camping_Item__c',
                'Name': '',
                'Quantity__c': 0,
                'Price__c': 0,
                'Packed__c': false});
    }
})
camping.cmp
<aura:component implements="flexipage:availableForRecordHome">
	<br/><br/><br/>
    <c:campingHeader />
    <c:campingList />
</aura:component>

campingHeader.cmp
<aura:component >
	<lightning:layout class="slds-page-header">
		<lightning:layoutItem >
			<lightning:icon iconName="action:goal"/>
		</lightning:layoutItem>

		<div class="slds-page-header">
			<h1 class="slds-text-heading--label"> Camping List </h1>
		</div>
	</lightning:layout>
</aura:component>

campingListItem.cmp
 
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>

Any other controllers or helper classes are not needed. That is the trick here. Using helper classes when not specified fails the challenge. I hope you will read through and understand this code as I have to realize why it is this way and not simply copypasta.

Enjoy!
 
I had so much trouble with this one section that I feel like I have to post this to help out those who are struggling as much as me. Three hours for a simple controller... The problem is the way trailhead tests the challenge is hard for them and they have very strict criteria that is not implicit in the challenge directions.

camingList.cmp
<aura:component >
    
	<aura:attribute name="newItem" type="Camping_Item__c"  default="{'sobjectType': 'Camping_Item__c', 'Quantity__c': 0, 'Price__c': 0.00}" required="true"/>
	<aura:attribute name="items" type="Camping_Item__c[]"/>
	<lightning:layout class="slds-page-header slds-page-header--object-home">
        <lightning:layoutItem >
            <lightning:icon iconName="standard:scan_card" alternativeText="My Campign Items"/>
        </lightning:layoutItem>
        <lightning:layoutItem padding="horizontal-small">
            <div class="page-section page-header">
                <h1 class="slds-text-heading--label">Camping Items</h1>
                <h2 class="slds-text-heading--medium">My Camping Items</h2>
            </div>
        </lightning:layoutItem>
    </lightning:layout>
    <!-- / PAGE HEADER -->

    <!-- NEW EXPENSE FORM -->
    <lightning:layout >
        <lightning:layoutItem padding="around-small" size="6">

        <!-- CREATE NEW EXPENSE -->
    <div aria-labelledby="newitemform">

        <!-- BOXED AREA -->
        <fieldset class="slds-box slds-theme--default slds-container--small">

        <legend id="newitemform" class="slds-text-heading--small 
          slds-p-vertical--medium">
          Add Camping Item
        </legend>
  
        <!-- CREATE NEW EXPENSE FORM -->
        <form class="slds-form--stacked">          
            <lightning:input aura:id="itemform" label="Item Name"
                             name="itemname"
                             value="{!v.newitem.Name}"
                             required="true"/> 
            <lightning:input type="itemform" aura:id="itemform" label="Amount"
                             name="itemprice"
                             min="0.1"
                             formatter="currency"
                             step="0.01"
                             value="{!v.newitem.Price__c}"
                             messageWhenRangeUnderflow="Enter an amount that's at least $0.10."/>
            <lightning:input aura:id="itemform" label="Quantity"
                             name="itemquantity"
                             value="{!v.newitem.Quantity__c}"
							 min="1"
							 type="number"
							 required="true"
							 messageWhenRangeUnderflow="Enter minimum 1 Quantity"/>
                             />
            <lightning:input type="checkbox" aura:id="itemform" label="Packed?"  
                             name="packed"
							 class="slds-checkbox"
                             checked="{!v.newitem.Packed__c}"/>
            <lightning:button label="Create Camping Item" 
                              class="slds-m-top--medium"
                              variant="brand"
                              onclick="{!c.clickCreateItem}"/>
        </form>
        <!-- / CREATE NEW EXPENSE FORM -->
  
      </fieldset>
      <!-- / BOXED AREA -->

    </div>
    <!-- / CREATE NEW EXPENSE -->

        </lightning:layoutItem>
    </lightning:layout>
    <!-- / NEW EXPENSE FORM -->
	
	<div class="slds-card slds-p-top--medium">
        <header class="slds-card__header">
            <h3 class="slds-text-heading--small">Camping</h3>
        </header>
        
        <section class="slds-card__body">
            <div id="list" class="row">
                <aura:iteration items="{!v.items}" var="cmp">
                    <c:campingListItem item="{!cmp}"/>
                </aura:iteration>
            </div>
        </section>
	</div>
</aura:component>

campingList.Controller
({
		handleAddItem: function(component, event, helper) {
    var addItm = event.getParam("item");
    helper.createItem(component, addItm);

},

    createItem: function(component, newItem) {
    var action = component.get("c.clickCreateItem");
    action.setParams({
        "item": newItem
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            var items = component.get("v.items");
            items.push(response.getReturnValue());
            component.set("v.items", items);
        }
    });
    $A.enqueueAction(action);
},
    clickCreateItem: function(component, event, helper) {
		
        var validItem = component.find('itemform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        
        
        // ... hint: more error checking here ...

        // If we pass error checking, do some real work
        if(validItem){
            // Create the new expense
            var newItem = component.get("v.newItem");
            console.log("Create Camping Item: " + JSON.stringify(newCamping));
            handleAddItem(component, newItem);
        }
		component.set("v.newItem",{'sobjectType':'Camping_Item__c',
                'Name': '',
                'Quantity__c': 0,
                'Price__c': 0,
                'Packed__c': false});
    }
})
camping.cmp
<aura:component implements="flexipage:availableForRecordHome">
	<br/><br/><br/>
    <c:campingHeader />
    <c:campingList />
</aura:component>

campingHeader.cmp
<aura:component >
	<lightning:layout class="slds-page-header">
		<lightning:layoutItem >
			<lightning:icon iconName="action:goal"/>
		</lightning:layoutItem>

		<div class="slds-page-header">
			<h1 class="slds-text-heading--label"> Camping List </h1>
		</div>
	</lightning:layout>
</aura:component>

campingListItem.cmp
 
<aura:component >
    <aura:attribute name="item" type="Camping_Item__c"/>
    
    <p>Name:
        <ui:outputText value="{!v.item.Name}"/>
    </p>
    <p>Price:
        <ui:outputCurrency value="{!v.item.Price__c}"/>
    </p>
    <p>Quantity:
        <ui:outputNumber value="{!v.item.Quantity__c}"/>
    </p>
    <p>Packed:
        <ui:outputCheckbox value="{!v.item.Packed__c}"/>
    </p>
</aura:component>

Any other controllers or helper classes are not needed. That is the trick here. Using helper classes when not specified fails the challenge. I hope you will read through and understand this code as I have to realize why it is this way and not simply copypasta.

Enjoy!
 
hi all,

i have a scenario where in i query an html email template and populate its merge fields in my apex class itself.
however,when i use the sethtmlBody() method,it renders an empty email.
So i have to comment the sethtmlbody() and go with setplaintextbody().

What can be the reason for this?
Also how do i use the setHtmlBody() along with setplainTextBody()?

Below is my code
 
public static void sendingEmail(String cid,String cname,String eventId)
    {
        String plainTxtBody='',startDate='',endDate='',scheduledDate='';
        String hbody='';
        Date sdate;

        //get the email template
        EmailTemplate template=[SELECT HtmlValue,Body FROM EmailTemplate WHERE          DeveloperName='Meeting_Reminder'];
        
        Event eve=[select subject,StartDateTime,EndDateTime,Owner.name,Owner.Email,Owner.Phone 
                    From Event where Id=:eventId];
                    
        hbody=template.HtmlValue;
        
        //setting the merge fields
        hbody=hbody.replace('{!Contact.Name}',cname);
        hbody=hbody.replace('{!Event.Subject}',eve.Subject);
         
        plainTxtBody=template.Body;
        plainTxtBody=plainTxtBody.replace('{!Contact.Name}',cname);
        plainTxtBody=plainTxtBody.replace('{!Event.Subject}',eve.Subject);
        
        //Construct the email message
        Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage();
        mail.setTargetObjectId(cid);
        mail.setSaveAsActivity(false);
        mail.setSubject('Meeting Reminder');
        //mail.setHtmlBody(hbody);
        mail.setPlainTextBody(plainTxtBody);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{mail});     
    }
Also can anyone explain why do we have to set the plaintextbody() even when the email template is of type html?

Any help is appreciated...

Thanks,