Flutter_riverpod Providers are not allowed to modify other providers during their initialization

58 views Asked by At

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

0

There are 0 answers