i'm trying to display a list of data in my home page , but i have an issue with my flow that i have imlpemented to achive this feature : error:
_debugCurrentlyBuildingElement == this': Providers are not allowed to modify other providers during their initialization.
E/flutter ( 4358):
E/flutter ( 4358): The provider AutoDisposeFutureProvider<List<Parking>>#e44aa modified StateNotifierProvider<ParkingNotifier, ParkingState>#a7361 while building.
E/flutter ( 4358):
my flow: ui where i want to display a list of data :
@RoutePage()
class HomeScreen extends ConsumerWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, ref) {
final AppLocalizations? appLocalizations = AppLocalizations.of(context);
final parkingDataProvider = FutureProvider.autoDispose<List<Parking>>((ref) async {
final parkingNotifier = ref.read(parkingNotifierProvider.notifier);
return parkingNotifier.getParkings();
});
final parkingState = ref.watch(parkingNotifierProvider);
final parkingsAsyncValue = ref.watch(parkingDataProvider);
return Scaffold(
body: CustomScrollView(
slivers: [
const HomeAppBar(),
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 19.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 18),
const Text(
'Parking List',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16.0),
if (parkingState is ParkingLoaded)
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: parkingState.parkings.length,
shrinkWrap: true,
itemBuilder: (context, index) {
final parking = parkingState.parkings[index];
return Padding(
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(19),
right: ScreenUtil().setWidth(19),
bottom: ScreenUtil().setHeight(8),
top: ScreenUtil().setHeight(5),
),
child: GestureDetector(
onTap: () {},
child: Container(
width: ScreenUtil().setWidth(352),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.15),
offset: Offset(-1, 1),
blurRadius: 6,
spreadRadius: 2,
),
],
),
child: Row(
children: [
Flexible(
flex: 1,
child: Padding(
padding: EdgeInsets.only(
left: 8.0.w,
top: 8.h,
bottom: 8.h),
child: Container(
height: ScreenUtil().setHeight(85),
width: ScreenUtil().setWidth(85),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(15.r),
image: parking.images!.isNotEmpty
? DecorationImage(
//image from the server
: DecorationImage(
image: AssetImage(
'assets/images/parking.png',
),
fit: BoxFit.cover,
),
),
),
),
),
Flexible(
flex: 2,
child: Padding(
padding: EdgeInsets.only(
left: 8.0.h,
top: 12.h,
bottom: 12.h),
child: Column(
children: [
Row(
children: [
AutoSizeText(
parking.parkingName!
.toString(),
style: TextStyle(
fontFamily: 'Poppins',
fontWeight:
FontWeight.w500,
overflow:
TextOverflow.ellipsis,
fontSize: ScreenUtil()
.setSp(14),
),
),
],
),
SizedBox(
height: 30.h,
child: Marquee(
text: parking.adress!,
style: TextStyle(
fontFamily: 'Poppins',
color: AppColors.greyColor,
fontWeight: FontWeight.w500,
fontSize:
ScreenUtil().setSp(12),
),
scrollAxis: Axis.horizontal,
crossAxisAlignment:
CrossAxisAlignment.start,
blankSpace: 20.0,
velocity:
30.0, // Adjust the scrolling speed
pauseAfterRound:
Duration(seconds: 1),
startPadding: 10.0,
),
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Center(
child: Text(
"4km"
/* parking.location ==
""
? "--"
: _selectedParkingDistance =
_formatDistance(
distance)*/
,
style: TextStyle(
fontFamily: 'Poppins',
color: AppColors
.primaryColor,
fontSize: ScreenUtil()
.setSp(14),
fontWeight:
FontWeight.w500),
),
),
/* FittedBox(
child: Text(
parking.grille!.isEmpty
? appLocalizations!
.not_available
: appLocalizations!
.available,
style: TextStyle(
fontFamily: 'Poppins',
color: parking
.grille!.isEmpty
? Colors.red
: AppColors
.greenColor,
fontWeight:
FontWeight.w400,
fontSize: ScreenUtil()
.setSp(11),
),
),
)*/
],
),
],
),
),
),
],
),
),
),
);
},
),
],
),
),
),
],
),
);
}
}
lib/presentation/providers/parkings_provider.dart:
import 'package:effia_park/domain/providers/parking_provider.dart';
import 'package:effia_park/presentation/providers/state/parking_states/parking_state.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'state/parking_states/parking_notifier.dart';
final parkingNotifierProvider = StateNotifierProvider<ParkingNotifier, ParkingState>((ref) {
final getParkingsUseCases = ref.read(getParkingsDataUseCaseProvider);
return ParkingNotifier(getParkingsUseCases);
});
lib/presentation/providers/state/parking_states/parking_notifier.dart:
import 'package:effia_park/domain/usecases/parking/get_parks_use_case.dart';
import 'package:effia_park/shared/models/parking/parking.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive/hive.dart';
import '../../../../shared/use_case.dart';
import 'parking_state.dart';
class ParkingNotifier extends StateNotifier<ParkingState> {
final GetParkUsecases _getParkingUseCases;
// final Box _hiveBox;
ParkingNotifier(this._getParkingUseCases)
: super(const ParkingState.initial());
Future<List<Parking>> getParkings() async {
state = const ParkingState.loading();
final result = await _getParkingUseCases.call(NoParams());
return result.fold(
(failure) {
state = ParkingState.failure(failure);
throw failure; // Throw the exception to handle it outside
},
(parkings) {
state = ParkingState.loaded(parkings: parkings);
return parkings;
},
);
}
}
lib/presentation/providers/state/parking_states/parking_state.dart:
import 'package:effia_park/infrastructure/exceptions/http_exception.dart';
import 'package:effia_park/shared/models/parking/parking.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'parking_state.freezed.dart';
@freezed
abstract class ParkingState with _$ParkingState {
const factory ParkingState.initial() = Initial;
const factory ParkingState.loading() = Loading;
const factory ParkingState.loaded({required List<Parking> parkings}) = ParkingLoaded;
const factory ParkingState.failure(AppException exception) = Failure;
const factory ParkingState.success() = Success;
}
lib/domain/usecases/parking/get_parks_use_case.dart:
import 'package:effia_park/domain/repositories/parking_repository.dart';
import 'package:effia_park/infrastructure/either.dart';
import 'package:effia_park/shared/models/parking/parking.dart';
import '../../../infrastructure/exceptions/http_exception.dart';
import '../../../shared/use_case.dart';
class GetParkUsecases implements UseCase<List<Parking>, NoParams> {
final ParkingRepository parkingRepository;
GetParkUsecases(this.parkingRepository);
@override
Future<Either<AppException, List<Parking>>> call(noParams) async {
return await parkingRepository.getParks();
}
}
lib/domain/repositories/parking_repository.dart:
import 'package:effia_park/infrastructure/exceptions/http_exception.dart';
import 'package:effia_park/shared/models/parking/parking.dart';
import '../../infrastructure/either.dart';
abstract class ParkingRepository {
Future<Either<AppException, List<Parking>>> getParks();
}
lib/domain/providers/parking_provider.dart:
import 'package:effia_park/data/datasources/parking_data_source/parking_remote_data_source.dart';
import 'package:effia_park/data/repositories/parking_repository_impl.dart';
import 'package:effia_park/domain/repositories/parking_repository.dart';
import 'package:effia_park/domain/usecases/parking/get_parks_use_case.dart';
import 'package:effia_park/infrastructure/network_service.dart';
import 'package:effia_park/infrastructure/providers/network_service_provider.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final parkingdatasourceProvider = Provider.family<ParkingRemoteDataSource, NetworkService>(
(_, networkService) => ParkingRemoteDataSource(networkService),
);
final parkinRepositoryProvider = Provider<ParkingRepository>((ref) {
final networkService = ref.watch(networkServiceProvider);
final datasource = ref.watch(parkingdatasourceProvider(networkService));
// final localDataSource = ref.watch(parkingLocalDataSourceProvider);
final repository = ParkingRepositoryImpl(remoteDataSource: datasource/*,localDataSource:localDataSource*/);
return repository;
});
final getParkingsDataUseCaseProvider = Provider<GetParkUsecases>((ref) {
return GetParkUsecases(ref.read(parkinRepositoryProvider));
});
lib/data/repositories/parking_repository_impl.dart:
import 'package:effia_park/data/datasources/parking_data_source/parking_remote_data_source.dart';
import 'package:effia_park/domain/repositories/parking_repository.dart';
import 'package:effia_park/infrastructure/either.dart';
import 'package:effia_park/infrastructure/exceptions/http_exception.dart';
import 'package:effia_park/shared/models/parking/parking.dart';
class ParkingRepositoryImpl implements ParkingRepository {
final ParkingRemoteDataSource _remoteDataSource;
//final ParkingLocalDataSource _localDataSource;
ParkingRepositoryImpl({
required ParkingRemoteDataSource remoteDataSource,
}) : _remoteDataSource = remoteDataSource;
@override
Future<Either<AppException, List<Parking>>> getParks() async {
return await _remoteDataSource.getParks();
}
}
lib/data/datasources/parking_data_source/parking_remote_data_source.dart:
abstract class ParkingDataSource {
Future<Either<AppException, List<Parking>>> getParks();
}
class ParkingRemoteDataSource implements ParkingDataSource {
final NetworkService networkService;
ParkingRemoteDataSource(this.networkService);
@override
Future<Either<AppException, List<Parking>>> getParks() async{
try {
final eitherType = await networkService.get(
'endpoint-of-my-data',
);
return eitherType.fold(
(exception) {
return Left(exception);
},
(response) {
final parking = List<Parking>.from(response.data["Parkings"].map((x) => Parking.fromJson(x)).toList(),) ;
return Right(parking);
},
);
} catch (e) {
return Left(
AppException(
e.toString(),
message: e.toString(),
statusCode: 1,
identifier: '${e.toString()}\nparkingRemoteDataSource.getParks',
),
);
}
}
}
i'm trying to use a clean architecture with flutter_riverpod , and i get this issue on retrieving a list of data , it's not a complex feature , but i'm trying to mnage and use a best practices with providers and state management, any help ? and thanks a lot