dart_helper_utils 4.0.0-dev.3 copy "dart_helper_utils: ^4.0.0-dev.3" to clipboard
dart_helper_utils: ^4.0.0-dev.3 copied to clipboard

This package offers a collection of Dart utilities, tools for converting dynamic objects to various types, and extending core Dart classes with extensions.

dart_helper_utils logo

pub package

dart_helper_utils is a toolkit designed to make coding in Dart more convenient by offering utilities for pagination, type conversions, data manipulation, time measurements, HTTP status handling, and much more. We’ve bundled a wide range of extension methods and helper classes that let you write less code and focus on your app's core logic.

Note: If you’re working on a Flutter project, we recommend using flutter_helper_utils. It includes everything you’ll find here, plus Flutter-specific extensions like widgets and color utilities.


Why Use dart_helper_utils? #

We initially created dart_helper_utils to gather all those tiny, repetitive tasks that pop up in Dart projects—think date parsing, JSON decoding, or pagination. Over time, we introduced more powerful features like infinite scrolling, advanced string transformations, numeric calculations, and user-friendly HTTP status messages. The result is a collection of robust, well-tested utilities that you can easily slot into your own Dart applications.

1. Parsing Dynamic JSON Data #

Before:

Map<String, dynamic> parseUser(Map<String, dynamic> json) {
  final result = <String, dynamic>{};
  
  // Manually checking and converting each field
  if (json['name'] != null && json['name'] is String) {
    result['name'] = json['name'];
  }
  
  if (json['age'] != null) {
    final age = int.tryParse(json['age'].toString());
    if (age != null) {
      result['age'] = age;
    }
  }
  
  return result;
}
copied to clipboard

After:

Map<String, dynamic> parseUser(Map<String, dynamic> json) {
	// json.getString('key')
  return {
    'name': json.getString('name'),
    'age': json.getInt('age'),
  };
}
copied to clipboard

2. Date Handling

Before:

bool isDateValid(DateTime? date) {
  if (date == null) return false;
  final now = DateTime.now();
  return date.year == now.year && 
         date.month == now.month && 
         date.day == now.day;
}
copied to clipboard

After:

bool isDateValid(DateTime? date) {
  return date?.isToday ?? false;
}
copied to clipboard

3. Duration Delays

Before:

await Future<void>.delayed(const Duration(seconds: 3));
copied to clipboard

After:

await 3.secondsDelay();
copied to clipboard

4. HTTP Status Handling

Before:

String getErrorMessage(int statusCode) {
  switch (statusCode) {
    case 429:
      return 'Too many requests. Please wait before trying again.';
    case 404:
      return 'Resource not found. Please check the URL.';
    case 500:
      return 'Server error. Please try again later.';
    default:
      return 'An error occurred.';
  }
}
copied to clipboard

After:

String getErrorMessage(int statusCode) {
  return statusCode.toHttpStatusUserMessage;
}
copied to clipboard

Getting Started #

Installation #

Add this to your pubspec.yaml:

dependencies:
  dart_helper_utils: ^4.0.0
copied to clipboard

Then run:

dart pub get   # For Dart projects
# or
flutter pub get # For Flutter projects
copied to clipboard

Basic Usage #

Import the package:

import 'package:dart_helper_utils/dart_helper_utils.dart';
copied to clipboard

Start using the extensions and utilities:

// String operations
final text = "hello_world_example";
print(text.toCamelCase());  // "helloWorldExample"

// Safe number conversion
final value = "123.45".tryToDouble() ?? 0.0;

// Date handling
final date = DateTime.now();
print(date.isToday);  // true
print(date.format("dd/MM/yyyy"));  // "16/01/2025"

// Collection utilities
final list = [1, 2, null, 3, null, 4];
print(list.whereNotNull());  // [1, 2, 3, 4]
copied to clipboard

Extensions Deep Dive #

Date & Time Extensions #

final date = DateTime.now();

// Quick checks
print(date.isToday);         // true
print(date.isTomorrow);      // false
print(date.isWeekend);       // depends on the date

// Navigation
final nextWeek = date.nextWeek;
final lastDayOfMonth = date.lastDayOfMonth;
final startOfDay = date.startOfDay;

// Formatting
print(date.format('dd/MM/yyyy'));           // "16/01/2025"
print(date.httpFormat);                     // "Thu, 16 Jan 2025 00:00:00 GMT"

// Comparisons
final other = DateTime(2024, 1, 1);
print(date.isAtSameYearAs(other));         // false
print(date.isAtSameMonthAs(other));        // true
print(date.passedDays);                    // Days since date
print(date.remainingDays);                 // Days until date
copied to clipboard

Collection Extensions #

Iterable

final numbers = [1, 2, null, 3, null, 4];

// Safe operations
print(numbers.firstOrNull);                // 1
print(numbers.lastOrDefault(0));           // 4
print(numbers.whereNotNull());             // [1, 2, 3, 4]

// Aggregation
final products = [
  Product(price: 10),
  Product(price: 20),
];
print(products.totalBy((p) => p.price));   // 30
copied to clipboard

Map

final map = {'a': 1, 'b': 2, 'nested': {'x': 10}};

// Safe operations
print(map.getString('key', defaultValue: ''));
print(map.getInt('a'));                     // 1
print(map.getInt('nested', innerKey: 'x')); // 10

// Transformations
final filtered = map.filter((k, v) => v is int);
final flattened = map.flatMap();            // Flattens nested maps
copied to clipboard

List

final list = [1, 2, 3, 4, 5];

// List operations
print(list.halfLength);                    // 2
print(list.firstHalf);                     // [1, 2]
print(list.secondHalf);                    // [3, 4, 5]
final swapped = list.swap(0, 1);           // [2, 1, 3, 4, 5]
copied to clipboard

Number Extensions #

// Duration conversions
await 5.secondsDelay;                      // Delays execution
final duration = 30.minutes;               // Duration object

// HTTP status helpers
print(200.isSuccessCode);                  // true
print(404.isNotFoundError);                // true
print(429.statusCodeRetryDelay);           // Suggested retry duration

// Numeric operations
print(5.factorial);                        // 120
print(25.sqrt());                          // 5.0
print(10.isBetween(5, 15));               // true
copied to clipboard

String Extensions #

final text = "Hello, World!";

// Validation
print("test@email.com".isValidEmail);      // true
print("192.168.1.1".isValidIp4);          // true
print("Hello123".isAlphanumeric);          // true

// Manipulation
print(text.replaceAfter(",", ""));         // "Hello"
print("  text  ".removeWhiteSpaces());     // "text"
print("multi\nline".toOneLine());          // "multi line"

// Null safety
final nullableText = null;
print(nullableText.orEmpty);               // ""
print("".ifEmpty(() => "default"));        // "default"
copied to clipboard

Core Features #

Pagination #

Three powerful pagination implementations to handle any scenario:

Key Features:

  • Built-in caching with expiration checks
  • Automatic retry handling for failed requests
  • Race condition prevention for async operations
  • Optional analytics tracking for performance monitoring
  • Support for both page-based and cursor-based pagination
// 1. Sync pagination for in-memory lists
final paginator = Paginator(
  items: myItems,
  pageSize: 10,
);

// 2. Async pagination with automatic retries
final asyncPaginator = AsyncPaginator<User>(
  fetchPage: (pageNumber, pageSize) => api.fetchUsers(pageNumber, pageSize),
  pageSize: 20,
  autoCancelFetches: true,  // Prevents race conditions
);

// 3. Infinite scrolling with cursor-based pagination
final infinitePaginator = InfinitePaginator.cursorBased(
  fetchItems: (pageSize, cursor) => api.fetchItems(pageSize, cursor),
  getNextCursor: (items) => items.last.id,
);

// Add analytics tracking to any paginator
final trackedPaginator = paginator with PaginationAnalytics<Item>();
copied to clipboard

String Similarity & Text Operations #

Powerful text manipulation tools including case conversion and similarity checks:

// Case conversions
final text = "helloWorld_example-TEXT";
print(text.toPascalCase());           // HelloWorldExampleText
print(text.toSnakeCase());            // hello_world_example_text
print(text.toKebabCase());            // hello-world-example-text
print(text.toScreamingSnakeCase());   // HELLO_WORLD_EXAMPLE_TEXT

// String similarity checks
final str1 = "hello";
final str2 = "hallo";

// Different algorithms available
final similarity = str1.compareWith(
  str2, 
  algorithm: StringSimilarityAlgorithm.levenshtein
);
print(similarity); // 0.8

// Words extraction (smarter than simple split)
print("FlutterAndDart_are-AWESOME".toWords);
// [Flutter, And, Dart, are, AWESOME]
copied to clipboard

Type-Safe Conversions #

Safe extraction and conversion of values from dynamic data:

// Safe JSON parsing
final jsonStr = '{"name":"John","age":"25","scores":[90,85,95]}';
final map = jsonStr.decode();

// Type-safe extractions
final name = map.getString('name');      // "John"
final age = map.getInt('age');           // 25
final scores = map.getList<int>('scores');  // [90, 85, 95]

// Nested extractions
final userData = {
  'user': {
    'details': {
      'address': {'zipcode': '12345'}
    }
  }
};

// Safe nested access with fallback
final zipcode = userData.getInt(
  'user', 
  innerKey: 'details.address.zipcode',
  defaultValue: 0
); // 12345

// Complex conversions
final date = "2024-01-16".toDateTime(format: "yyyy-MM-dd");
final number = "1,234.56".toNum(format: "#,##0.00");
copied to clipboard

Time & Execution Utils #

Comprehensive utilities for measuring and controlling execution time:

// Measure execution duration
final duration = await TimeUtils.executionDuration(() async {
  await someExpensiveOperation();
});
print("Operation took ${duration.inMilliseconds}ms");

// Run with timeout
try {
  final result = await TimeUtils.runWithTimeout(
    task: () => longRunningTask(),
    timeout: Duration(seconds: 5),
  );
} catch (e) {
  print('Task timed out');
}

// Throttle function calls
final throttled = TimeUtils.throttle(
  duration: Duration(seconds: 1),
  function: () => print('Throttled function called'),
);

// Run periodic tasks
final subscription = TimeUtils.runPeriodically(
  interval: Duration(minutes: 1),
  task: () => checkForUpdates(),
);

// Clean up when done
subscription.cancel();
copied to clipboard

Each utility focuses on making common programming tasks more manageable while providing type safety and proper error handling.

Extensions Deep Dive #

Date & Time Extensions #

Simplify date operations and comparisons:

final date = DateTime.now();

// Quick comparisons
print(date.isToday);         // true
print(date.isTomorrow);      // false
print(date.isYesterday);     // false
print(date.isWeekend);       // depends on the date

// Navigation
final nextWeek = date.nextWeek;
final prevMonth = date.previousMonth;
final startOfDay = date.startOfDay;
final endOfMonth = date.endOfMonth;

// Duration calculations
final otherDate = DateTime(2025, 12, 31);
print(date.remainingDays(otherDate));    // days until otherDate
print(date.passedDays(otherDate));       // days since otherDate

// Formatting
print(date.format('dd/MM/yyyy'));        // "16/01/2025"
print(date.httpFormat);                  // "Thu, 16 Jan 2025 00:00:00 GMT"

// Age calculation
final birthDate = DateTime(1990, 1, 1);
print(birthDate.calculateAge());         // 35 (as of 2025)
copied to clipboard

Collections Extensions #

Powerful extensions for Lists, Maps, and Sets:

// List Extensions
final list = [1, 2, null, 3, null, 4];
print(list.whereNotNull());              // [1, 2, 3, 4]
print(list.firstOrDefault(0));           // 1
print(list.distinctBy((e) => e));        // [1, 2, null, 3, 4]

// Splitting lists
print(list.firstHalf);                   // [1, 2, null]
print(list.secondHalf);                  // [3, null, 4]

// Map Extensions
final map = {'name': 'John', 'scores': [85, 90, 95]};

// Safe extractions with defaults
final name = map.getString('name', defaultValue: 'Unknown');
final scores = map.getList<int>('scores', defaultValue: []);

// Manipulation
map.setIfMissing('email', 'default@email.com');
final filtered = map.filter((key, value) => value != null);

// Set Extensions
final set = {1, 2, 3};
set.addIfNotNull(4);                     // Adds only if not null
set.removeWhere((e) => e.isEven);        // Removes even numbers

// Common Iterable Extensions
final items = [1, 2, 3, 4, 5];
print(items.total);                      // Sum: 15
print(items.tryGetRandom());             // Random element or null
copied to clipboard

Numbers & Math Extensions #

Enhanced numeric operations and conversions:

// Basic Operations
final num = 123.456;
print(num.roundToNearest(5));           // 125
print(num.isBetween(100, 200));         // true

// Numeric Checks
print(42.isPrime);                      // false
print(16.isPerfectSquare);              // true
print(8.isPerfectCube);                 // true

// Currency and Formatting
final price = 1234567.89;
print(price.formatAsCurrency());        // "$1,234,567.89"
print(price.formatAsCompact());         // "1.2M"
print(price.asGreeks);                  // "1.23M"

// Time Conversions
await 5.secondsDelay();                   // Delays for 5 seconds
final duration = 30.asMinutes;            // Duration of 30 minutes

// HTTP Status Helpers
print(200.isSuccessCode);              // true
print(404.isNotFoundError);            // true
print(429.statusCodeRetryDelay);       // Suggested retry duration
copied to clipboard

String Extensions #

Rich text manipulation and validation:

// Smart Case Conversions
final text = "helloWorld_example-TEXT";
print(text.toPascalCase());             // HelloWorldExampleText
print(text.toSnakeCase());              // hello_world_example_text
print(text.toDotCase());                // hello.world.example.text

// Validation
print("test@email.com".isValidEmail);   // true
print("192.168.1.1".isValidIp4);        // true
print("https://dart.dev".isValidUrl);   // true

// Text Manipulation
print("  hello  world  ".removeWhiteSpaces());  // "helloworld"
print("hello".padCenter(10, '*'));      // "**hello***"

// Safe Operations
final nullableText = null;
print(nullableText.orEmpty);            // ""
print("".ifEmpty(() => "default"));     // "default"

// JSON Handling
final jsonStr = '{"key": "value"}';
print(jsonStr.decode());                // Map<String, dynamic>
print(jsonStr.tryDecode());             // Returns null if invalid
copied to clipboard

HTTP Status Extensions #

Clean and informative HTTP status handling:

final statusCode = 404;

// Status Checks
print(statusCode.isSuccessCode);        // false
print(statusCode.isNotFoundError);      // true
print(statusCode.isRetryableError);     // false

// User Messages
print(statusCode.toHttpStatusUserMessage);
// "The requested resource could not be found. Please check the URL and try again."

// Developer Messages
print(statusCode.toHttpStatusDevMessage);
// "Resource not found. Verify the path and parameters. Check if resource exists..."

// Retry Handling
if (statusCode.isRateLimitError) {
  final delay = statusCode.statusCodeRetryDelay;
  print("Retry after: ${delay.inSeconds} seconds");
}
copied to clipboard

Each extension is designed to make your code more readable and maintainable while reducing boilerplate and handling edge cases automatically.

Additional Utilities #

DoublyLinkedList #

A full-featured doubly linked list implementation with extensive operations:

// Create a list
final list = DoublyLinkedList<int>([1, 2, 3, 4]);

// Basic operations
list.append(5);         // Add to end
list.prepend(0);       // Add to start
list.insert(1, 15);    // Insert at position

// Node operations
for (final node in list.nodes) {
  print('Value: ${node.data}, '
        'Previous: ${node.prev?.data}, '
        'Next: ${node.next?.data}');
}

// Factory constructors
final filled = DoublyLinkedList.filled(3, 0);           // [0, 0, 0]
final generated = DoublyLinkedList.generate(3, (i) => i * 2);  // [0, 2, 4]

// Advanced operations
list.reverse();
list.removeNodesWhere((node) => node.data.isEven);
list.swapNodes(list.firstNode!, list.lastNode!);
copied to clipboard

Regular Expressions #

Pre-defined RegExp patterns for common validation scenarios:

// Common patterns
print(RegExp(alphanumericPattern).hasMatch('Test123'));    // true
print(RegExp(specialCharsPattern).hasMatch('Test@123'));   // true
print(RegExp(usernamePattern).hasMatch('user_123'));       // true
print(RegExp(phoneNumberPattern).hasMatch('+1234567890')); // true

// Validation using String extensions
print("test@email.com".isValidEmail);   // true
print("192.168.1.1".isValidIp4);        // true
print("https://dart.dev".isValidUrl);   // true
print("12345".isNumeric);               // true
print("abcDEF".isAlpha);                // true
copied to clipboard

Constants & Formats #

Built-in constants for common operations:

// Time Constants
print(oneSecond);              // Duration(seconds: 1)
print(oneMinute);              // Duration(minutes: 1)
print(oneHour);                // Duration(hours: 1)
print(oneDay);                 // Duration(days: 1)

// Milliseconds Constants
print(millisecondsPerSecond);  // 1000
print(millisecondsPerMinute);  // 60000
print(millisecondsPerHour);    // 3600000
print(millisecondsPerDay);     // 86400000

// Number Formats
print(greekNumberSuffixes);
// {
//   'K': 1000,
//   'M': 1000000,
//   'B': 1000000000,
//   'T': 1000000000000,
// }

// Calendar Constants
print(smallWeekdays);     // {1: 'Mon', 2: 'Tue', ...}
print(fullWeekdays);      // {1: 'Monday', 2: 'Tuesday', ...}
print(smallMonthsNames);  // {1: 'Jan', 2: 'Feb', ...}
print(fullMonthsNames);   // {1: 'January', 2: 'February', ...}

// Roman Numerals
print(romanNumerals);
// {1: 'I', 5: 'V', 10: 'X', 50: 'L', 100: 'C', 500: 'D', 1000: 'M'}
copied to clipboard

Contributing #

We love contributions! If you’d like to add a feature, report a bug, or suggest an improvement, open an issue or submit a pull request in the GitHub repository. We appreciate every piece of feedback and aim to make things smoother for everyone.


License #

dart_helper_utils is released under the BSD 3-Clause License. You’re free to use, modify, and distribute it as long as you comply with the license terms.

If this package saves you time or helps you ship faster, consider buying me a coffee. It goes a long way in helping maintain and improve these tools.

Buy Me A Coffee


Thank you for choosing dart_helper_utils. We hope it makes your next Dart project more enjoyable and efficient! If you run into any issues or have suggestions, don’t hesitate to reach out.


Keywords: extension pack, helpers, utilities, string manipulation, conversions, time utils, date extension, datetime helper, DateFormat, intl, extensions, iterable, map, number, object, set, URI, boolean extension, JSON encoding/decoding, parsing, safe parsing, object conversion, cast, list casting.

44
likes
0
points
888
downloads

Publisher

verified publishertomars.tech

Weekly Downloads

2024.05.30 - 2025.04.24

This package offers a collection of Dart utilities, tools for converting dynamic objects to various types, and extending core Dart classes with extensions.

Repository (GitHub)
View/report issues

Topics

#utils #utilities #helpers #extensions-pack #case-conversion

License

unknown (license)

Dependencies

async, intl, meta, mime

More

Packages that depend on dart_helper_utils