1

Here is my code. I followed the Lightning Components Developer Guide for the most part. I left out parts about updating the running count of records and changed how the 'newCase' attribute is created and populated the input data.

My guess is this is it where its going wrong. This is due to me setting the newCase values to the respective fields AFTER pulling the newCase attribute from the view. Either this or the fact that I am passing events in createCase and upsertCase in the helper class function parameters instead of cases. Trying to pass cases gives me an error that says the following:

Something has gone wrong. Error during init [TypeError: Cannot read property 'apply' of undefined].Please try again.

The component runs all the way to the very end, but a new Case is not created. When I console.log(evnent) at the very end, it shows the same Case that I input data for.

Here is the link for the developer guide.

Controller

public with sharing class MyCases {

@AuraEnabled
public static List<Case> getCases(){
    Id myId = UserInfo.getUserId();
    System.debug('myId+++++++++++'+myId);

    List<Case> clist = [Select Id, Subject, Type, Origin, Status From Case];

    System.debug('clist++++++++++'+cList.size());
    return cList;
}

@AuraEnabled
public static Case saveCase(Case ca) {

// Perform isUpdateable() check here
upsert ca;
return ca;
}}

Component

<aura:component implements="forceCommunity:availableForAllPageTypes,flexipage:availableForAllPageTypes,force:appHostable" controller="MyCases">
<ltng:require styles="/resource/SLDS_Stylesheet/assets/styles/salesforce-lightning-design-system-ltng.css" />aura:attribute name="cases" type="Case[]"/>
 <aura:attribute name="newCase" type="Case"
     default="{ 'sobjectType': 'Case',
                            'Subject': '',
                     'Origin': '',
                     'Status': '',
                     'Contact': ''
                   }"/>

  <aura:handler name="init" value="{!this}" action="{!c.init}"/>

  <!-- Input Form using components -->
 <div class="container">
   <form class="slds-form--stacked">
     <div class="slds-form-element slds-is-required">
    <div class="slds-form-element__control">

      <ui:inputText aura:id="subject" label="Subject"
                    class="slds-input"
                    labelClass="slds-form-element__label"
                    value=""
                    required="true"/>
     </div>
   </div>
   <div class="slds-form-element slds-is-required">
     <div class="slds-form-element__control">
       <ui:inputText aura:id="origin" label="Origin"
                       class="slds-input"
                       labelClass="slds-form-element__label"
                       value=""
                       required="true"/>
      </div>
    </div>
    <div class="slds-form-element">
      <div class="slds-form-element__control">
        <ui:inputText aura:id="status" label="Status"
                      class="slds-input"
                      labelClass="slds-form-element__label"
                      value="" 
                      required="true"/>
       </div>
     </div>
     <div class="slds-form-element">
       <div class="slds-form-element__control">
         <ui:inputText aura:id="contact" label="Contact Name"
                           class="slds-input"
                           labelClass="slds-form-element__label"
                           value="" 
                           required="true"/>
        </div>
      </div>
      <div class="slds-form-element">
        <ui:button label="Submit" 
                   class="slds-button slds-button--neutral"
                   labelClass="label"
                   press="{!c.createCase}"/>
       </div>
     </form>
    </div>
  </aura:component>

Controller Javascript Class

({

init : function(component, event, helper) {
    helper.getCases(component);
},

createCase : function(component, event, helper) {

    var subjectField = component.find("subject");
    var subject =  subjectField.get("v.value");

    var originField = component.find("origin");
    var origin =  originField.get("v.value");

    var statusField = component.find("status");
    var status =  statusField.get("v.value");

    var contactField = component.find("contact");
    var contact =  contactField.get("v.value");

    var newCase = component.get('v.newCase');
    newCase.subject = subject;
    newCase.origin = origin;
    newCase.status = status;
    newCase.contact = contact;

    console.log(newCase);
    helper.createCase(component, newCase);


    console.log('End of createCase');

}})

Controller Javascript Helper Class

({
 getCases: function(component) {
    var action = component.get("c.getCases");
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            component.set("v.cases", response.getReturnValue());
        }
    });
    $A.enqueueAction(action);  },


  createCase: function(component, event) {
    this.upsertCase(component, event, function(a) {
        var cases = component.get("v.cases");
        cases.push(a.getReturnValue());
        component.set("v.cases", cases);
      });
},

upsertCase : function(component, event, callback) {
    var action = component.get("c.saveCase");
    action.setParams({ 
        "case": event
    });
    if (callback) {
      action.setCallback(this, callback);
    }
    $A.enqueueAction(action);

},})

2 Answers 2

1

Try to convert your new Case into JSON using JSON.stringify() and send it instead of object. On server side, deserialize it with JSON.deserialize() and then upsert. In general you should do the following:

use

helper.createCase(component, JSON.stringify(newCase));

instead of

helper.createCase(component, newCase);

and on server side your method should look like

@AuraEnabled
public static Case saveCase(String caseJSON) {
    Case newCase = (Case)JSON.deserialize(caseJSON, Case.class);

    upsert newCase;
    return newCase;
}

If you'll compare object representation of new Case record before saveCase() is executed with representation that is returned by this method you should notice that they are different. Lightning does not send sObject records on server appropriatelly if they have a structure presented in your "default" attribute while second representation is easily converted by framework without any issues. In such cases, when APEX can't recognize the data sent from client controller, handling object conversion on your own is a good way to solve the issue.

Additional suggestions:

1) bind your record fields with their inputs, in that case you don't need to write any code to pull values from inputs and put them into your record

<ui:inputText label="Origin" class="slds-input"
                   labelClass="slds-form-element__label"
                   value="{!v.record.Field__c}"
                   required="true"/>

2) use component from lightning: namespace instead of ui:, they are more flexible and inherit SLDS styles

3) try to use Lightning Data Service in cases when you need to view/create/edit a single record

4) implement methods in handler only if their logic is used multiple times in controller methods, it is their main purpose

Let me know if this helps

0

If this is specified in the developers guide, it's weird thing that is not working, but why dont you try this by passing the parameters to the method and create the case in the controller, did you see the debug logs under saveCase?

Also, you are getting the user id and not using it the query you defined in getCases.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .