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
Dave BerenatoDave Berenato 

system.QueryException: invalid ID field: null

I have an Apex Class that pulls Contacts that are assigned using a custom field to a specific Door Knocker:

 
public with sharing class DoorKnockerAssigned {
    
      public DoorKnockerAssigned(){
        if(ApexPages.currentpage().getParameters().get('leadgenerator') == null){myParam = UserInfo.getUserId();}
        else{myParam = ApexPages.currentpage().getParameters().get('leadgenerator');}
        }
    
      public String myParam { get; set; }
      public String sortOrder = ' Door_Knocker__r.Name ';
      public String ascendingOrDescending = ' ASC ';

public void sortByDoorKnocker() {this.sortOrder = ' Door_Knocker__r.Name '; if(ascendingOrDescending ==' ASC ') {ascendingorDescending = ' DESC ';} else{ascendingorDescending = ' ASC ';}}

String myRequestYesterday = ' SELECT id, Owner.Id,Owner.Name,Name, FirstName, LastName, Door_Knocker__r.Id,Assigned_Knock_Date__c'+
                  	  ' FROM Contact '+
                      ' WHERE Assigned_Knock_Date__c = YESTERDAY AND Door_Knocker__r.Id = \'' + myParam + '\' ORDER BY ';

List<Contact> DKYesterday; public List<Contact> getDKYesterday() {DKYesterday = new List<Contact>();DKYesterday = Database.query(myRequestYesterday + sortOrder + ascendingOrDescending);return DKYesterday;}

public void saveDKYesterday() {update DKYesterday;}

And I'm using the below Test Class:
 
@isTest
public class DoorKnockerAssignedTest {
    
    static testMethod void TestDKAssignedYesterday(){
            
    Account testaccount = new Account();
    testaccount.name = '123 Test Drive';
    testaccount.RecordTypeId = '0126A0000004Qo4';
    testaccount.APN__c = '123';
    testaccount.Foreclosure_Status__c = 'Auction';
    testaccount.Property_Zip_Code__c = '90001';
    insert testaccount;
         
    Contact testcontact = new Contact();
    testcontact.Contact_Stage__c = 'Dialing';
    testcontact.Phone_1__c = '6106754043';
    testcontact.Accountid = testaccount.id;
    testcontact.LastName = 'Dave';
    testcontact.OwnerId = '0056A000000HocdQAC';
    testcontact.Door_Knocker__c = UserInfo.getUserId();
    testcontact.RecordTypeId = '0126A0000004QlU';
    testcontact.Assigned_Knock_Date__c = date.valueOf('2018-02-26 11:00:00z');
    insert testcontact;
        
    system.debug(UserInfo.getUserId());
    system.debug(testcontact.OwnerId);
    system.debug(testcontact.Door_Knocker__c);
        
    ApexPages.currentPage().getParameters().put('leadgenerator',UserInfo.getUserId());
    DoorKnockerAssigned td = new DoorKnockerAssigned();
    system.debug(td.myParam);
    List<Contact> list1 = td.getDKYesterday();
    td.saveDKYesterday();
    system.assertEquals(1, list1.size());
    }

The test fails and says "System.QueryException: invalid ID field: null" but shouldn't it pull the UserID into the myParam?

Also my system.debug didn't show up in the log.

I got the test class to pass when I took out 
AND Door_Knocker__r.Id = \'' + myParam + '\'
from String myRequestYesterday so I know it's coming from that.

Any suggestions on how I can get this to work?


 
Best Answer chosen by Dave Berenato
Dave BerenatoDave Berenato
public with sharing class DoorKnockerAssigned {
    
      public DoorKnockerAssigned(){
        if(ApexPages.currentpage().getParameters().get('leadgenerator') == null){myParam = UserInfo.getUserId();}
        else{myParam = ApexPages.currentpage().getParameters().get('leadgenerator');}
        }
    
      public String myParam { get; set; }
      public String sortOrder = ' Door_Knocker__r.Name ';
      public String ascendingOrDescending = ' ASC ';

public void sortByDoorKnocker() {this.sortOrder = ' Door_Knocker__r.Name '; if(ascendingOrDescending ==' ASC ') {ascendingorDescending = ' DESC ';} else{ascendingorDescending = ' ASC ';}}



List<Contact> DKYesterday; public List<Contact> getDKYesterday() {

String myRequestYesterday = ' SELECT id, Owner.Id,Owner.Name,Name, FirstName, LastName, Door_Knocker__r.Id,Assigned_Knock_Date__c'+
                  	  ' FROM Contact '+
                      ' WHERE Assigned_Knock_Date__c = YESTERDAY AND Door_Knocker__c = \'' + myParam + '\' ORDER BY ';

DKYesterday = new List<Contact>();DKYesterday = Database.query(myRequestYesterday + sortOrder + ascendingOrDescending);return DKYesterday;}

public void saveDKYesterday() {update DKYesterday;}
I figured it out. Because the myParam isn't set until the page loads in the test, it can't be outside the "getDKYesterday" because it was assigned a null value.
 

All Answers

Raj VakatiRaj Vakati
Your SOQL query was wrong  . Change is as shown below 
String myRequestYesterday = ' SELECT id, Owner.Id,Owner.Name,Name, FirstName, LastName, Door_Knocker__r.Id,Assigned_Knock_Date__c'+
                  	  ' FROM Contact '+
                      ' WHERE Assigned_Knock_Date__c = YESTERDAY AND Door_Knocker__r.Id = \'' + myParam + '\' ORDER BY Name ';

 
Dave BerenatoDave Berenato
Hi Raj,

The "ORDER BY" is followed by the variable "sortOrder" which is set through a public String.This allows me to build an Apex Table with sortable column headers.

When I added "Name" to the end of the SOQL Query, the error becomes "Unexpected token: Door_Knocker__r.Name" because that's the default sortOrder.
Dave BerenatoDave Berenato
public with sharing class DoorKnockerAssigned {
    
      public DoorKnockerAssigned(){
        if(ApexPages.currentpage().getParameters().get('leadgenerator') == null){myParam = UserInfo.getUserId();}
        else{myParam = ApexPages.currentpage().getParameters().get('leadgenerator');}
        }
    
      public String myParam { get; set; }
      public String sortOrder = ' Door_Knocker__r.Name ';
      public String ascendingOrDescending = ' ASC ';

public void sortByDoorKnocker() {this.sortOrder = ' Door_Knocker__r.Name '; if(ascendingOrDescending ==' ASC ') {ascendingorDescending = ' DESC ';} else{ascendingorDescending = ' ASC ';}}



List<Contact> DKYesterday; public List<Contact> getDKYesterday() {

String myRequestYesterday = ' SELECT id, Owner.Id,Owner.Name,Name, FirstName, LastName, Door_Knocker__r.Id,Assigned_Knock_Date__c'+
                  	  ' FROM Contact '+
                      ' WHERE Assigned_Knock_Date__c = YESTERDAY AND Door_Knocker__c = \'' + myParam + '\' ORDER BY ';

DKYesterday = new List<Contact>();DKYesterday = Database.query(myRequestYesterday + sortOrder + ascendingOrDescending);return DKYesterday;}

public void saveDKYesterday() {update DKYesterday;}
I figured it out. Because the myParam isn't set until the page loads in the test, it can't be outside the "getDKYesterday" because it was assigned a null value.
 
This was selected as the best answer