Skip to main content

Release 7.1.0 - Simplified API with Direct List Returns

· 3 min read
Hyo
Maintainer of flutter_inapp_purchase & expo-iap

Release 7.1.0 simplifies the fetchProducts() API by returning lists directly instead of union types, making it easier to work with products while maintaining type safety through explicit type annotations.

View the release on GitHub →

Highlights

Simplified fetchProducts API

The biggest change in 7.1 is the simplification of the fetchProducts() method. Instead of returning a FetchProductsResult union type that needs unwrapping, it now returns a list directly.

Before (7.0):

final result = await iap.fetchProducts(
skus: ['product_id'],
type: ProductQueryType.InApp,
);

if (result is FetchProductsResultProducts) {
final products = result.value ?? [];
for (final product in products) {
print('${product.title}: ${product.displayPrice}');
}
}

After (7.1):

final List<Product> products = await iap.fetchProducts(
skus: ['product_id'],
type: ProductQueryType.InApp,
);

for (final product in products) {
print('${product.title}: ${product.displayPrice}');
}

Key Benefits

  1. Simpler API: No more union type unwrapping with .value or checking is FetchProductsResultProducts
  2. Cleaner Code: Direct iteration over products without intermediate steps
  3. Type Safety: Explicit type annotations provide full IDE support and compile-time safety
  4. Better DX: More intuitive API that's easier to learn and use

Type Annotations

To get proper type inference, use explicit type annotations on the variable:

// In-app products
final List<Product> products = await iap.fetchProducts(
skus: ['coins_100', 'remove_ads'],
type: ProductQueryType.InApp,
);

// Subscriptions
final List<ProductSubscription> subscriptions = await iap.fetchProducts(
skus: ['premium_monthly', 'premium_yearly'],
type: ProductQueryType.Subs,
);

// All products (both in-app and subscriptions)
final List<ProductCommon> allProducts = await iap.fetchProducts(
skus: ['coins_100', 'premium_monthly'],
type: ProductQueryType.All,
);

Migration from 7.0

Migrating from 7.0 to 7.1 is straightforward:

// 7.0: Unwrap union type
final result = await iap.fetchProducts(
skus: productIds,
type: ProductQueryType.InApp,
);
final products = result.value ?? [];

// 7.1: Direct list with explicit type
final List<Product> products = await iap.fetchProducts(
skus: productIds,
type: ProductQueryType.InApp,
);

Breaking Changes

fetchProducts Return Type

  • Before: Returns Future<FetchProductsResult> (union type)
  • After: Returns Future<List<dynamic>> (requires explicit type annotation)

Required Changes

  1. Add explicit type annotation to variable declarations
  2. Remove .value or .products getter calls
  3. Remove union type checks (is FetchProductsResultProducts)

Full Example

Here's a complete example showing the new API:

import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';

class ProductStore {
final _iap = FlutterInappPurchase.instance;

Future<void> loadProducts() async {
// Initialize connection
await _iap.initConnection();

// Load in-app products
final List<Product> inAppProducts = await _iap.fetchProducts(
skus: ['coins_100', 'coins_500', 'remove_ads'],
type: ProductQueryType.InApp,
);

// Load subscriptions
final List<ProductSubscription> subscriptions = await _iap.fetchProducts(
skus: ['premium_monthly', 'premium_yearly'],
type: ProductQueryType.Subs,
);

// Use products directly
for (final product in inAppProducts) {
print('${product.id}: ${product.displayPrice}');
}

for (final sub in subscriptions) {
print('${sub.id}: ${sub.displayPrice}');
}
}
}

Why This Change?

The previous union type approach (introduced in 7.0) provided strong type safety but added unnecessary complexity for most use cases. User feedback (#576) showed that:

  1. The union type unwrapping felt verbose and boilerplate-heavy
  2. Type inference didn't work as expected with for-in loops
  3. The API was harder to learn for new users

Version 7.1 strikes a better balance by:

  • Keeping type safety through explicit annotations
  • Simplifying the common case (direct iteration)
  • Reducing boilerplate code
  • Maintaining full compatibility with the OpenIAP specification

Documentation

All documentation has been updated to reflect the new API:

Version 7.0 documentation is still available in the version dropdown.

Credits

Special thanks to @matifdeveloper for reporting the type inference issue in #576.

What's Next?

We continue to focus on:

  • OpenIAP specification compliance
  • Better developer experience
  • Comprehensive documentation
  • Community feedback and improvements

Try out 7.1.0 and let us know your feedback!

dependencies:
flutter_inapp_purchase: ^7.1.0