function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JeffreyStevensJeffreyStevens 

Serverside controllers ExpenseController returns ERROR

I'm working through the Connect to Salesforce with Server-Side Controllers step, and before the challenge - dealing with the expenses - my createExpense function is getting a response state of ERROR.  I am NOT getting anything in the debug on the apex controller that it's even being called.

Can anyone give me some more to go on here?

expensesHelper.js...
({
    validateExpenseForm: function(component) {
    	
        var validExpense = true;
        
        // Name must not be blank
        var nameField = component.find("expname");
        var expname = nameField.get("v.value");
        if ($A.util.isEmpty(expname)) {
            validExpense = false;
            nameField.set("v.errors", [{message: "Expense name can't be blank."}]);
        } else {
            nameField.set("v.errors", null);
        }
        
        // Amount must be set
        var amtField = component.find("amount");
        var amt = amtField.get("v.value");
        if ($A.util.isEmpty(amt) || isNaN(amt) || (amt <= 0.00)) {
            validExpense = false;
            amtField.set("v.errors", [{message:"Enter an expense amount."}]);
        } else {
            amtField.set("v.errors", null);
        }
        
        return validExpense;
        
    },
    
	createExpense : function(component, expense) {
        console.log('createExpense...');
        
        var action = component.get("c.saveExpense");
        action.setParams({"expense" : expense});
        
        action.setCallback(this, function(response) {
        	var state = response.getState();
            console.log('response='+response + response.getState());
            if (component.isValid() && state === "SUCCESS") {
                var expenses = component.get("v.expenses");
                expenses.push(response.getReturnValue());
                component.set("v.expenses", expenses);
            }
        });
        $A.enqueueAction(action);
        var theExpenses = component.get("v.expenses");
		console.log("theExpenses="+JSON.parse(JSON.stringify(theExpenses)));
	}
})

ExpenseController.apxc...
public with sharing class ExpenseController {
    
    @AuraEnabled
    public static list<Expense__c> getExpenses(){
        system.debug('getExpenses...');
        // Perform isAccessible() checking first, then
        // check to make sure all fields are accessible to this user
        
        String[] fieldsToCheck = new string[] {
            'Id', 'Name', 'Amount__c', 'Client__c', 'Date__c', 'Reimbursed__c', 'CreatedDate'
        };
        map<string,Schema.sObjectField> fieldDescribeTokens = Schema.sObjectType.Expense__c.fields.getMap();
        
        for(String field :fieldsToCheck) {
            if (!fieldDescribeTokens.get(field).getDescribe().isAccessible()) {
                throw new System.NoAccessException();
                return null;
            }
        }

        
        return [SELECT id,name, Amount__c, Client__c, 
                		Date__c, Reimbursed__c,CreatedDate
               	FROM Expense__c];
    }

    @AuraEnabled
    public static Expense__c saveExpense(Expense__c expense) {
        system.debug('saveExpense...');
        // Perform isUpdateable() checking first, then
        upsert expense;
        system.debug('expense='+expense);
        return expense;
    }
}

 
Best Answer chosen by JeffreyStevens
JeffreyStevensJeffreyStevens
Found the issue - it was a typo on the objectType definition in the component.

This
<!-- Expense object definition & list -->
    <aura:attribute name="expenses" type="Expense__c[]" />
	<aura:attribute name="newExpense" type="Expense__c"
                    default="{ 'sobjecType' : 'Expense__c' ,
                            'Name' 			: '' ,
                            'Amount__c ' 	: 0,
                            'Client__c'		: '',
                            'Date__c'		: '',
                            'Reimbursed__c' : false }" />

was changed to 
<!-- Expense object definition & list -->
    <aura:attribute name="expenses" type="Expense__c[]" />
	<aura:attribute name="newExpense" type="Expense__c"
                    default="{ 'sobjectType' : 'Expense__c' ,
                            'Name' 			: '' ,
                            'Amount__c ' 	: 0,
                            'Client__c'		: '',
                            'Date__c'		: '',
                            'Reimbursed__c' : false }" />

(notice the default = "{  'sobjecType ... " typeo?

When I corrected this, the call came back with success.  Would have been nice to find some more detail error messages though.