Async in Class Methods
Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 80 of 110.
Now that you know how to handle async initialization with factory methods, let's look at making regular instance methods asynchronous. This is straightforward - just add async to any method and have it return a Future.
class WeatherService {
String _location;
WeatherService(this._location);
Future<String> fetchTemperature() async {
await Future.delayed(Duration(seconds: 1));
return '22°C in $_location';
}
Future<void> updateLocation(String newLocation) async {
await Future.delayed(Duration(milliseconds: 500));
_location = newLocation;
print('Location updated to $_location');
}
}
Future<void> main() async {
var service = WeatherService('London');
var temp = await service.fetchTemperature();
print(temp);
await service.updateLocation('Paris');
}Async methods can access and modify instance variables just like regular methods. The key difference is that callers must await the result. Methods returning Future<void> don't return a value but still need to be awaited if you want to ensure they complete before continuing.
You can also combine multiple async calls within a method, or call other async methods from the same class:
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}This pattern is essential for classes that interact with external resources - APIs, databases, or any operation that takes time.
Challenge
EasyLet's build a stock portfolio tracker that manages stock prices and calculates portfolio values using async methods! You'll create a class that simulates fetching real-time stock data and combines multiple async operations to generate reports.
You'll organize your code into two files:
portfolio.dart: Create aStockPortfolioclass that tracks stocks and their quantities. Your class should have:- A private
Map<String, int>called_holdingsthat stores stock symbols and the number of shares owned - A constructor that initializes
_holdingsas an empty map - A method
addStock(String symbol, int quantity)that adds or updates a stock holding (not async) - An async method
fetchPrice(String symbol)that returns aFuture<double>. Simulate a delay of 50 milliseconds, then return a price calculated as: the length of the symbol multiplied by 25.5 - An async method
getStockValue(String symbol)that returns aFuture<double>. This should awaitfetchPricefor the symbol, multiply by the quantity held, and return the total value. If the symbol isn't in holdings, return 0.0 - An async method
getTotalValue()that returns aFuture<double>. This should calculate the combined value of all holdings by awaitinggetStockValuefor each stock and summing the results - An async method
generateReport()that returns aFuture<String>. This should build a report showing each stock's value and the total. Format each line as[symbol]: $[value](value with 1 decimal place), followed by a final lineTotal: $[totalValue](also 1 decimal place)
- A private
main.dart: Import your portfolio file and demonstrate how async methods work together within a class:- Create a
StockPortfolioinstance - Add these holdings:
AAPLwith 10 shares,GOOGLwith 5 shares,MSFTwith 8 shares - Print
Fetching portfolio data... - Await and print the result of
generateReport()
- Create a
Notice how generateReport() calls other async methods within the same class, and how each method builds upon the others. Use toStringAsFixed(1) to format decimal values!
Expected output:
Fetching portfolio data...
AAPL: $1020.0
GOOGL: $637.5
MSFT: $816.0
Total: $2473.5Cheat sheet
To make instance methods asynchronous, add the async keyword and return a Future:
class WeatherService {
String _location;
WeatherService(this._location);
Future<String> fetchTemperature() async {
await Future.delayed(Duration(seconds: 1));
return '22°C in $_location';
}
Future<void> updateLocation(String newLocation) async {
await Future.delayed(Duration(milliseconds: 500));
_location = newLocation;
print('Location updated to $_location');
}
}Async methods can access and modify instance variables. Callers must await the result. Methods returning Future<void> don't return a value but still need to be awaited to ensure completion.
Async methods can call other async methods within the same class:
Future<String> getFullReport() async {
var temp = await fetchTemperature();
var humidity = await fetchHumidity();
return '$temp, Humidity: $humidity';
}This pattern is essential for classes that interact with external resources like APIs or databases.
Try it yourself
import 'portfolio.dart';
void main() async {
// TODO: Create a StockPortfolio instance
// TODO: Add holdings:
// - AAPL with 10 shares
// - GOOGL with 5 shares
// - MSFT with 8 shares
// TODO: Print "Fetching portfolio data..."
// TODO: Await and print the result of generateReport()
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesLibraries & ImportsIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsInstance VariablesConstructor BasicsRecap - Simple Calculator4Null Safety
Intro to Null SafetyNullable vs Non-NullableThe ? and ! OperatorsLate Keyword & Null SafetyNull-Aware OperatorsNull Safety in ClassesRecap - User Profile System7Abstract Classes & Interfaces
Abstract ClassesAbstract MethodsInterfaces in DartImplicit InterfacesImplementing vs ExtendingMultiple InterfacesRecap - Shape Calculator10Collections & Generics
List, Set, Map OverviewType-Safe CollectionsGeneric ClassesGeneric MethodsGeneric ConstraintsIterable & IteratorRecap - Generic Storage13Advanced OOP Concepts
Composition vs InheritanceExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums with Methods16Project: Library Management
Project OverviewBook and User Classes2Constructors in Dart
Default ConstructorNamed ConstructorsInitializer ListsConstant ConstructorsFactory ConstructorsRedirecting ConstructorsRecap - Shape Builder5Encapsulation
Public vs Private MembersThe _ Prefix ConventionLibrary-Level PrivacyGetters & Setters DepthInformation HidingRecap - Student Records8Mixins
Introduction to MixinsCreating MixinsUsing Multiple Mixinson Keyword in MixinsMixin vs InheritanceMixin vs InterfaceRecap - Animal System11Special Methods
toString() OverridehashCode & == OverrideComparable Interfacecall() MethodnoSuchMethod OverrideRecap - Custom Collection14Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern3Class Properties
Instance vs Static MembersFinal & Const FieldsLate VariablesStatic Methods & FieldsGetters and SettersRecap - Bank Account Manager6Inheritance
Basic InheritanceThe super KeywordMethod OverridingThe @override AnnotationThe final Class KeywordConstructors & InheritanceRecap - Employee Hierarchy9Polymorphism
Polymorphism BasicsPolymorphism via InterfacesRuntime Type CheckingThe is & as OperatorsCovariant KeywordRecap - Payment Processor12Async OOP
Futures & async/awaitStreams BasicsStream ControllersAsync ConstructorsAsync in Class MethodsRecap - Data Fetcher