Skip to content

Commit

Permalink
Add base implementations for http request and pre-request, remove red…
Browse files Browse the repository at this point in the history
…undant user example
  • Loading branch information
michalina-majewska committed Jul 8, 2024
1 parent 14821ab commit ec552ad
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 92 deletions.
2 changes: 0 additions & 2 deletions packages/leancode_cubit_utils/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'package:provider/provider.dart';
class Routes {
static const home = '/';
static const simpleRequest = '/simple-request';
static const simpleRequestHook = '/simple-request-hook';
static const paginatedCubit = '/paginated-cubit';
}

Expand Down Expand Up @@ -90,7 +89,6 @@ class MainApp extends StatelessWidget {
routes: <String, WidgetBuilder>{
Routes.home: (_) => const HomePage(),
Routes.simpleRequest: (_) => const RequestScreen(),
Routes.simpleRequestHook: (_) => const RequestHookScreen(),
Routes.paginatedCubit: (_) => const PaginatedCubitScreen(),
},
);
Expand Down
57 changes: 30 additions & 27 deletions packages/leancode_cubit_utils/example/lib/pages/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,37 @@ import 'package:example/http/status_codes.dart';
import 'package:http/http.dart' as http;
import 'package:leancode_cubit_utils/leancode_cubit_utils.dart';

/// [PreRequestRun] and [RequestHandleResult] can be used repeatedly
/// in cubits handling http.
/// Base class for http request cubits.
abstract class HttpRequestCubit<TOut>
extends RequestCubit<http.Response, String, TOut, int> {
HttpRequestCubit(super.loggerTag, {required this.client});

mixin PreRequestRun<TData, TItem>
on PreRequest<http.Response, String, TData, TItem> {
final http.Client client;

@override
Future<RequestState<TOut, int>> handleResult(
http.Response result,
) async {
if (result.statusCode == StatusCode.ok.value) {
logger.info('Request success. Data: ${result.body}');
return RequestSuccessState(map(result.body));
} else {
logger.severe('Request error. Status code: ${result.statusCode}');
try {
return await handleError(RequestErrorState(error: result.statusCode));
} catch (e, s) {
logger.severe(
'Processing error failed. Exception: $e. Stack trace: $s',
);
return RequestErrorState(exception: e, stackTrace: s);
}
}
}
}

/// Base class for http pre-request use cases.
abstract class HttpPreRequest<TData, TItem>
extends PreRequest<http.Response, String, TData, TItem> {
@override
Future<PaginatedState<TData, TItem>> run(
PaginatedState<TData, TItem> state) async {
Expand Down Expand Up @@ -34,26 +60,3 @@ mixin PreRequestRun<TData, TItem>
}
}
}

mixin RequestHandleResult<TOut>
on RequestCubit<http.Response, String, TOut, int> {
@override
Future<RequestState<TOut, int>> handleResult(
http.Response result,
) async {
if (result.statusCode == StatusCode.ok.value) {
logger.info('Request success. Data: ${result.body}');
return RequestSuccessState(map(result.body));
} else {
logger.severe('Request error. Status code: ${result.statusCode}');
try {
return await handleError(RequestErrorState(error: result.statusCode));
} catch (e, s) {
logger.severe(
'Processing error failed. Exception: $e. Stack trace: $s',
);
return RequestErrorState(exception: e, stackTrace: s);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ class HomePage extends StatelessWidget {
child: const Text('Simple request page'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => pushNamed(Routes.simpleRequestHook),
child: const Text('Simple request hook page'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => pushNamed(Routes.paginatedCubit),
child: const Text('Paginated cubit page'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ class AdditionalData with EquatableMixin {
);
}

class FiltersPreRequest
extends PreRequest<http.Response, String, AdditionalData, User>
with PreRequestRun {
class FiltersPreRequest extends HttpPreRequest<AdditionalData, User> {
FiltersPreRequest({
required this.api,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,75 +6,25 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart' as http;
import 'package:leancode_cubit_utils/leancode_cubit_utils.dart';
import 'package:leancode_hooks/leancode_hooks.dart';

class UserRequestCubit extends RequestCubit<http.Response, String, User, int>
with RequestHandleResult {
UserRequestCubit(
this._request,
) : super('UserRequestCubit');

final Request<http.Response> _request;
class UserRequestCubit extends HttpRequestCubit<User> {
UserRequestCubit({required super.client}) : super('UserRequestCubit');

@override
Future<http.Response> request() => _request();
Future<http.Response> request() => client.get(Uri.parse('success'));

@override
User map(String data) =>
User.fromJson(jsonDecode(data) as Map<String, dynamic>);
}

class RequestHookScreen extends StatelessWidget {
const RequestHookScreen({super.key});

@override
Widget build(BuildContext context) => const RequestHookPage();
}

class RequestHookPage extends HookWidget {
const RequestHookPage({super.key});

@override
Widget build(BuildContext context) {
final userCubit = useBloc(
() => UserRequestCubit(
() => context.read<http.Client>().get(Uri.parse('success')),
)..run(),
[],
);

return Scaffold(
appBar: AppBar(
title: const Text('Simple request page'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: RequestCubitBuilder(
cubit: userCubit,
builder: (context, data) => Text('${data.name} ${data.surname}'),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: userCubit.refresh,
child: const Text('Refresh'),
),
],
),
);
}
}

class RequestScreen extends StatelessWidget {
const RequestScreen({super.key});

@override
Widget build(BuildContext context) => BlocProvider(
create: (context) => UserRequestCubit(
() => context.read<http.Client>().get(Uri.parse('success')),
)..run(),
create: (context) =>
UserRequestCubit(client: context.read<http.Client>())..run(),
child: const RequestPage(),
);
}
Expand Down

0 comments on commit ec552ad

Please sign in to comment.