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

Popular posts from this blog

Second GET API Calling with Bloc simple Example in Flutter

Stack Container Scrollable Card widget UI with Custom Widget

Pagination with Bloc Pattern in Flutter