The Set of code generators reduce boilerplate code writing.
Add dependencies to your pubspec.yaml
dependencies:
boilerplate_annotations:
dev_dependencies:
boilerplate_generators:
build_runner:
The code generator for copyWith and copyWithNull methods generation supports deep copy and field ignoring.
- Annotate a class with the @copyWith annotation
- Add a part file - part 'your_file_name.g.dart'
- Run the build_runner.
Methods copyWith, and copyWithNull will be generated.
part 'address.g.dart';
@copyWith
class Address {
final String? street;
final int? home;
const Address({this.street, this.home});
}
If you want to disable the copyWithNull method generation, pass "copyWithNull = false" to the CopyWith annotation.
@CopyWith(copyWithNull: false)
class Address {
final String? street;
final int? home;
const Address({this.street, this.home});
}
The copyWith method rejects null.
@copyWith
class Payment {
final int id;
final String? description;
const Payment({required this.id, this.description});
}
const payment = Payment(id: 4, description: 'test',);
print(payment.copyWith(description: null)); // Payment(id:4, description: test)
The copyWithNull method allows a copy with a null value.
@copyWith
class Payment {
final int id;
final String? description;
const Payment({required this.id, this.description});
}
const payment = Payment(id: 4, description: 'test',);
print(payment.copyWithNull(description: null)); // Payment(id:4, description: null)
With deep copy support, you can call copyWith and copyWithNull methods of objects that a class contains and get a new instance of a class with an updated object. A class and objects that a class contains must be annotated with the @copyWith annotation.
@copyWith
class Payment {
final int id;
final String? description;
final Customer? customer;
const Payment({required this.id, this.customer, this.description});
}
@copyWith
class Customer {
final int id;
final String name;
final String surname;
final String? patronymic;
const Customer({
required this.id,
required this.name,
required this.surname,
this.patronymic,
});
}
const payment = Payment(
id: 4,
customer: Customer(
id: 1,
name: 'John',
surname: 'Dou',
),
);
print(payment.copyWith.customer!(name: 'Bob')); // Payment(id: 4, customer: Customer(id: 1,name: 'Bob',surname: 'Dou'))
If you want a class field to be excluded from copyWith and copyWithNull methods generation, you need to annotate this field with the @copyWithExclude annotation. In this case, it will be impossible to change this field with these methods.
@copyWith
class Payment {
@copyWithExclude
final int id;
final String? description;
final Customer? customer;
const Payment({required this.id, this.customer, this.description});
}
The code generator generates equatable props.
- Annotate a class with the @props annotation
- Add a part file - part 'your_file_name.g.dart'
- Override the props getter to return the _${your class name}Props(this);
- Run the build_runner.
Generated props will contain all final class fields.
part 'address.g.dart';
@props
class Address extends Equatable {
final String? street;
final int? home;
const Address({this.street, this.home});
}
@override
List<Object?> get props => _$AddressProps(this);
}
If your class extends from another class that uses Equatable, you need to add props from a superclass. You need to pass superclass props to the superProps parameter.
@props
class First extends Equatable {
final String data;
First(this.data);
@override
List<Object?> get props => _$FirstProps(this);
}
@props
class Second extends First {
final String second;
Second(this.second, String data) : super(data);
@override
List<Object?> get props => _$SecondProps(this, superProps: super.props);
}
If you want a class field to be excluded from props generation, you need to annotate this field with the @propsExclude annotation. In this case, props will not contain this field.
@props
class Address extends Equatable {
@propsExclude
final String? street;
final int? home;
const Address({this.street, this.home});
}
@override
List<Object?> get props => _$AddressProps(this);
}