• Patrick McClellan
  • SMARTIE
  • 504 Points
  • Member since 2017

  • Chatter
    Feed
  • 1
    Best Answers
  • 2
    Likes Received
  • 1
    Likes Given
  • 14
    Questions
  • 55
    Replies
I have no idea what is hanging up this trailhead unit, I have gone through the unit 3 times now following every single step the unit spells out for you to do. The error I am getting is "Challenge Not yet complete... here's what's wrong: 
The markup for the 'SimilarProperties' component is incorrect."
Here are the files created by following every excrutiating step.

SimilarProperties.cmp
<aura:component controller="MyPropertyController" implements="flexipage:availableForRecordHome">
<aura:attribute name="recordId" type="Id" />
<aura:attribute name="similarProperties" type="Object[]" />
<aura:attribute name="property" type="Property__c" />
<aura:attribute name="remoteRecordId" type="Id" />
<aura:attribute name="showDialog" type="String" default="false" />
<aura:attribute name="searchCriteria" type="String" default="Price" />
<aura:attribute name="priceRange" type="String" default="100000" />

    <aura:handler event="c:recordUpdated" action="{!c.doInit}" />

<force:recordData aura:id="propertyService"
                  recordId="{!v.recordId}"
                  targetRecord="{!v.property}"
                  recordUpdated="{!c.doInit}"
                  layoutType="FULL" />

<lightning:card iconName="custom:custom85" title="{! 'Similar Properties by ' + v.searchCriteria}" class="slds-is-relative">
    <div class="slds-p-left--medium slds-p-right--medium">
        <ul class="slds-list--vertical slds-has-dividers--top-space">
            <aura:iteration items="{!v.similarProperties}" var="item" indexVar="i">
                <li class="slds-list__item">                   
                    <c:SimilarProperty propertyId="{!item.Id}" remoteRecordId="{!v.remoteRecordId}" showDialog="{!v.showDialog}" />
                </li>
            </aura:iteration>
        </ul>
    </div>
    <lightning:spinner aura:id="spinner" variant="brand" size="large"/>
    <c:SimilarPropertyEdit showDialog="{!v.showDialog}" remoteRecordId="{!v.remoteRecordId}" />
</lightning:card>

</aura:component>
SimilarPropertiesController.js
({
    doInit : function(component, event, helper) {
        var spinner = component.find("spinner");
        $A.util.removeClass(spinner, "slds-hide");
        var action = component.get("c.getSimilarProperties");
        action.setParams({
        recordId: component.get("v.recordId"),
        beds: component.get("v.property.fields.Beds__c.value"),
        price: component.get("v.property.fields.Price__c.value"),
        searchCriteria: component.get("v.searchCriteria"),
        priceRange: parseInt(component.get("v.priceRange"), 10)
    });

        action.setCallback(this, function(response){
            var similarProperties = response.getReturnValue();
            component.set("v.similarProperties", similarProperties);
            $A.util.addClass(spinner, "slds-hide");
        });
        $A.enqueueAction(action);
    }
})
SimilarProperties.css
.THIS {
    min-height: 153px;
}

SimilarProperties.design
<design:component label="Similar Properties">
    <sfdc:objects>
        <sfdc:object>Property__c</sfdc:object>
    </sfdc:objects>
    <design:attribute name="searchCriteria" label="Search By" datasource="Bedrooms, Price" default="Price" description="Search for similar houses based on what criteria?" />
    <design:attribute name="priceRange" label="Price Range" default="100000" description="When searching by Price, search using the price plus or minus this amount" />   
</design:component>

SimilarProperties.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <path d="M120,108 C120,114.6 114.6,120 108,120 L12,120 C5.4,120 0,114.6 0,108 L0,12 C0,5.4 5.4,0 12,0 L108,0 C114.6,0 120,5.4 120,12 L120,108 L120,108 Z" id="Shape" fill="#2A739E"/>
        <path fill="#FFF" d="m78 24h-50v-2c0-1.1-0.9-2-2-2h-4c-1.1 0-2 0.9-2 2v56c0 1.1 0.9 2 2 2h4c1.1 0 2-0.9 2-2v-46h50c1.1 0 2-0.9 2-2v-4c0-1.1-0.9-2-2-2z m-4 14h-34c-3.3 0-6 2.7-6 6v22c0 3.3 2.7 6 6 6h34c3.3 0 6-2.7 6-6v-22c0-3.3-2.7-6-6-6z m-5.5 17h-2.5v10c0 0.6-0.4 1-1 1h-4c-0.6 0-1-0.4-1-1v-6c0-0.6-0.4-1-1-1h-4c-0.6 0-1 0.4-1 1v6c0 0.6-0.4 1-1 1h-4c-0.6 0-1-0.4-1-1v-10h-2.5c-0.5 0-0.7-0.6-0.3-0.9l11.2-10.9c0.4-0.3 0.9-0.3 1.3 0l11.2 10.9c0.3 0.3 0.1 0.9-0.4 0.9z"></path>
    </g>
</svg>

SimilarProperty.cmp
<aura:component implements="force:hasRecordId" access="global">
    <aura:attribute name="propertyId" type="Id" />
    <aura:attribute name="targetFields" type="Property__c" />
    <aura:attribute name="showDialog" type="String" />
    <aura:attribute name="remoteRecordId" type="Id" />

    <force:recordData aura:id="propertyRecord"
                      recordId="{!v.propertyId}"
                      targetFields="{!v.targetFields}"
                      fields="Name, Beds__c, Baths__c, Price__c, Status__c, Thumbnail__c"
                      />

    <div class="slds-media">
        <div class="slds-media__figure">
            <img src="{!v.targetFields.Thumbnail__c}" class="slds-avatar--large slds-avatar--circle" alt="{!v.targetFields.Title_c}" />
        </div>
        <div class="slds-media__body">
            <div class="slds-grid">
                <a onclick="{!c.navToRecord}">
                    <h3 class="slds-text-heading--small slds-m-bottom--xx-small">{!v.targetFields.Name}</h3>
                </a>
                <lightning:buttonIcon iconName="utility:edit" class="slds-col--bump-left" variant="bare" alternativeText="Edit Record" onclick="{!c.editRecord}" />
            </div>
            <div aura:id="propertyDetails" class="slds-m-top--small">
                <ul class="slds-grid slds-wrap">
                    <li class="slds-list__item slds-size--1-of-2"><span class="slds-text-color--weak slds-m-right--small">Beds:</span> {!v.targetFields.Beds__c}</li>
                    <li class="slds-list__item slds-size--1-of-2"><span class="slds-text-color--weak slds-m-right--small">Baths:</span> {!v.targetFields.Baths__c}</li>
                    <li class="slds-list__item slds-size--1-of-2"><span class="slds-text-color--weak slds-m-right--small">Price:</span> {!v.targetFields.Price__c}</li>
                    <li class="slds-list__item slds-size--1-of-2"><span class="slds-text-color--weak slds-m-right--small">Status:</span> {!v.targetFields.Status__c}</li>
                </ul>
            </div>
        </div>
    </div>
</aura:component>

SimilarPropertyController.js
({
    navToRecord : function (component, event, helper) {
        var navEvt = $A.get("e.force:navigateToSObject");
        navEvt.setParams({
            "recordId": component.get("v.propertyId")
        });
        navEvt.fire();
    },
    
        editRecord : function(component, event, helper) {
    var recId = component.get("v.propertyId");
    component.set("v.remoteRecordId", recId);
    component.set("v.showDialog", "true");
}
})

SimilarPropertyEdit.cmp
<aura:component>
    <aura:attribute name="showDialog" type="String" default="false" />
    <aura:attribute name="remoteRecordId" type="Id" />
    <aura:attribute name="selectedProperty" type="Property__c" />
    <aura:handler name="change" value="{!v.showDialog}" action="{!c.toggleDialog}" />
    <aura:handler name="change" value="{!v.remoteRecordId}" action="{!c.getRecord}" />

    <force:recordData aura:id="editRecord"
                         targetRecord="{!v.selectedProperty}"
                         fields="Id,Name,Beds__c,Baths__c,Price__c,Status__c"
                         mode="EDIT" />

    <div aura:id="editDialog" role="dialog" tabindex="-1" aria-labelledby="header43" class="slds-modal">
        <div class="slds-modal__container">
            <div class="slds-modal__header">
                <button class="slds-button slds-modal__close " title="Close" onclick="{!c.toggleDialog}">
                    <lightning:icon iconName="utility:close" variant="bare" ></lightning:icon>
                    <span class="slds-assistive-text">Close</span>
                </button>
                <h2 class="slds-text-heading--medium">Edit Record</h2>
            </div>
            <div class="slds-modal__content slds-p-around--medium slds-grid slds-wrap slds-grid--align-spread">
                <lightning:input aura:id="propName" name="propName" label="Property Name" required="true" value="{!v.selectedProperty.fields.Name.value}" class="slds-size--1-of-1 slds-p-horizontal--x-small" />
                <lightning:input aura:id="propBeds" name="propBeds" type="number" label="Beds" value="{!v.selectedProperty.fields.Beds__c.value}" class="slds-size--1-of-2 slds-p-horizontal--x-small" />
                <lightning:input aura:id="propBaths" name="propBaths" type="number" label="Baths" value="{!v.selectedProperty.fields.Baths__c.value}" class="slds-size--1-of-2 slds-p-horizontal--x-small" />
                <lightning:input aura:id="propPrice" name="propPrice" type="number" label="Price" value="{!v.selectedProperty.fields.Price__c.value}" class="slds-size--1-of-2 slds-p-horizontal--x-small" />
                <lightning:input aura:id="propStatus" name="propStatus" label="Status" value="{!v.selectedProperty.fields.Status__c.value}" class="slds-size--1-of-2 slds-p-horizontal--x-small" />
            </div>
            <div class="slds-modal__footer">
                <button class="slds-button slds-button--neutral" onclick="{!c.toggleDialog}">Cancel</button>
                <button class="slds-button slds-button--brand" onclick="{!c.saveRecord}">Save</button>
            </div>
        </div>
    </div>
    <div aura:id="overlay" class="slds-backdrop"></div>
</aura:component>
SimilarPropertyEditController.js
({
    getRecord : function(component) {
        var tempRec = component.find("editRecord");
        tempRec.set("v.recordId", component.get("v.remoteRecordId"));
        tempRec.reloadRecord();
    },
    toggleDialog : function(component, event, helper) {
        helper.showHideModal(component);
    },
    saveRecord : function(component,event,helper) {
        var propBeds = parseInt(component.find('propBeds').get("v.value"), 10);
        var propBaths = parseInt(component.find('propBaths').get("v.value"), 10);
        var propPrice = parseInt(component.find('propPrice').get("v.value"), 10);

        component.set("v.selectedProperty.fields.Beds__c.value", propBeds);
        component.set("v.selectedProperty.fields.Baths__c.value", propBaths);
        component.set("v.selectedProperty.fields.Price__c.value", propPrice);

        var tempRec = component.find("editRecord");
        tempRec.saveRecord($A.getCallback(function(result){
            console.log(result.state);
            if (result.state === "SUCCESS" || result.state === "DRAFT") {
                var event = $A.get("e.c:recordUpdated");
                event.fire();
            } else if (result.state === "ERROR") {
                console.log('Error: ' + JSON.stringify(result.error));
            } else {
                console.log('Unknown problem, state: ' + result.state + ', error: ' + JSON.stringify(result.error));
            }
        }));       
        helper.showHideModal(component);
    }
})
SimilarPropertyEditHelper.js
({
    showHideModal : function(component) {
        var modal = component.find("editDialog");
        $A.util.toggleClass(modal, 'slds-fade-in-open');
        var overlay = component.find("overlay");
        $A.util.toggleClass(overlay, 'slds-backdrop--open');
        component.set("v.showDialog", "false");
    }
})
recordUpdated.evt
<aura:event type="APPLICATION" description="Event template" />
MyPropertyController.apxc
public with sharing class MyPropertyController {
    @AuraEnabled
    public static List<Property__c> getSimilarProperties (Id recordId, String searchCriteria, Decimal beds, Decimal price, Decimal priceRange ) {
         if (searchCriteria == 'Bedrooms') {
             return [
                 SELECT Id, Name, Beds__c, Baths__c, Price__c, Broker__c, Status__c, Thumbnail__c
                 FROM Property__c WHERE Id != :recordId AND Beds__c = :beds
             ];
         } else {
             Decimal range;
             if (priceRange == null) {
                 range = 100000;
             } else {
                 range = priceRange;
             }
             return [
                 SELECT Id, Name, Beds__c, Baths__c, Price__c, Broker__c, Status__c, Thumbnail__c
                 FROM Property__c WHERE Id != :recordId AND Price__c > :price - range AND Price__c < :price + range
             ];
         }
     }
}

PLEASE HELP!
I'm on the second challenge of the Lightning Components Superbadge. I've created my BoatSearchForm.cmp, and the BoatSearchFormController.js. I need to pull the value from the pulldown selector. I have an onChange event that calls the handleChange handler, but then it fails when I try to call event.getParam("value"). It says event.getParam function doesn't exist!

Here's the code:

cmp excerpt:
<select class="slds-select" id="selectType" onchange="{!c.handleChange}" >
         <option value="">All Types</option>
          <aura:iteration items="{!v.BoatTypes}" var="boatType">
                   <option value="{!boatType.Id}">{!boatType.Name}</option>
          </aura:iteration>
 </select>
And the handler from my js controller:
handleChange : function(component, event){
        var selectedValue = event.getParam("value");
        console.log(selectedValue);
    },
I know that handler doesn't actually set anything... I'm still just trying to access the value that is selected in the pulldown of the cmp. Once I get that, I can assign it with a component.set() line.

Any idea why it's not taking the event.getParam()?

 
I'm having trouble validating challenge 2, with regard to Shinje Tashi's user settings.
ERROR: 
Challenge Not yet complete... here's what's wrong: 
Shinje Tashi does not have the user settings he needs.

The instructions say: "This sales data quality specialist supports the entire company and needs to be assigned a role that can see and access all account, contact, and opportunity records for the entire company. Use the Standard User profile."

First off, it seems odd not to handle this through a separate profile, but I'm trying to follow the directions. So...

I created Shinje as an active user, User License: Salesforce, Profile: Standard User. There isn't a role specified for him, and the instructions suggest providing access to all acct, contact and oppty records through a role assignment, so I created a Sales Data Admin role, reporting to the CEO. That role should provide RECORD access. Additionally, for OBJECT access, I created a permission set granting full access (CRED, View All, Modify All) to Acct, Contact, and Oppty objects and assigned it to Shinje. I created a separate permission set granting access to the Language preference field on Acct, named that permission set "Bilingual Pilot" as instructed, and assigned it to Shinje.

I'm not sure what I'm missing...

 
I'm trying to understand how to communicate/ set attributes (variables) in nested components. Here's the situation:
Top level component: enterResult.cmp -- contains an aura:iterate that calls...
Second level component: topicItem.cmp.
I'm running a doInit handler in topicItemController.js, where I want to get an attibute from Top Level enterResult.cmp, add 1, then set an attribute in Second level component topicItem.cmp.

Any help, links to documentation, and/or examples would be appreciated. Thanks!
Is there a way to get Visual Workflows to look like the styling of Lightning Design System? I tried hacking the lightning design markup into Text Output fields, but that didn't work.
In Lightning components, one would typically collect a set of new records and save them all in a single server transaction. I'm working in Visual Workflows now, and I've gathered a whole group of object records, but it appears I have to loop and create the records one at a time. Am I wrong? This seems like a feature that would be quite practical.

Thanks.
I have two objects:
  • PARENT OBJECT: Results__c, which holds basic info about a certification exam result (user, exam name, date, passed). 
  • CHILD OBJECT: Result_topics__c, which holds exam section topic name and the score achieved. Note that there are different number of result_topic__c records associated with each parent Result__c, depending on which exam it is. That's why it's a separate object, rather than fields in the main object.
When the user creates a new (parent) Result__c, a Process detects the new record and launches a flow to solicit input to create the child records.

The Visual Flow accesses all of the topics related to that particular exam, and then loops through input screens asking the user for the score for that section. Each time the user enters a score and presses NEXT, the Result_Topic__c record is created. At the end of the flow, there's a summary screen. The flow works great on its own.

My problem is this: the Visual Workflow has screen elements, so it won't allow me to save it as Type: Autolaunched Flow, which is a requirement to launch it from an action step in Process Builder.

Is it true that Process Builder can't launch any flow that requests user input?

Am I missing something? Any workaround ideas?
I'm creating a Lightning component that uses aura:iterate to dynamically build a form, with a field for each item in a list object. The markup works great, but I don't know how to go back and get the values from the fields later -- to validate the fields and then to save the values.

I would normally use aura:id to component.find() the field, and then get("v.value"). BUT aura:id is undefined because it can't be dynamically assigned with a merge field. Here's how I was trying to assign aura:id in the iteration markup, but that aura:id assignment doesn't work.
<aura:component >
    <aura:attribute name="topic" type="Topic__c"/>
        <div class="slds-tile slds-hint-parent">
            <div class="slds-form-element slds-is-required">
                <div class="slds-form-element__control">
                    <ui:inputNumber aura:id="{!v.topic.Id}" label="{!v.topic.Name}"
                                    class="slds-input"
                                    labelClass="slds-form-element__label"
                                    value = "{!v.topicResult.score__c}" />   
                </div>
            </div> 
        </div>
</aura:component>
I've double checked that {v.topic.Id} is valid (I can assign it to the label with no problem). I've tried using a simple string in a variable, also with no success. It appears aura:id has to be hard-coded.

So, any ideas on another attribute I can use to identify and call each field?
Is there a way to do a component.find() on a different attribute, like label, that can be set dynamically?

I'm using ui:inputNumber based on my use of it in the Lightning Component Trail on Trailhead (the one with Expenses and the Camping List), but I'm seeing an altenative --  lightning:input (Beta). I'm reading the docs on it, thinking maybe I can use the name attribute, but not sure if I can then component.find() it by name.

Any insight or ideas out there? Thanks.
I have a component that creates a form to enter Salesforce Certification Test Results, which provide section level scores. For example:

Test Taker: John Doe
Test Date: 08/02/2017
Exam: Administrator I

Section-Level Scores:
Organization Set-Up (Global UI): 100%
User Setup: 66%
Security and Access: 75%
Standard and Custom Objects: 77%
Sales and Marketing Applications: 75%
Service and Support Applications: 75%
Activity Management and Collaboration: 66%
Data Management: 100%
Analytics - Reports and Dashboards: 100%
Workflow/Process Automation: 80%
Desktop and Mobile Administration: 100%
AppExchange: 100%

When saved, I need to do the following:
  • Save the Exam name, User name, Exam date to a NEW Result__c record. Result__c is my PARENT object in a Master-Detail Relationship.
  • Create x number of child objects in Result_topic__c[], saving Topic Name, Score, and the recordID of the new result__c record. But that parent record is being created in the same operations (one form submission). 
I don't know where to derive the recordID number for the parent record that is being created at the same time. Does recordId get generated during the save operation, or is it generated when you hit the NEW button and open the form (that wouldn't be very efficient, but very useful in this situation.)

Anybody know where to look for an answer?
I'm working hard to understand the range of automation tools. Salesforce makes it really confusing with their lack of consistent naming, and with the inevitable tool updates/replacements while supporting the legacy versions. 

Yes, I have read "Which Automation Tool Do I Use?". It's helpful, but lacks the candid insights I'm hoping to get from your feedback. They tell you what's possible, like invoking an approval process from within a Process Builder process, but they don't explain WHY you might want to do it that way. There are other posts out there comparing various tools, but I'm not clear on the timeline of tool launches and updates, so reading a post from 2015 might have been accurate then, but now...?

Here's what I understand, with questions in italics. I welcome your insights and corrections.

Approval Processes: simple but capable process automation around approvals. An approval process allows specification of the approvers, and specific steps that will occur when approved or rejected -- typically including locking or unlocking the record for edits, and updating fields such as opportunity stage. Approval processes can be triggered through a button click or link, or through a criteria such as a field update to a particular value (such as stage = "submit for approval"). They can also be invoked from Process Builder Flows or Workflow Rules, though it's unclear to me why you'd want to do this instead of using the entry criteria. And if you intend to invoke the approval from a Flow or Workflow, what do you set for the entry criteria that wouldn't fire on its own?

User-added image


Workflow Rules: accessed in Setup as "Workflow Rules", and setup using a form interface very similar to the Approval Processes. From what I can understand, this tool continues to exist because there are lots of legacy workflow rules in use. However, for new rules, they seem to be pushing us toward using Process Builder, with its drag-n-drop visual interface and additional capabilities.  Right?

User-added image

Process Builder: (aka "Lightning Process Builder"), accessible in Setup as "Process Builder", and what you create are called "Processes". Seems to be the automation tool of choice when you don't need user input, but you want things to happen automatically behind the scenes. Replaces Workflow Rules.

This is a very capable tool, able to evaluate multiple criteria and perform multiple actions in specified sequence. You can collect a whole series of criteria/actions within a single process, or you can call invoke a separate process from the one you're creating. I'm not clear why you'd want to gang them all together, other than to control the sequence of the processes. Otherwise, discrete component processes seems easier to create, test, and debug. Any insights here?

User-added image

Visual Workflows, accessible in Setup as "Flows". <rant> If they're replacing Workflow Rules with Process Builder Processes, it's damn annoying that they call THIS tool Visual Workflows and the outputs are "Flows". </rant>

This is the most capable of the automation tools, specifically useful for user interaction. These flows aren't tied to a specific Object, so they can CRED on any object. They are typically triggered by user interaction. Although the record lookup, loops, use of variables, text formatting, etc., are cool features, I'm frustrated by lack of comprehensive training on it. For example, I want to create a dynamic screen interface (number of input fields corresponds to a lookup value) -- can't find any documentation, but it seems like an common need.

User-added image

OK, thanks for making it this far in the post. I welcome your insights.



 
We're instructed to send an email to the finance group -- that's pretty vague. I'm going to create a Finance group, made up of the CFO and subordinates. Am I missing something in the instructions?
Requesting help from Saleforce Trailhead Admin. I'm using a brand new DE org for this superbadge. I've complete the challenge and it works in my org, but the validation has this error:

There was an unexpected error while verifying this challenge. Usually this is due to some pre-existing configuration or code in the challenge Org. We recommend using a new Developer Edition (DE) to check this challenge. If you're using a new DE and seeing this error, please post to the developer forums and reference error id: IHOXZBFU
In the Trailhead module called "Override A Standard Action with a Lightning Component", everything is going OK up till the point where we add SLDS styling to the cmp to make it a modal. They provide the code (see below), but for some reason, it's not displaying as modal for me. (Yes, I've refreshed, multiple times, even relaunching the playground.) Anybody else experiencing this?
<aura:component implements="lightning:actionOverride,flexipage:availableForRecordHome,force:hasRecordId" access="global">
    <aura:attribute name="picklistValues" type="Object" />
    <aura:attribute name="propertyRecord" type="Property__c" />
    <force:recordData aura:id="forceRecord"
                      recordId="{!v.recordId}"
                      targetFields="{!v.propertyRecord}"
                      fields="Id,Name,Beds__c,Baths__c,Price__c,Status__c"
                      mode="EDIT" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <c:PickListValues sObjectName="Property__c" fieldName="Status__c" picklistValues="{!v.picklistValues}" />

    <div aura:id="editDialog" role="dialog" tabindex="-1" aria-labelledby="header43" class="slds-modal slds-fade-in-open">
        <div class="slds-modal__container">
                <div class="slds-modal__header">
                    <h2 class="slds-text-heading--medium">New Record</h2>
            </div>
            <div class="slds-modal__content slds-p-around--medium slds-grid slds-wrap ">
                <lightning:input aura:id="propName" name="propName" label="Property Name" required="true" class="slds-size--1-of-1 slds-p-horizontal_x-small" />
                <lightning:input aura:id="propBeds" name="propBeds" label="Beds" class="slds-size--1-of-2 slds-p-horizontal_x-small" />
                <lightning:input aura:id="propBaths" name="propBaths" label="Baths" class="slds-size--1-of-2 slds-p-horizontal_x-small" />
                <lightning:input aura:id="propPrice" name="propPrice" label="Price" class="slds-size--1-of-2 slds-p-horizontal_x-small" />    
                <lightning:select aura:id="propStatus" name="propStatus" label="Status" class="slds-size--1-of-2 slds-p-horizontal_x-small">
                    <aura:iteration items="{!v.picklistValues}" var="item">
                        <option value="{!item}">{!item}</option>
                    </aura:iteration>
                </lightning:select>
            </div>
            <div class="slds-modal__footer">                
                <lightning:button variant="neutral" label="Cancel" />
                <lightning:button variant="brand" label="Submit" onclick="{!c.saveRecord}" />
            </div>
        </div>
    </div>
    <div aura:id="overlay" class="slds-backdrop slds-backdrop--open"></div>
</aura:component>

 
I'm in the Create Service Analytics with a Wizard module. I follow all the instructions, but it gives me a failure email and the app is not created. The shell of the app appears to be there, but when I click a dashboard, it says resources are not available. Yes, I have refreshed DTC data, so that's not it.

The email log:
Successfully updated resource type [dashboard], label [My Performance Summary]. 
Successfully updated resource type [dashboard], label [Service Account Profile]. 
Successfully updated resource type [dashboard], label [Service Agent Activity]. 
Successfully updated resource type [dashboard], label [Service Agent Performance]. 
Successfully updated resource type [dashboard], label [Service Agent Sidebar By Case History]. 
Successfully updated resource type [dashboard], label [Service Agent Sidebar By Customer]. 
Successfully updated resource type [dashboard], label [Service Agent Sidebar By Similarity]. 
Successfully updated resource type [dashboard], label [Service Analytics Overview]. 
Successfully updated resource type [dashboard], label [Service Backlog]. 
Successfully updated resource type [dashboard], label [Service Channel Review]. 
Successfully updated resource type [dashboard], label [Service Customer Satisfaction]. 
Successfully updated resource type [dashboard], label [Service Open Cases]. 
Successfully updated resource type [dashboard], label [Service Telephony]. 
Generation of resource type [xmd], label [ServiceActivity] failed. EdgemartData null not found for Edgemart 0Fb6A000000kDEnSAM 
Generation of resource type [xmd], label [ServiceCase] failed. EdgemartData null not found for Edgemart 0Fb6A000000kDElSAM 
Generation of resource type [xmd], label [ServiceCaseHistory] failed. EdgemartData null not found for Edgemart 0Fb6A000000kDEoSAM 
Generation of resource type [xmd], label [ServiceOpportunity] failed. EdgemartData null not found for Edgemart 0Fb6A000000kDEmSAM 
Application reset [My First Service App] failed.
I'm stuck trying to access Einstein Platform Account. It says my email is already registered, but I have no way to get in. PEM? HELP please.
I'm creating a Lightning component that uses aura:iterate to dynamically build a form, with a field for each item in a list object. The markup works great, but I don't know how to go back and get the values from the fields later -- to validate the fields and then to save the values.

I would normally use aura:id to component.find() the field, and then get("v.value"). BUT aura:id is undefined because it can't be dynamically assigned with a merge field. Here's how I was trying to assign aura:id in the iteration markup, but that aura:id assignment doesn't work.
<aura:component >
    <aura:attribute name="topic" type="Topic__c"/>
        <div class="slds-tile slds-hint-parent">
            <div class="slds-form-element slds-is-required">
                <div class="slds-form-element__control">
                    <ui:inputNumber aura:id="{!v.topic.Id}" label="{!v.topic.Name}"
                                    class="slds-input"
                                    labelClass="slds-form-element__label"
                                    value = "{!v.topicResult.score__c}" />   
                </div>
            </div> 
        </div>
</aura:component>
I've double checked that {v.topic.Id} is valid (I can assign it to the label with no problem). I've tried using a simple string in a variable, also with no success. It appears aura:id has to be hard-coded.

So, any ideas on another attribute I can use to identify and call each field?
Is there a way to do a component.find() on a different attribute, like label, that can be set dynamically?

I'm using ui:inputNumber based on my use of it in the Lightning Component Trail on Trailhead (the one with Expenses and the Camping List), but I'm seeing an altenative --  lightning:input (Beta). I'm reading the docs on it, thinking maybe I can use the name attribute, but not sure if I can then component.find() it by name.

Any insight or ideas out there? Thanks.
I'm working hard to understand the range of automation tools. Salesforce makes it really confusing with their lack of consistent naming, and with the inevitable tool updates/replacements while supporting the legacy versions. 

Yes, I have read "Which Automation Tool Do I Use?". It's helpful, but lacks the candid insights I'm hoping to get from your feedback. They tell you what's possible, like invoking an approval process from within a Process Builder process, but they don't explain WHY you might want to do it that way. There are other posts out there comparing various tools, but I'm not clear on the timeline of tool launches and updates, so reading a post from 2015 might have been accurate then, but now...?

Here's what I understand, with questions in italics. I welcome your insights and corrections.

Approval Processes: simple but capable process automation around approvals. An approval process allows specification of the approvers, and specific steps that will occur when approved or rejected -- typically including locking or unlocking the record for edits, and updating fields such as opportunity stage. Approval processes can be triggered through a button click or link, or through a criteria such as a field update to a particular value (such as stage = "submit for approval"). They can also be invoked from Process Builder Flows or Workflow Rules, though it's unclear to me why you'd want to do this instead of using the entry criteria. And if you intend to invoke the approval from a Flow or Workflow, what do you set for the entry criteria that wouldn't fire on its own?

User-added image


Workflow Rules: accessed in Setup as "Workflow Rules", and setup using a form interface very similar to the Approval Processes. From what I can understand, this tool continues to exist because there are lots of legacy workflow rules in use. However, for new rules, they seem to be pushing us toward using Process Builder, with its drag-n-drop visual interface and additional capabilities.  Right?

User-added image

Process Builder: (aka "Lightning Process Builder"), accessible in Setup as "Process Builder", and what you create are called "Processes". Seems to be the automation tool of choice when you don't need user input, but you want things to happen automatically behind the scenes. Replaces Workflow Rules.

This is a very capable tool, able to evaluate multiple criteria and perform multiple actions in specified sequence. You can collect a whole series of criteria/actions within a single process, or you can call invoke a separate process from the one you're creating. I'm not clear why you'd want to gang them all together, other than to control the sequence of the processes. Otherwise, discrete component processes seems easier to create, test, and debug. Any insights here?

User-added image

Visual Workflows, accessible in Setup as "Flows". <rant> If they're replacing Workflow Rules with Process Builder Processes, it's damn annoying that they call THIS tool Visual Workflows and the outputs are "Flows". </rant>

This is the most capable of the automation tools, specifically useful for user interaction. These flows aren't tied to a specific Object, so they can CRED on any object. They are typically triggered by user interaction. Although the record lookup, loops, use of variables, text formatting, etc., are cool features, I'm frustrated by lack of comprehensive training on it. For example, I want to create a dynamic screen interface (number of input fields corresponds to a lookup value) -- can't find any documentation, but it seems like an common need.

User-added image

OK, thanks for making it this far in the post. I welcome your insights.



 
I'm on the second challenge of the Lightning Components Superbadge. I've created my BoatSearchForm.cmp, and the BoatSearchFormController.js. I need to pull the value from the pulldown selector. I have an onChange event that calls the handleChange handler, but then it fails when I try to call event.getParam("value"). It says event.getParam function doesn't exist!

Here's the code:

cmp excerpt:
<select class="slds-select" id="selectType" onchange="{!c.handleChange}" >
         <option value="">All Types</option>
          <aura:iteration items="{!v.BoatTypes}" var="boatType">
                   <option value="{!boatType.Id}">{!boatType.Name}</option>
          </aura:iteration>
 </select>
And the handler from my js controller:
handleChange : function(component, event){
        var selectedValue = event.getParam("value");
        console.log(selectedValue);
    },
I know that handler doesn't actually set anything... I'm still just trying to access the value that is selected in the pulldown of the cmp. Once I get that, I can assign it with a component.set() line.

Any idea why it's not taking the event.getParam()?

 

Hi!

I receive this error message : Challenge Not yet complete... here's what's wrong: 
Lincoln Ulrich cannot set up and execute marketing campaigns to his accounts.  

I probed adding permission set, set to marketing user, set to system admin but I have the same issue.

  • October 18, 2017
  • Like
  • 1
I'm having trouble validating challenge 2, with regard to Shinje Tashi's user settings.
ERROR: 
Challenge Not yet complete... here's what's wrong: 
Shinje Tashi does not have the user settings he needs.

The instructions say: "This sales data quality specialist supports the entire company and needs to be assigned a role that can see and access all account, contact, and opportunity records for the entire company. Use the Standard User profile."

First off, it seems odd not to handle this through a separate profile, but I'm trying to follow the directions. So...

I created Shinje as an active user, User License: Salesforce, Profile: Standard User. There isn't a role specified for him, and the instructions suggest providing access to all acct, contact and oppty records through a role assignment, so I created a Sales Data Admin role, reporting to the CEO. That role should provide RECORD access. Additionally, for OBJECT access, I created a permission set granting full access (CRED, View All, Modify All) to Acct, Contact, and Oppty objects and assigned it to Shinje. I created a separate permission set granting access to the Language preference field on Acct, named that permission set "Bilingual Pilot" as instructed, and assigned it to Shinje.

I'm not sure what I'm missing...

 
I have built the reports and dashboards as outlined in the requirements, but I'm getting the following error "Challenge Not yet complete... here's what's wrong: Couldn't find a component with the title 'My Top Accounts'."  
User-added image

However, I have the component on the dashboard as you can see below.
User-added image
What am I missing?
I have created a data set and uploaded it successfully to the einstein API's. But when I try to train I get the error "Trainer process failed to complete" and I dont see any way to get more details about why its faililng.

Here is a sample of the data ive uploaded.
"  Borrower added on 12/22/11 > I need to upgrade my business technologies.<br>","Fully Paid"
"  Borrower added on 12/13/11 > Pay off my credit card, finish my house to refinance,appraised two years ago at $200.000 from an appraiser, <br>","Charged Off"
Here are the calls ive made:
curl -X POST -H "Authorization: Bearer <TOKEN>" -H "Cache-Control: no-cache" -H "Content-Type: multipart/form-data" -F "path=<URL>" -F "type=text-intent"  https://api.einstein.ai/v2/language/datasets/upload -k

{"id":1011898,"name":"loan_prepped.csv; filename*=UTF-8''loan_prepped.csv","createdAt":"2017-09-03T16:44:55.000+0000","updatedAt":"2017-09-03T16:44:55.000+0000","labelSummary":{"labels":[]},"totalExamples":0,"available":false,"statusMsg":"UPLOADING","type":"text-intent","object":"dataset"}

curl -X POST -H "Authorization: Bearer <TOKEN>" -H "Cache-Control: no-cache" -H "Content-Type: multipart/form-data" -F "name=Case Status Model" -F "datasetId=1011898" -F "trainParams={\"trainSplitRatio\":0.7}" https://api.einstein.ai/v2/language/train -k

{"datasetId":1011898,"datasetVersionId":0,"name":"Weather Intent Model","status":"QUEUED","progress":0,"createdAt":"2017-09-03T16:50:43.000+0000","updatedAt":"2017-09-03T16:50:43.000+0000","learningRate":0.0,"epochs":0,"queuePosition":3,"object":"training","modelId":"OPLZANLBXC6ILDY5W5XQVVPUKA","trainParams":{"trainSplitRatio":0.7},"trainStats":null,"modelType":"text-intent"}
And here is the status of the model:
curl -X GET -H "Authorization: Bearer <TOKEN>" -H "Cache-Control: no-cache" https://api.einstein.ai/v2/vision/datasets/1011898/models -k

{"object":"list","data":[{"datasetId":1011898,"datasetVersionId":7273,"name":"Weather Intent Model","status":"FAILED","progress":0.01,"createdAt":"2017-09-03T16:50:43.000+0000","updatedAt":"2017-09-03T16:54:57.000+0000","failureMsg":"Trainer process failed to complete","object":"model","modelId":"OPLZANLBXC6ILDY5W5XQVVPUKA","modelType":"text-intent"}]}
What I would like to know is how to troubleshoot issues? Are there log files somewhere? Any way to enable debug?
I'm trying to understand how to communicate/ set attributes (variables) in nested components. Here's the situation:
Top level component: enterResult.cmp -- contains an aura:iterate that calls...
Second level component: topicItem.cmp.
I'm running a doInit handler in topicItemController.js, where I want to get an attibute from Top Level enterResult.cmp, add 1, then set an attribute in Second level component topicItem.cmp.

Any help, links to documentation, and/or examples would be appreciated. Thanks!
I'm creating a Lightning component that uses aura:iterate to dynamically build a form, with a field for each item in a list object. The markup works great, but I don't know how to go back and get the values from the fields later -- to validate the fields and then to save the values.

I would normally use aura:id to component.find() the field, and then get("v.value"). BUT aura:id is undefined because it can't be dynamically assigned with a merge field. Here's how I was trying to assign aura:id in the iteration markup, but that aura:id assignment doesn't work.
<aura:component >
    <aura:attribute name="topic" type="Topic__c"/>
        <div class="slds-tile slds-hint-parent">
            <div class="slds-form-element slds-is-required">
                <div class="slds-form-element__control">
                    <ui:inputNumber aura:id="{!v.topic.Id}" label="{!v.topic.Name}"
                                    class="slds-input"
                                    labelClass="slds-form-element__label"
                                    value = "{!v.topicResult.score__c}" />   
                </div>
            </div> 
        </div>
</aura:component>
I've double checked that {v.topic.Id} is valid (I can assign it to the label with no problem). I've tried using a simple string in a variable, also with no success. It appears aura:id has to be hard-coded.

So, any ideas on another attribute I can use to identify and call each field?
Is there a way to do a component.find() on a different attribute, like label, that can be set dynamically?

I'm using ui:inputNumber based on my use of it in the Lightning Component Trail on Trailhead (the one with Expenses and the Camping List), but I'm seeing an altenative --  lightning:input (Beta). I'm reading the docs on it, thinking maybe I can use the name attribute, but not sure if I can then component.find() it by name.

Any insight or ideas out there? Thanks.
I have a component that creates a form to enter Salesforce Certification Test Results, which provide section level scores. For example:

Test Taker: John Doe
Test Date: 08/02/2017
Exam: Administrator I

Section-Level Scores:
Organization Set-Up (Global UI): 100%
User Setup: 66%
Security and Access: 75%
Standard and Custom Objects: 77%
Sales and Marketing Applications: 75%
Service and Support Applications: 75%
Activity Management and Collaboration: 66%
Data Management: 100%
Analytics - Reports and Dashboards: 100%
Workflow/Process Automation: 80%
Desktop and Mobile Administration: 100%
AppExchange: 100%

When saved, I need to do the following:
  • Save the Exam name, User name, Exam date to a NEW Result__c record. Result__c is my PARENT object in a Master-Detail Relationship.
  • Create x number of child objects in Result_topic__c[], saving Topic Name, Score, and the recordID of the new result__c record. But that parent record is being created in the same operations (one form submission). 
I don't know where to derive the recordID number for the parent record that is being created at the same time. Does recordId get generated during the save operation, or is it generated when you hit the NEW button and open the form (that wouldn't be very efficient, but very useful in this situation.)

Anybody know where to look for an answer?
We're instructed to send an email to the finance group -- that's pretty vague. I'm going to create a Finance group, made up of the CFO and subordinates. Am I missing something in the instructions?
It looks to me like the insructions on part of this trail are out of order.  About halfway down you are creating the "handleCreateExpense" action handler. These are the instructions:
We’ll start with the handleUpdateExpense action handler. Here’s the code, and be sure to put it riiiiiight under the handleCreateExpense action handler.

It tells us to put it under the "handleCreateExpense" handler, but we haven't created that one yet.  The instructions to create it are further down in the instructions.  About another quarter of the way through we finally get to this:
Finally, for the last step, create the handleCreateExpense action handler in the expenses controller. Add this code right above or below the handleUpdateExpense action handler.​
 
Wanted to share since it caught me up for a bit.  Thought I had missed something in an earlier trail and went searching for it.

Has anyone completed the Security Superbadge since the updates by Trailhead?  I can't get the Apex tests to pass for Stage 2.  All I get is the (1/2) Test Methods Passed (i.e., 1 test failed) with absolutely no suggestion as to what to do.  

User-added image

Does anyone know what the Apex test is even looking for?  I can't fix what I don't know is broken, so I'm completely stuck.  

Maybe it's this part of the instructions?

"Configure other Salesforce settings related to record-level security to meet the business requirements."

That seems rather ambiguous so I'm not sure if I'm missing some part of the requirements.  

Hi everyone!
I have a problem with the challenge, my App work fine but I don´t pass the challenge. This is my code:

campingList.cmp:
 
<aura:component controller="CampingListController">
    
    <ltng:require styles="/resource/SLDS105/assets/styles/salesforce-lightning-design-system-ltng.css"/>

	<aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
    
     <aura:attribute name="newItem" type="Camping_Item__c"
     default="{ 'sobjectType': 'Camping_Item__c',
                    'Price__c': 0,
                    'Quantity__c': 0}"/>
    
    <div class="slds-card slds-p-top--medium">
    <ui:inputText aura:id="campname" label="Camping Name"
        value="{!v.newItem.Name}" required="true"/>
    <ui:inputCheckbox aura:id="packed" label="Packed?"
        value="{!v.newItem.Packed__c}"/>
     <ui:inputCurrency aura:id="price" label="Price"
        value="{!v.newItem.Price__c}" required="true"/>
     <ui:inputNumber aura:id="quantity" label="Quantity"
        value="{!v.newItem.Quantity__c}" required="true"/>
    
    <ui:button label="Create Camping" press="{!c.clickCreateCamping}"/>
    </div>
    
    <aura:attribute name="items" type="Camping_Item__c[]"/>	 
    <div class="slds-card slds-p-top--medium">
        <header class="slds-card__header">
            <h3 class="slds-text-heading--small">Campings</h3>
        </header>
        <section class="slds-card__body">
            <div id="list" class="row">
                <aura:iteration items="{!v.items}" var="item">
                    <c:campingListItem item="{!item}"/>
                </aura:iteration>
            </div>
        </section>
    </div>
</aura:component>

campingListController.js:
 
({
    
    // Load expenses from Salesforce
	doInit: function(component, event, helper) {

    // Create the action
    var action = component.get("c.getItems");

    // Add callback behavior for when response is received
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            component.set("v.items", response.getReturnValue());
        }
        else {
            console.log("Failed with state: " + state);
        }
    });

    // Send action off to be executed
    $A.enqueueAction(action);
	},
    
    clickCreateCamping: function(component, event, helper) {
        
        if(helper.validateCampingForm(component)){
	        // Create the new expense
	        var newCamping = component.get("v.newItem");
	        helper.createItem(component, newCamping);
	    }
    }
})
campingListHelper.js
 
({
    
    createItem: function(component, camping) {
        
        var action = component.get("c.saveItem");
        action.setParams({
            "item": camping
        });
    	action.setCallback(this, function(response){
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            var campings = component.get("v.items");
            campings.push(response.getReturnValue());
            component.set("v.items", campings);
        }
    	});
    	$A.enqueueAction(action);
    },
    
    validateCampingForm: function(component) {
      
     	var validQuantity = true;
        var validPrice = true;

        var nameField = component.find("campname");
        var campname = nameField.get("v.value");
        
        var quantityField = component.find("quantity");
        var quantity = quantityField.get("v.value");
        
        var priceField = component.find("price");
        var price = priceField.get("v.value");
        
        if ($A.util.isEmpty(campname) || $A.util.isEmpty(quantity) || $A.util.isEmpty(price)){
            validQuantity = false;
            validPrice = false;
            nameField.set("v.errors", [{message:"Camping name, quantity or price can't be blank."}]);
        }
        else {
            nameField.set("v.errors", null);
        }
		
		return(validQuantity && validPrice);        
	}
})
CampingListController.apxc:
 
public with sharing class CampingListController {

    @AuraEnabled
    public static List<Camping_Item__c> getItems() {
    
        // Check to make sure all fields are accessible to this user
        String[] fieldsToCheck = new String[] {
            'Id', 'Name', 'Packed__c', 'Price__c', 'Quantity__c'
        };
        
        Map<String,Schema.SObjectField> fieldDescribeTokens = 
            Schema.SObjectType.Camping_Item__c.fields.getMap();
        
        for(String field : fieldsToCheck) {
            if( ! fieldDescribeTokens.get(field).getDescribe().isAccessible()) {
                throw new System.NoAccessException();
                return null;
            }
        }        
        
        // Perform isAccessible() checking first, then
        return [SELECT Id, Name, Packed__c, Price__c, Quantity__c 
                FROM Camping_Item__c];
    }
    
    @AuraEnabled
    public static Camping_Item__c saveItem(Camping_Item__c item) {
        // Perform isUpdatable() checking first, then
        upsert item;
        return item;
    }
}
I am still getting this error:

Challenge Not yet complete... here's what's wrong:
The campingList JavaScript helper isn't saving the new record to the database or adding it to the 'items' value provider.


My App save the new record into the database and add it to the "items" list.
Thanks for your answers!