Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Alright so let's begin assuming you created the project and can currently run the hello world app, first thing to do is remove all the boilerplate and keep only the main method.
After this, you need to create the "Application" widget. In order to do that create a new folder under src and create a new file called "application.dart"
So all of this is straightforward. The next step is to define our routes.
What are we building?
The project that we are going to build for this tech camp is a simple shopping app with the following features:
Get my profile
Get all products
Filter products by category
Add products to the cart
Increment or decrement products on the cart
The purpose of the project and its limited features is to introduce you basics of coding a standard app in a way that is scalable and easy to manage in the future.
These are what the screens of the application we are going to build would look like
That being said here's a couple of things to expect to learn with this project:
Bloc (Cubit) state management
Local state caching using hydrated cubit
Using DIO for Rest-API requests
Freezed for sealed class generation
JSON annotation for model generation
Unit testing with mockito
Widget testing
Auto Route for route management
Dependency injection using GetIt
Before heading off to explain the project details let's take a step back and discuss about the project structure we are going to follow.
So basically folders are going to be grouped based on the feature under src as you can see from the image above.
Apart from the feature, there is an application folder for putting the main app or the root widget, there is also a di folder for dependency injection and finally the router folder for putting all our page routes.
Let's take a closer look at the product feature for instance.
So each of the folders represent a layer of the feature to be coded. If the names don't make sense we will cover them later don't worry.
Adding linters, Adding Dependency
On the main project folder go to pubspec.yaml
pubspec.yaml is used to maintain dependencies on the flutter project.
Once you added the package run the following command to install the package in your project.
Once install the package make sure to restart the project. Because the flutter hot-reload can't access the package unless it restarts.
Welcome to Tech-camp Ethiopia.
A tech boot camp is exactly what it sounds like – an encompassing program where we learn to either cultivate new tech skills or improve our current strengths. In a way, boot camps are like extended workshops. It is an intensive coding training course that prepares people with little or no prior experience in software development to work as junior developers.
"Learning to write programs stretches your mind, and helps you think better, creates a way of thinking about things that I think is helpful in all domains.” Bill Gates
The Tech Camp Ethiopia 2020 will be a series of 6 Bootcamp programs that encourage all of the youths – makers, engineers, do-gooders, executives, computer scientists, inventors, innovators – are making things that are not just nice to have, but that people need.
Tech Camp Ethiopia creates connections, sparks, innovations, and empowers young tech-savvy society to solve real-world pressing challenges through technology.
This program is organized by the U.S. Embassy in Ethiopia in collaboration with GDG Addis (as an implementing partner) and CAWEE (a financial administrator). It is one part of #USInvestsInEthiopians programs.
The goal of Tech Camp Ethiopia is to guide youths where to get started in the trending tech world and raise their technical, business, and other soft skills through one-to-one learning, hands-on training, and workshops in record time. It aims to pave the way for the participants how to convert ideas to prototype and then prototype into business by letting them enjoy their new skills with project-based practices.
Involve as many underrepresented communities as possible by implementing DIVERSITY & INCLUSION principles.
Let the participants find the best teams to work together and probably to form a startup.
Elevate the business and digital marketing skills of the youth
Give the youths the habit of how to get the job done through hands-on practices and project-based exercises.
Create a fun way of learning experience through different gamification and engaging activities.
Create networking opportunities with tech companies who may potentially find skill power from the participants.
Learn more about the program at https://techcamp.gdgaddis.dev
Code generation for immutable classes that has a simple syntax/API without compromising on the features.
While there are many code-generators available to help you deal with immutable objects, they usually come with a trade-off. Either they have a simple syntax but lack features, or they have very advanced features but with complex syntax.
Add this to your package's pubspec.yaml file:
You can then install packages from the command line:
Alternatively, your editor might support dart pub get
. Check the docs for your editor to learn more.
Now you can use it in your Dart code by importing it like this:
Note that the line partmy_demo.freezed.dart
will give you a warning, because the file is not created yet
Write the following code
To generate the code type the following command
It is likely that the code generated by Freezed will cause your linter to report warnings.
The solution to this problem is to tell the linter to ignore generated files, by modifying your analysis_options.yaml
:
In order to create the first page create products_screen.dart under src/product/view/product with the following basic screen.
That's enough for now let's go ahead and create the router setup.
So the last step is adding an instance of the router class we just generated to the material app to manage its routes.
While doing this step flutter may cause an error that the router class is imported from two libraries. So in order to overcome that change your imports like this.
It is hard to think of a mobile app that doesn’t need to communicate with a web server or easily store structured data at some point. When making network-connected apps, the chances are that it needs to consume some good old JSON, sooner or later.
In case you're not familiar with the term data class, it's simply a class with value equality, copyWith
method, its fields are immutable and it usually easily supports serialization. Also, if you're familiar with Kotlin, you know that you can heavily cut down on the boilerplate by defining fields directly in the constructor like this:
instead of this
instead of coding boilerplate freezed does all this with a few keystrokes
In this section we will be Working on Creating the models of the Products features and the following will be covered.
For this project, we are going to use auto_route for routing between screens as named routes. So to begin first add it on your "pubspec.yaml"
So auto route uses code generation if you're new to code generation in dart check out this .
After that let's go ahead and create our first page and create our router.
First, create the "products_state.dart" file under src/product/cubit/products/ with the following code.
Now let's create the "products_cubit.dart" file under src/product/cubit/products/ with the following code.
Add this to your package's pubspec.yaml file:
You can then install packages from the command line:
Alternatively, your editor might support dart pub get
. Check the docs for your editor to learn more.
Now you can use it in your Dart code by importing it like this:
Note that the line partmy_demo.g.dart
will give you a warning, because the file is not created yet
Write the following code
To generate the code type the following command
It is likely that the code generated by Json_Serializer will cause your linter to report warnings.
The solution to this problem is to tell the linter to ignore generated files, by modifying your analysis_options.yaml
:
In flutter, state management is like a life support system where the whole App depends on, there are different state management techniques like Redux, MobX, bloc, flutter bloc, provider, and cubit. Actually Cubit is a cocktail of Flutter Bloc and Provider where we use some features of both techniques and we are going to learn how to use and implement Cubit, So before we go for its implementation firstly let’s have some cursory knowledge of it.
Cubit is a lightweight state management solution. It is a subset of the bloc package that does not rely on events and instead uses methods to emit new states. Every cubit
requires an initial state which will be the state of the cubit
before emit
has been called. The current state of a cubit
can be accessed via the state
getter.
After that let's create the configuration needed for the router. First, create the "router.dart" file under src/router/ with the following code.
After this run, the command "pub run build_runner build" on the terminal of the project to generate the router source code. After running it you should see a "router.gr.dart" file next to it where the generated source code is written.
What the above code basically does is register a new route for "ProductsScreen" and make it the initial route.
After installing and experimenting on the freezed package, now let's create producs model.
First, create the "product.dart" file under src/product/model/product/ with the following code.
After this run, the command "pub run build_runner build" on the terminal of the project to generate the product source code. After running it you should see "product.freezed.dart" and "product.g.dart" files next to it where the generated source code is written.
A repository is nothing flutter specific. It's a design pattern with many implementations in many languages and for our case we are going to be using DIO. The Repository pattern implements separation of concerns by abstracting the data persistence logic in your applications. Design patterns are used as a solution to recurring problems in your applications, and the Repository pattern is one of the most widely used design patterns.
Dio is a networking library developed by Flutter. It is powerful Http client for Dart, which supports Interceptors, Global configuration, FormData, Request Cancellation, File downloading, ConnectionTimeout etc. Things that dio supports can be done with normal http library which we get in flutter sdk too but its not that easy to learn or understand so dio can be better.
Inside the product_screen.dart file under src/product/view/products/ add the following code:
Making your first http request with DIO
The above example will make a request to http://google.com and print the result.
Performing a GET
request:
Performing a POST
request:
Performing multiple concurrent requests:
Downloading a file:
You can create an instance of Dio with an optional BaseOptions
object:
In this section we are going to be setting up our UI.
In order to use the blocs in your Flutter UI, you need to be able to access the blocs through-out your app. For example, you want to be able to do something like this in a widget. Provider is a term you'll see a lot in the Flutter world. In Flutter, it's used to describe a class that is used to inject other objects throughout your widget tree or scope, even when you're much further down the widget tree than where the objects are created.
Dependency Injection (DI) is a technique used to reduce tight coupling between classes thus achieving greater re-usability of your code. Instead of your class instantiating/creating the dependent classes/objects, the dependent objects are injected or supplied to your class; thus maintaining an external library of sorts to create and manage object creation in your project.
Some of the state management libraries such as flutter_bloc, provider incorporate dependency injection by means of the Inherited Widget model.
Inside the product_screen.dart file under src/product/view/products/ add the following code:
Inside the product_screen.dart file we created earlier put the following code:
The _CartButton is a stateless widget placed inside product_screen.dart that builds a clickable widget we will use to navigate to the cartScreen
Now let's edit ProductScreen class in product_screen.dart
Inside the product_screen.dart file under src/product/view/products/ add the following code:
Widget testing is otherwise called component testing. As its name proposes, it is utilized for testing a single widget, and the objective of this test is to check whether the widget works and looks true to form.
Widget testing proves to be useful when we are trying the particular widgets. On the off chance that the Text widget doesn’t contain the text, at that point, Widget testing throws an error expressing that the Text widget doesn’t have a text inside it. We likewise don’t host to install any third-party dependencies for widget testing in Flutter.
Implementation:
Steps to Implement Widget Testing
Step 1: Add the dependencies
Add the
flutter_test
dependency to pubspec — yaml file.
Step 2: Create a file "product_screen_test.dart" in the directory test/product/view/products/ with the following code.