I have an abstract class A:
abstract class A {
Future<String> firstMethod();
}
and I implemented this abstract class:
class Aimp implements A {
#override
Future<String> firstMethod() async {
return "test";
}
}
I have created another abstract class:
abstract class B extends A {
Future<String> secondMethod();
}
and I implemented this abstract class:
class Bweb extends B {
#override
Future<Object> secondMethod() async {
final t = //I want to call firstMethod()
if(t.isNotEmpty()) // do sth
}
}
In the implementation of secondMethod(), how can I call the implementation of firstMethod()?
I don't want to use mixin.
I try to use with instead:
abstract class A {
Future<String> firstMethod();
}
class Aimp implements A {
#override
Future<String> firstMethod() async {
return "test";
}
}
abstract class B with Aimp {
Future<String> secondMethod();
}
class Bweb extends B {
#override
Future<String> secondMethod() async {
final String t = await firstMethod(); //Your firstMethod function
if(t.isNotEmpty) {
return t;
}
return '';
}
}
Then you need an object of Aimp class item as a field of Bweb class. Or place A class as a field for the B one.
Related
I have an abstract class written in Dart, that not only contains abstract method but also contains concrete methods like below:
abstract class Person {
void speak();
Foot getFoot();
void walk() {
getFoot().move();
}
}
class Foot {
void move() {
}
}
Test:
class MockPerson extends Person {
#override
Foot getFoot() {
return Foot();
}
#override
void speak() {
}
}
void main() {
late MockPerson sut;
setUp(() {
sut = MockPerson();
});
test('test walk', () {
/// ??
});
}
I tried to created mock of Person to be able to test against it. But I'm not sure how can I write unit test for walk() method?
I am trying to find solution to manage async queries. For example, i have internet shop and i want to update all products and categories when city is changed. And i don't want to keep all async logic on ui. In order to achieve this result, i've created this bloc:
class AppEvent {
String message;
AppEvent({this.message = ''});
}
class EventsBlock extends Bloc<AppEvent, AppEvent> {
EventsBlock() : super(AppEvent());
#override
Stream<AppEvent> mapEventToState(AppEvent event) async* {
yield event;
}
}
final events = EventsBlock();
Then, i can use it like this:
class CityCubit() {
CityCubit() : super(CityState());
Future<void> changeCity() async {
await api.changeCity();
events.add(AppEvent(message: 'cityChanged'));
}
}
class CategoryCubit extends Cubit<CategoryState> {
CategoryCubit() : super(CategoryEmptyState()) {
events.stream.listen((e) {
if(e.message == 'cityChanged') {
fetchCategories();
}
});
};
Future<void> fetchCategories() async {
//fetch categories
}
}
class ProductCubit extends Cubit<ProductState> {
ProductCubit() : super(ProductEmptyState()) {
events.stream.listen((e) {
if(e.message == 'cityChanged') {
fetchProducts();
}
});
};
Future<void> fetchProducts() async {
//fetch products
}
}
It's something like eventBus pattern. But i am not sure that it's a correct way to use bloc. I've tried to use redux + redux saga, but it has a lot of boilerplate and i believe that flutter has better solution to manage things like that.
Your general idea is ok, but I can't see a real need for the EventsBloc class. In fact, it is kinda strange that you use the same class for the events and for the states of this bloc, and simply yield the event you receive. It's like EventsBloc could be a simple stream.
Here's a way to go, turning CityCubit into an actual bloc (and also with some error handling, which is something you can do gracefully with bloc):
abstract class CityState {}
class CityInitial extends CityState {}
class CityLoadingCities extends CityState {}
class CityCitiesLoaded extends CityState {}
class CityLoadError extends CityState {}
abstract class CityEvent {}
class CityLoadCities extends CityEvent {}
class CityBloc<CityEvent, CityState> {
CityBloc() : super(CityInitial());
#override
Stream<AppEvent> mapEventToState(CityEvent event) async* {
if(event is CityLoadCities) {
yield CityLoadingCities();
try {
await api.changeCity();
yield CityCitiesLoaded();
} catch (error) {
yield CityLoadError();
}
}
}
void changeCity() {
add(CityLoadCities());
}
}
Now you can do this inside any other bloc:
instanceOfCityBloc.listen((cityState) {
if(cityState is CityCitiesLoaded){
// do stuff
}
});
I ended up with this code:
class CityChangedEvent {
int cityId;
CityChangedEvent(this.cityId);
}
EventBus eventBus = EventBus();
mixin EventBusMixin {
StreamSubscription<T> listenEvent<T>(void Function(T) subscription) =>
eventBus.on<T>().listen(subscription);
void shareEvent<S>(S event) => eventBus.fire(event);
}
class CityCubit extends CityCubit<CityState> with EventBusMixin {
CityCubit() : super(CityInitialState());
Future<void> changeCity(cityId) async {
try {
emit(ChangeCityLoadingState());
final result = await api.changeCity(cityId);
if(result.success) {
emit(ChangeCitySuccessState());
shareEvent(CityChangedEvent(cityId));
}
} catch (_) {
emit(ChangeCityErrorState());
}
}
}
class CategoryCubit extends Cubit<CategoryState> with EventBusMixin {
CategoryCubit() : super(CategoryEmptyState()) {
listenEvent<CityChangedEvent>((e) {
fetchCategories(e.cityId);
);
}
Future<void> fetchCategories(cityId) async {
try {
emit(CategoryLoadingState());
final categoriesList = await fetchCategoriesApi();
emit(CategoryLoadedState(categories: categoriesList));
} catch (_) {
emit(CategoryErrorState());
}
}
}
Now, i can communicate between blocs without the need to instantiate or inject their instances. Thanks to this library https://pub.dev/packages/event_bus
i'm new to flutter i can't get the constructor to work which is in comment,
but the other constructor works, why? thank you
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
child: ImageEditor()
// child: PhotoView(imageProvider: AssetImage("Assets/img/carte.png"),)
);
}
}
class ImageEditor extends PhotoView {
// ignore: missing_required_param
ImageEditor():super(imageProvider: AssetImage("Assets/img/carte.png"),){
init();
}
//ImageEditor(){
// super(imageProvider: AssetImage("Assets/img/carte.png"),);
// init()
// }
void init(){
if(imageProvider!=null) {
print("il y a peut etre moyen de dessiner sur l'image");}
}
}
This is what you call a super constructor.
ImageEditor():super(imageProvider: AssetImage("Assets/img/carte.png")){
init();
}
Normally, a subclass can inherit all the variables and function from the parent class(using the extends) keyword, but you cannot access its constructor.
Using the : super() argument, you can however call the constructor from the parent class. You can only do it that way, that is simply the syntax.
Example:
class Class1 {
Class1(String name) {
print("Hello $name");
}
}
class Class2 extends Class1 {
Class2() : super("Tom") { //the name from above
print("Hello World");
}
}
void main() {
Class2 test = new Class2();
}
The output would be(in that order):
Hello Tom
Hello World
I am trying to make multiple Controller Types foo multiple Models for use with Provider in Flutter.
This is my Code:
//generic controller
class ModelController<E extends HiveObject> extends ChangeNotifier {
Box<E> _db;
ModelController(Box<E> db) {
_db = db;
}
// getters
List<E> get all => _db.values;
// create
void add(E item) {
_db.add(item);
notifyListeners();
}
void update(E item) {
item.save();
notifyListeners();
}
// delete
void delete(E item) {
item.delete();
notifyListeners();
}
}
class PacketController extends ModelController<Packet>{
PacketController(Box<Packet> db) : super(db);
}
The code for class PacketController is the only way I found to create a concrete type from a generic one.
Question:Is there a better way for this?
Shortly, I am looking for something like typedef in c++:
typedef IntVector std::vector<int>
I have class that process data. I have two options.
1. To registration it as Provider directly:
class GetServerData extends ChangeNotifier
{
String resultDate;
getData() {
resultDate = http.get(...);
notifyListeners();
}
}
Сreate wrapper-provider class. And use it as Provider.
class ServerDataProvider extends ChangeNotifier {
String resultDate;
GetServerData getServerData = GetServerData();
getData() {
resultDate = getServerData.getData();
notifyListeners();
}
}
When I should prefer to use first variant and when second?