Skip to content
Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
DictionaryWWrapper Class
DevelopmentIntermediate

Wrapper Class

A wrapper class in Apex is a custom class that bundles several values, or several objects, into one object so your code can pass them around as a single unit.

§ 01

Definition

A wrapper class in Apex is a custom class that bundles several values, or several objects, into one object so your code can pass them around as a single unit. Developers reach for a wrapper class when the data a screen or a process needs does not line up with any one Salesforce object. The class declares the fields it needs as public properties, and usually a constructor that fills them in one step.

The pattern shows up most often in Visualforce pages and Lightning components that display a table with a checkbox on every row. A SOQL query returns the records, but a record has nowhere to store whether its row is ticked. A wrapper class sits beside each record and holds that extra Boolean, so the page can bind to the record and the checkbox at once. The class is ordinary Apex. It carries no special annotation and can live inside the controller that uses it.

§ 02

How a wrapper class earns its place in Apex

Why one object is not always enough

Apex hands you sObjects for database rows and primitive types for single values. Real screens often need both at once, plus a few values that no database field holds. Picture a list of Opportunities where each row needs a checkbox, a calculated margin, and a short status label. You cannot store those three things on the Opportunity record without writing them to the database first, and you do not want to do that just to render a page. A wrapper class keeps the Opportunity and the extra values together in memory for the life of the request. The page then works with one list of wrapper objects instead of three loose lists that all have to stay in the same order. When a user ticks a row, the Boolean on that wrapper flips, and the record it describes is one property away. The controller stays short because it passes around a single list. The markup reads cleanly because every value a row needs hangs off the same object. The pattern gives a screen a shape the data model alone does not provide, and it does so without touching the database.

What the pattern looks like in code

A wrapper class is a normal class with public properties and a constructor. A common shape holds the record and a Boolean. You might write a class named OppRow with an Opportunity property called record and a Boolean property called selected. The constructor takes an Opportunity and sets selected to false by default. The controller queries the Opportunities, loops over them once, and adds a new OppRow to a list for each record. That list of wrappers is what the page reads. Because the wrapper is only useful to the controller that builds it, developers usually declare it as an inner class inside the controller file. Apex allows one level of inner classes, which is all this job needs. The wrapper needs no interface and no annotation to work in Apex itself, so it stays small and easy to read. It is the plainest kind of class the language allows. That simplicity is a large part of why the pattern shows up in so many orgs, and why new developers meet it early.

Selecting rows on a Visualforce page

The original home of the wrapper class is the Visualforce table with row selection. An apex:pageBlockTable binds its value to the list of wrappers and its var to a single wrapper. Inside the table, one column binds an apex:inputCheckbox to the selected property, and the other columns bind to fields on the wrapped record. When the user submits the form, the controller walks the same list and reads which wrappers have selected set to true. Those are the chosen records, ready for an update, a delete, or a custom action. Without the wrapper there is no clean place to hold the checkbox state across the postback that Visualforce performs. People once tried a parallel map of record id to Boolean, which worked but tended to drift out of sync with the list it shadowed. The wrapper keeps the record and its selection in one object, so the two values can never separate. This is the example most tutorials still use to teach the pattern, because it makes the need for a wrapper obvious.

Carrying the idea into Lightning and LWC

Lightning Web Components moved the user interface to the browser, but the wrapper class still earns its keep on the server. An Apex method marked AuraEnabled can return a list of wrapper objects, and the framework serializes them to JSON for the component to read. The component receives them as plain JavaScript objects with the same property names the Apex class used. For this to work, the wrapper properties must themselves be marked AuraEnabled, so the framework can see and serialize them. A common use is a custom data table that needs a record plus a computed value the query did not return, such as a days-open count or a formatted total. The wrapper computes those on the server and ships them next to the record. The component never has to recreate the logic in JavaScript, which keeps a single source of truth in Apex. The same idea supports a flow screen or an Aura component, so one wrapper design can feed several front ends without change.

Sorting, grouping, and running totals

Once data sits in wrapper objects, you can shape it in ways a raw query cannot. Because the wrapper is a class, you can make it implement the Comparable interface and define a compareTo method. A list of wrappers will then sort on whatever rule you write, such as margin descending or name ascending, which a single SOQL order by clause may not express. Wrappers also make grouping natural. You can build a map keyed by region, where each value is a list of wrappers for that region, and add a per-group subtotal property to each one. A summary row at the top of a page reads those subtotals directly. The query stays simple, and the presentation logic lives in Apex, where unit tests cover it. This is the point where a wrapper class stops being a workaround and becomes a small, testable view model for the screen. A new teammate can read the class and see exactly what each row will show, which is hard to get from a query and a page alone.

Keeping wrapper classes inside governor limits

A wrapper class lives in the heap, so it counts toward the limits Salesforce sets on every transaction. Each wrapper you build holds a reference to a record and whatever extra values you add to it. Wrapping a few hundred rows is cheap and well within budget. Wrapping tens of thousands in one request can push the heap size limit and stop the transaction with an error. The safe habit is to query only the rows a screen will actually show, page through large sets, and keep the wrapper lean. Store what the page reads and nothing more. Avoid putting queries or DML inside the wrapper itself, because building a list could then fire one query per row and burn the SOQL query limit in a single loop. Keep data access in the controller, build the wrappers in one pass, and reuse the list rather than rebuilding it on every action. Follow those habits and the pattern stays well inside the limits, even on a busy page that thousands of users load each day.

When to choose a wrapper over other options

A wrapper class is not the only way to carry extra data, so it helps to know when it fits. If you only need to add one value to a query result and you control the SOQL, a formula field or a sub-select can sometimes do the job without any Apex at all. If the extra value is the same for every row, a single controller property is simpler than a wrapper. The wrapper earns its place when each row needs its own extra values, when those values come from logic rather than the database, or when the page has to track per-row state such as a checkbox. It also fits when several screens share the same shaped data, because one class can feed them all from a single design. Reaching for a wrapper out of habit can add code you do not need, so weigh it against the lighter options first. When a row truly needs more than the record holds, the wrapper is the clean and well-understood answer that most Salesforce developers will recognise on sight.

§

Trust & references

Sources

Cross-checked against the following references.

Official documentation

Straight from the source - Salesforce's reference material on Wrapper Class.

Keep learning

Hands-on resources to go deeper on Wrapper Class.

Was this entry helpful?
Help us write better definitions. Quick reactions or detailed edit suggestions.

About the Author

Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.

§

Test your knowledge

Q1. What is a Wrapper Class?

Q2. What's a classic use case?

Q3. Is it Visualforce-only?

§

Discussion

Loading…

Loading discussion…