API handling using BLOC in Flutter
import "package:bloc_wslc_statemanagement/Api_handling_using_Bloc/Custom_Class/api_helper.dart";
import "package:bloc_wslc_statemanagement/Api_handling_using_Bloc/bloc/quote_bloc.dart";
import "package:bloc_wslc_statemanagement/Api_handling_using_Bloc/bloc/quote_event.dart";
import "package:bloc_wslc_statemanagement/Api_handling_using_Bloc/bloc/quote_state.dart";
import "package:flutter/material.dart";
import "package:flutter_bloc/flutter_bloc.dart";
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Home Page",
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: Colors.grey,
centerTitle: true,
),
),
home: BlocProvider(
create: (context) {
return QuoteBloc(apiHelper: ApiHelper());
},
child: const HomePage(),
),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() {
return HomePageState();
}
}
class HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
BlocProvider.of<QuoteBloc>(context).add(GetQuotesEvent());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
"Quotes",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
body: BlocBuilder<QuoteBloc, QuoteState>(
builder: (context, state) {
if (state is QuoteLoadingState) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (state is QuoteErrorState) {
return Center(
child: Text(state.errormsg),
);
} else if (state is QuoteLoadedState) {
var mDataModel = state.resData;
return ListView.builder(
itemCount: mDataModel.quotes?.length,
itemBuilder: (context, index) {
var eachQuote = mDataModel.quotes![index];
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 7.0,
child: ListTile(
title: Text("${eachQuote.quote}"),
subtitle: Text("${eachQuote.author}"),
),
),
);
},
);
}
return Container();
},
),
);
}
}
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/Custom_Class/api_helper.dart';
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/Model/quote_model.dart';
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/Urls/urls.dart';
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/app_exceptions.dart';
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/bloc/quote_event.dart';
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/bloc/quote_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class QuoteBloc extends Bloc<QuoteEvent, QuoteState> {
ApiHelper apiHelper;
QuoteBloc({required this.apiHelper}) : super(QuoteInitialState()) {
on<QuoteEvent>(
(event, emit) async {
emit(QuoteLoadingState());
try {
var resJson = await apiHelper.getAPI(url: Urls.getQuotesUrl);
if (resJson != null) {
var mResData = DataModel.fromJson(resJson);
emit(QuoteLoadedState(resData: mResData));
} else {
emit(QuoteErrorState(errormsg: "Uhh..No!!, Error Occurred"));
}
} catch (e) {
emit(QuoteErrorState(errormsg: (e as AppExceptions).toErrorMsg()));
}
},
);
}
}
import "dart:convert";
import "dart:io";
import "package:bloc_wslc_statemanagement/Api_handling_using_Bloc/app_exceptions.dart";
import "package:http/http.dart" as http;
class ApiHelper {
Future<dynamic> getAPI({required String url}) async {
var uri = Uri.parse(url);
try {
var response = await http.get(uri);
return returnJsonResponse(response);
} on SocketException catch (e) {
throw (FetchDataException(errorMsg: "No Internet!!"));
}
}
Future<dynamic> postAPI(
{required String url, Map<String, dynamic>? bodyParams}) async {
var uri = Uri.parse(url);
var response = await http.post(uri, body: bodyParams ?? {});
if (response.statusCode == 200) {
var mData = jsonDecode(response.body);
}
}
dynamic returnJsonResponse(http.Response response) {
switch (response.statusCode) {
case 200:
{
var mData = jsonDecode(response.body);
return mData;
}
case 400:
throw BadRequestException(errorMsg: response.body.toString());
case 401:
case 403:
throw UnauthorisedException(errorMsg: response.body.toString());
case 500:
default:
throw FetchDataException(
errorMsg:
"Error occurred while Communication with Server with StatusCode : ${response.statusCode}");
}
if (response.statusCode == 200) {
var mData = jsonDecode(response.body);
return mData;
} else {
return null;
}
}
}
class AppExceptions implements Exception {
String title;
String msg;
AppExceptions({required this.title, required this.msg});
String toErrorMsg() {
return "$title: $msg";
}
}
class FetchDataException extends AppExceptions {
FetchDataException({required String errorMsg})
: super(title: "Network Error", msg: errorMsg);
}
class BadRequestException extends AppExceptions {
BadRequestException({required String errorMsg})
: super(title: "Invalid Request: ", msg: errorMsg);
}
class UnauthorisedException extends AppExceptions {
UnauthorisedException({required String errorMsg})
: super(title: "Unauthorised: ", msg: errorMsg);
}
class InvalidInputException extends AppExceptions {
InvalidInputException({required String errorMsg})
: super(title: "", msg: errorMsg);
}
class Urls {
static final String getQuotesUrl = "https://dummyjson.com/quotes";
}
class QuoteEvent {}
class GetQuotesEvent extends QuoteEvent {}
import 'package:bloc_wslc_statemanagement/Api_handling_using_Bloc/Model/quote_model.dart';
class QuoteState {}
class QuoteInitialState extends QuoteState {}
class QuoteLoadingState extends QuoteState {}
class QuoteLoadedState extends QuoteState {
DataModel resData;
QuoteLoadedState({required this.resData});
}
class QuoteErrorState extends QuoteState {
String errormsg;
QuoteErrorState({required this.errormsg});
}
class DataModel {
List<Quotes>? quotes;
int? total;
int? skip;
int? limit;
DataModel({this.quotes, this.total, this.skip, this.limit});
DataModel.fromJson(Map<String, dynamic> json) {
if (json['quotes'] != null) {
quotes = <Quotes>[];
json['quotes'].forEach((v) {
quotes!.add(new Quotes.fromJson(v));
});
}
total = json['total'];
skip = json['skip'];
limit = json['limit'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.quotes != null) {
data['quotes'] = this.quotes!.map((v) => v.toJson()).toList();
}
data['total'] = this.total;
data['skip'] = this.skip;
data['limit'] = this.limit;
return data;
}
}
class Quotes {
int? id;
String? quote;
String? author;
Quotes({this.id, this.quote, this.author});
Quotes.fromJson(Map<String, dynamic> json) {
id = json['id'];
quote = json['quote'];
author = json['author'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['quote'] = this.quote;
data['author'] = this.author;
return data;
}
}
Comments
Post a Comment