AndroidFlutter

How to implement Cubit in flutter app in most easiest tutorial on the web

For me when I started learning bloc and cubit , experience was very scary because people(me) tend to directly jump into implementations.

One very unusual thing happened with me and many fellow developers is we directly get all the implemented steps in some GitHub project or we get the same old counter example to understand Cubit/Bloc

In this post we will be following along how to start implementing cubit with step by step approach . I will be showcasing here a very detailed guide on how to approach each class and how to think along when implementing cubit. In this post we will not be dumping all the source code at once , instead we will cover each class creation and also see where its significant and why we are creating it. At some places we will be coming with widget codes directly because we have very simple UI to explain the bloc.cubit concepts.

Why Bloc is important ?
Very simple: To separate business logic and UI code. And for accessing the state/data of one widget into some another widgets.(Global State management)

So Global state management is nothing but accessing the data generated in one widget into another widget which is created deep inside app widget hierarchy. E.g Marking a list of items and move to cart, so the items that are added in the cart is usable by not only cart screen but at many other places. In our example we will be fetching data using Cubit in this part -1.

Let’s see the diagram and break into this diagram.

Cubit
Cubit

We will create all these three parts in our code step by step and finally connect all this in the main.dart using provider.
Very important is “functions” because our app UI will change using function call in Cubit.

One important difference between Cubit and Bloc is :
Cubit works with “functions” and Bloc works with “Events”

 

So enough of theory , lets start with creating this components

Step 1: Lets create a UI screen first, our UI screen is movie_page.dart which is a first home page which will be loaded in main.dart.

movie_page.dart contains a statefulwidget which consists of simple list builder:

https://github.com/raviyadav5951/CubitExample/blob/main/lib/ui/movie_page.dart

Let’s install these dependencies:

bloc: ^8.1.3
flutter_bloc: ^8.1.4
dio: ^5.4.1
equatable: ^2.0.5

Dio we will be using for api call and equatable we will be using to compare the cubit classes.

We need bloc extension by Felix Angelov in vscode for making our life easy , these extension will provide a superpower to vscode for creating cubit class and provide us autogenerated templates for creating cubit classes, so that we dont need to write boilerplate codes.

https://marketplace.visualstudio.com/items?itemName=FelixAngelov.bloc

Now , after adding this extension we will be creating our cubit class , these will look something like this. You have to right click on folder and selection “new cubit option”

https://miro.medium.com/v2/resize:fit:1400/format:webp/1*o9i8kt5Dgs3MIwwGtdVqWg.png

These will create two important classes. One is Cubit class and second is state class.

We know that any api integration will move step by step from three/four states. Initial state, Loading state, Loaded state(Success state) and Error State(Fail State). We will create a function which will reflect these states so that our app can gradually covers all these states and our UI changes gets reflected accordingly

part of 'movie_cubit.dart';

abstract class MovieState extends Equatable {}

class InitialState extends MovieState {
  @override
  List<Object?> get props => [];
}

class LoadingState extends MovieState {
  @override
  List<Object?> get props => [];
}

class LoadedState extends MovieState {
  LoadedState(this.movies);
  final List<Results> movies;

  @override
  List<Object> get props => [movies];
}

class ErrorState extends MovieState {
  @override
  List<Object> get props => [];
}

We have different states , we are returning List<Result> which is a list of movies which will be returned on success state, empty on Loading state, empty on error state.

Based on this states our app UI will react , on loading our app will show loader and on success it will render the list , these we will see at the end.

And our Cubit class looks like these, we will cover repository class also, these is the same class(third component) from cubit diagram. so till here we have covered all the classes

import ‘package:movies_cubit/repository/movie_repository.dart’;

part ‘movie_state.dart’;

class MovieCubit extends Cubit<MovieState> {
MovieCubit({required this.repository}) : super(InitialState());

final MovieRepository repository;

void getTrendingMovies() async {
try {
emit(LoadingState());
final movies = await repository.getMovies();
emit(LoadedState(movies));
} catch (e) {
emit(ErrorState());
}
}
}

From the stateful widget that we have created , we will be calling getTrendingMovies() function and in the function above you can see “emit” keyword. This emit will be a state that we want our app UI should act on. You have observed that in the MovieCubit constructor we have passed InitialState.

Basically emit tells the UI to update the UI state . E.g emit(LoadingState()) tells user that UI is in loading state so , show your loading indicator and when your data arrived successfully then show the list of movies. And on error show the UI which shows some error messsage.


Feeling glad to receive your comment