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
Tyler HarrisTyler Harris 

Getting a 'attempt' to dereference null object Visualforce' Apex Visualforce

Trying to do some basic addition between two datatables to simulate a shoping cart.

I want the tempCount to total into the Cart class. It looks like it should work. Not sure why it's throwing an error.

Apex:
public class StoreFront2 {
    public String message { get; set; }
    List<DisplayMerchandise> products;
    Map<Id, DisplayMerchandise> cart;

    public PageReference shop(){
        handleTheBasket();
        message = 'You bought: ';
        for (DisplayMerchandise p:products){
            if(p.count > 0){
               message += p.merchandise.name + ' (' + p.count + ') ' ;
               }
            }
        return null;
    }

    public void handleTheBasket(){
        for(DisplayMerchandise c : products){
            if(c.tempCount > 0){
            if(cart.containsKey(c.merchandise.Id)){
                
                cart.get(c.merchandise.Id).count += c.tempCount;
                
            }
            else{
                cart.put(c.merchandise.Id, c);
            } 
        
        }
        }
        
    }
    
    public Map<Id, DisplayMerchandise> getCart() {
        if(cart == null){
            cart = new Map<Id, DisplayMerchandise>{};
                }
       
        return cart;
    }

    public class DisplayMerchandise {
        public Merchandise__c merchandise{get; set;}
        public Decimal count{get; set;}
        public Decimal tempCount{get;set;}
        
        public DisplayMerchandise(Merchandise__c item){
            this.merchandise = item;
            
        }
    }

    public List<DisplayMerchandise> getProducts() {
        if (products == null){
            products = new List<DisplayMerchandise>{};

            for (Merchandise__c item :
            [SELECT id, name, description__c, price__c
            FROM Merchandise__c
            WHERE Total_Inventory__c > 0]) {
            products.add(new DisplayMerchandise(item));
            }
        }
        return products;
    }
}

Visualforce
<apex:page standardStylesheets="false" showHeader="false" sidebar="false" controller="StoreFront2">
  <apex:stylesheet value="{!URLFOR($Resource.styles)}"/>
  <h1>Store Front</h1>
  
  <apex:form >
      <apex:dataTable value="{!products}" var="pitem" rowClasses="odd,even">
          
          <apex:column headerValue="Product">
              <apex:outputText value="{!pitem.merchandise.name}" />
          </apex:column>
          <apex:column headervalue="Price">
              <apex:outputText value="{!pitem.merchandise.Price__c}" />
          </apex:column>
          <apex:column headerValue="#Items">
              <apex:inputText value="{!pitem.tempCount}"/>
          </apex:column>
   
      </apex:dataTable>
      
      <br/>
      <apex:commandButton action="{!shop}" value="Add to Cart" reRender="msg,cart" />
  </apex:form>
  
    <apex:outputPanel id="msg">{!message}</apex:outputPanel><br/>    
    <h1>Your Basket</h1>
<form>    
     <apex:dataTable id="cart" value="{!cart}" var="carti" rowClasses="odd,even">
          
          <apex:column headerValue="Product">
              <apex:outputText value="{!cart[carti].merchandise.name}" />
          </apex:column>
          <apex:column headervalue="Price">
              <apex:outputText value="{!cart[carti].merchandise.price__c}" />
          </apex:column>
          <apex:column headerValue="#Items">
              <apex:outputText value="{!cart[carti].count}"/>
          </apex:column>
   
      </apex:dataTable>
    </form>
    
  
</apex:page>

 
Best Answer chosen by Tyler Harris
Tyler HarrisTyler Harris
That's a good solution, but I was able to fix by initialising the variables in the else statement:
 
public void handleTheBasket(){
        for(DisplayMerchandise c : products){
            if(c.tempCount > 0){
            if(cart.containsKey(c.merchandise.Id)){
                
                cart.get(c.merchandise.Id).count += c.tempCount;
                
            }
            else{
                cart.put(c.merchandise.Id, c);
                cart.get(c.merchandise.Id).count = c.tempCount;
            } 
        
        }
        }
        
    }


 

All Answers

Tyler HarrisTyler Harris
Error below:
Attempt to de-reference a null object
Error is in expression '{!shop}' in component <apex:commandButton> in page storecart: Class.StoreFront2.handleTheBasket: line 22, column 1
Class.StoreFront2.shop: line 7, column 1
An unexpected error has occurred. Your development organization has been notified.
sandeep sankhlasandeep sankhla
HI Tyler,

As a best practise we should always initalize our variables to avoid these kind of errors..

Please initalize all variables in constructor..

you can add a constructor and initalize like below

public StoreFront2()
{

     products = new List<DisplayMerchandise>();
     message  = '';
     cart = new Map<Id, DisplayMerchandise>();


}

Please chek and let me know if it helps you..

P.S. If my answer helps you to solve your problem please mark it as best answer. It will help other to find best answer.

Thanks,
Sandeep
Salesforce Certified Developer 
JayantJayant
In getCart() -
Replace 
cart = new Map<Id, DisplayMerchandise>{};
with
cart = new Map<Id, DisplayMerchandise>();

Similarly, in getProducts() - 
Replace
products = new List<DisplayMerchandise>{};
with
products = new List<DisplayMerchandise>();

The difference - 

Map<String, String> dummy = new Map<String, String>() -> This creates a new reference in memory that can be used to access the collection.

Map<String, String> dummy1 = new Map<String, String>{'key'=>'value'} -> This is used to populate the map during declaration.
Tyler HarrisTyler Harris
I'm still getting the error

Attempt to de-reference a null object
Error is in expression '{!shop}' in component <apex:commandButton> in page storecart: Class.StoreFront2.handleTheBasket: line 22, column 1
Class.StoreFront2.shop: line 7, column 1

Apex
public class StoreFront2 {
    public String message { get; set; }
    List<DisplayMerchandise> products;
    Map<Id, DisplayMerchandise> cart;

    public PageReference shop(){
        handleTheBasket();
        message = 'You bought: ';
        for (DisplayMerchandise p:products){
            if(p.tempCount > 0){
               message += p.merchandise.name + ' (' + p.tempCount + ') ' ;
               }
            }
        return null;
    }

    public void handleTheBasket(){
        for(DisplayMerchandise c : products){
            if(c.tempCount > 0){
            if(cart.containsKey(c.merchandise.Id)){
                
                cart.get(c.merchandise.Id).count += c.tempCount;
                
            }
            else{
                cart.put(c.merchandise.Id, c);
            } 
        
        }
        }
        
    }
    
    public Map<Id, DisplayMerchandise> getCart() {
        if(cart == null){
            cart = new Map<Id, DisplayMerchandise>();
                }
       
        return cart;
    }

    public class DisplayMerchandise {
        public Merchandise__c merchandise{get; set;}
        public Decimal count{get; set;}
        public Decimal tempCount{get;set;}
        
        public DisplayMerchandise(Merchandise__c item){
            this.merchandise = item;
            
        }
    }

    public List<DisplayMerchandise> getProducts() {
        if (products == null){
            products = new List<DisplayMerchandise>();

            for (Merchandise__c item :
            [SELECT id, name, description__c, price__c
            FROM Merchandise__c
            WHERE Total_Inventory__c > 0]) {
            products.add(new DisplayMerchandise(item));
            }
        }
        return products;
    }
}

Visualforce
<apex:page standardStylesheets="false" showHeader="false" sidebar="false" controller="StoreFront2">
  <apex:stylesheet value="{!URLFOR($Resource.styles)}"/>
  <h1>Store Front</h1>
  
  <apex:form >
      <apex:dataTable value="{!products}" var="pitem" rowClasses="odd,even">
          
          <apex:column headerValue="Product">
              <apex:outputText value="{!pitem.merchandise.name}" />
          </apex:column>
          <apex:column headervalue="Price">
              <apex:outputText value="{!pitem.merchandise.Price__c}" />
          </apex:column>
          <apex:column headerValue="#Items">
              <apex:inputText value="{!pitem.tempCount}"/>
          </apex:column>
   
      </apex:dataTable>
      
      <br/>
      <apex:commandButton action="{!shop}" value="Add to Cart" reRender="msg,cart" />
  </apex:form>
  
    <apex:outputPanel id="msg">{!message}</apex:outputPanel><br/>    
    <h1>Your Basket</h1>
<form>    
     <apex:dataTable id="cart" value="{!cart}" var="carti" rowClasses="odd,even">
          
          <apex:column headerValue="Product">
              <apex:outputText value="{!cart[carti].merchandise.name}" />
          </apex:column>
          <apex:column headervalue="Price">
              <apex:outputText value="{!cart[carti].merchandise.price__c}" />
          </apex:column>
          <apex:column headerValue="#Items">
              <apex:outputText value="{!cart[carti].count}"/>
          </apex:column>
   
      </apex:dataTable>
    </form>
    
  
</apex:page>

 
JayantJayant
Not sure why you are getting this (especially on line # 22), but if its still not resolved try 1 of these - 

1. Add a Constructor - 
public StoreFront2()
{
    //Call getters explicitly, so they are initialized
    getProducts();
    getCart();
}

2. Modify DisplayMerchandise constructor - 
public DisplayMerchandise(Merchandise__c item){
      this.merchandise = item;
      this.count = 0;
      this.tempCount = 0;
}
 
Tyler HarrisTyler Harris
That's a good solution, but I was able to fix by initialising the variables in the else statement:
 
public void handleTheBasket(){
        for(DisplayMerchandise c : products){
            if(c.tempCount > 0){
            if(cart.containsKey(c.merchandise.Id)){
                
                cart.get(c.merchandise.Id).count += c.tempCount;
                
            }
            else{
                cart.put(c.merchandise.Id, c);
                cart.get(c.merchandise.Id).count = c.tempCount;
            } 
        
        }
        }
        
    }


 
This was selected as the best answer
nansi kela 21nansi kela 21
Hello Everyone..

This code is very useful for me. Thank you.. 
I have a query :-  Can we add Counter in Cart .. means Number of product in cart..

Like If we have 3 products in cart.. Then it should b look like
Cart 3

Please provide any solution regarding this..

Thank you

Regards,
Nansi Kela