Tuesday, August 28, 2018

Dependency Injection with KOIN to Androidx Jetpack

August 28, 2018

Welcome to this post.

A few months ago google launch jetpack. This library includes some new component, like Work Manager. The problem is if you want to use dependency injection, then you can not do easily. If you heard about dependency injection then the first library coming in our mind is Dagger. But the problem is Dagger still not support androidx.

A few days ago I work with a new project, and I decide to use Work manger. But the problem arises because I am used Dagger. I search and waste a couple of hours but the solution is not in the satisfaction level. Then I decide to move to KOIN.

This is the first time I use KOIN. And the problem is gone. And I found KOIN is very handy. I don't have to write a lot of code. Just a simple line configuration. Declaring module is also very easy.
you will see that too in this post.

So let's start KOIN
First, add dependencies of KOIN


implementation 'org.koin:koin-android:0.9.3'
implementation "org.koin:koin-androidx-viewmodel:1.0.0-beta-3"

Note: Don't forget to add room, viewmodel, and livedata dependencies.

Let's Create a database.
I use room.

I skipping this part. you probably know how to create database using room. (This post is about some advanced topics).

Code snippet:
Create a table, such as WordTable
@Entity
class WordTable(
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0,
        var word: String = "",
        var des: String = "",
        var bookmark: Boolean = false,
        var addByUser: Boolean = false,
        var uploaded:Boolean = false
)

Now Data Accessing object(Dao), exp: WordTableDao
@Dao
interface WordTableDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun add(table: WordTable): Long

    @Update
    fun update(table: WordTable): Int

    @Delete
    fun delete(pageTable: WordTable): Int


    @Query("Select * From WordTable")
    fun getAllList(): List<WordTable>
}

All set, create the database class.

@Database(entities = [WordTable::class], version = 1,
        exportSchema = false)
abstract class MyDatabase:RoomDatabase(){
    abstract val wordTableDao: WordTableDao
}

So our class database is ready, but still, we don't create the database. We will create the database in the KOIN module declaration time.

Now create a ViewModel class.
we need only Dao. it will provide by KOIN. We ViewModel Class as the parent class.
In the class just create a method called getData()  and load data from the database and return.

class MainVM(private val wordTableDao: WordTableDao):ViewModel(){

    fun getData() = wordTableDao.getRandomData()

}

Now time for module declaration. See the code first, then I discussing code.
we have two module. The first one is dbModule

val dbModule = module {

    single {
        Room.databaseBuilder(androidContext(), MyDatabase::class.java,
                "SS").build()
    }

    single { get<MyDatabase>().wordTableDao }

}

code -
1. keyword: module, it's just a function that creating a koin module
2. To create an instance you have to use single (from this new version, in the old version, use been keyword)
3. in a single, create the database
4. another single, call get function and type MyDatabase and access the Dao.

The second module is vmModule,
Same as this module but this time use viewmodel instead of single.

val vmModule = module {
    viewModel {
        MainVM(get() as WordTableDao)
    }
}

Note: if you don't use the androidx version of KOIN then you get an error, in this module declaration

we finished all declaration. Now we are ready for using KOIN. But before using KOIN, we have to start KOIN. To start KOIN declare an application class.
and write a simple line of code-

startKoin(this, listOf(module_list)

See code-

class MyApp:Application(){

    override fun onCreate() {
        super.onCreate()
        startKoin(this, listOf(dbModule, vmModule))
    }
}

All set. Now inject the ViewModel in the Main activity.
Now hard here, just declare a variable type MainVM and use by keyword (for lazy injection) and call viewModel() function.

    private val viewModel: MainVM by viewModel()

See code-

class MainActivity : AppCompatActivity() {

    private val viewModel: MainVM by viewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)


        viewModel.getData().observe(this, Observer {
            //observe data
        })
    }

}

Now the most desired one-
we are going to inject in the worker class. Create a worker class. But this time you are injecting KOIN not supported class. Don't worry. KOIN has already built an option to solve this problem. You have to implement KoinComponent.
After that same, declare a variable and lazy injection call inject() function
    val wordTableDao: WordTableDao by inject()

See the code-

class MyWorker : Worker(), KoinComponent {

    val wordTableDao: WordTableDao by inject()

    override fun doWork(): Result {

        val table = WordTable()

        wordTableDao.add(table)
        
        return Result.SUCCESS
    }


}

That's it. We are done. We finished our goal.

If you check all of those code in Gist also. Click here.

So by using KOIN, you can easily inject on the Androidx component. But for the dagger case, it's not so easy as this.

So, it's your choice, to use dagger or koin.

Thanks for reading.
Hope this articles help you a lot.

Happy coding

Read More

Saturday, August 4, 2018

Playing with IO in Kotlin

August 04, 2018

Welcome to this post.

Today I going to cover a very unusual topic. If this problem is matched with you then it will help you to save a lot of time.

So let's start-

Imagine you have a text file of some data and you want to format it and save the data into the JSON file.

Example text file line:
abbey - n. a monastery ruled by an abbot
....
And you have so many lines in the text file.

and your goal is separate, the word and type(part of speech) and description of the word.
so the file output is like
word - abbey
type - n
des - a monastery ruled by an abbot

and save this on  a JSON file
{
    "word": "Abbey",
    "type": "n",
    "des": "a monastery ruled by an abbot"
}

This is our today goal. (If you don't clear the take a look again)

Let's jump in the code-
Create the main method and add try catch block

fun main(args: Array<String>) {
    try {

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

you have to write all the code in the try-catch block.
Create an input and output file name and path variable
val inputName = "definitions.txt"
val outputName = "Output2.json"
val path = "D:/Android/test/"
make sure you select right path. Now make input and output file.
val inputFile = File("$path$inputName")
val outputFile = File("$path$outputName")

you can check is your input file exists or not
println(inputFile.exists())
Output:
true
Note: If your output is false then your path is wrong, select the right path. until you get this output.

Create an instance of Gson
val gson = Gson()
Note: If you don't know how to add the external library, see this tutorial

Now create a Model class-
class Model(
    val word:String,
    val type:String
    val des:String
)
Create an array list of this model
val list = ArrayList<Model>()

Take a look at our data source. This decorated in lines. So we can go through emery lines.
So we run a for loop for every line. Take the buffer reader from the input file and read lines.

for (string in inputFile.bufferedReader(bufferSize = 4096).readLines()) {
}
I use the buffer size 4096 you can use 1024, or any as you want. If you don't have clear knowledge about buffer size then this answer on StackOverflow

create an instance of StringBuilder.
var stringBuilder = StringBuilder()

Step 1: separate the word.
so we read character wise and if we find this sign '-' then stop reading.
for (char in string) {
     if (char == '-') {
          break
     }
     stringBuilder.append(char)
}
so we find our word and that in the StringBuilder
var word = stringBuilder.toString().trim()
Note: use trim() to remove the space.

Step2: separate the type
first remove the word from the string and do the same code as the word. But this time sign is changed. Now sign is '.'
val typesData = string.removePrefix("$word -").trim()
stringBuilder = StringBuilder()
for (char in typesData){
     if (char == '.') {
         break
     }
     stringBuilder.append(char)
}
so we find the type
val type = stringBuilder.toString().trim()

Step 3: separate the description
first, remove the types
val des = typesData.removePrefix("$type.").trim()
so we find the description.

Extra:
we want to capitalize the first char of the word
val cap = word[0].toUpperCase()
word = word.replaceFirst(word[0],cap)

Now create the model and add to the list.
val model = Model(word,type,des)
list.add(model)

So our all word and tyes and des added in the array.

Now our final task is to convert this list to JSON. For this task we use Gson.
//convert list to JSON string
val string = gson.toJson(list)

Create a new output file on the disk.
//crate new file
outputFile.createNewFile()

Now create the instance of file writer and write this json code in the file.
//now write
val writer = FileWriter(outputFile)
writer.write(string)
Don't forget to close the writer.
//close writer
writer.close()

and finally, print a done message.
println("Done")

So everything is done. Now run the program

Output:
Done

So our JSON file:

[{"word":"Abbey","type":"n","des":"a monastery ruled by an abbot"},{"word":"Abide","type":"v","des":"dwell; inhabit or live in"},{"word":"Abound","type":"v","des":"be abundant or plentiful; exist in large quantities"},{"word":"Absence","type":"n","des":"the state of being absent"},{"word":"Absorb","type":"v","des":"assimilate or take in"},{"word":"Abstinence","type":"n","des":"practice of refraining from indulging an appetite especially alcohol"},{"word":"Absurd","type":"j","des":"inconsistent with reason or logic or common sense"},{"word":"Abundant","type":"j","des":"present in great quantity"},{"word":"Abusive","type":"j","des":"characterized by physical or psychological maltreatment"}, ... 

Check the full code on GitHub.

Some other problem:

Problem 1:
This time our output design will same but our input design will be different.
The input pattern is
word    (type) description

See the solution on Github 

Problem 2:
Input pattern:
word = (type) description

Check the solution on Github

That's it today. Today I cover some unusual topics, but this will help you to save time if you have the same problem.

Thank you very much for reading.

Happy coding.

Read More

Saturday, July 14, 2018

Dart: Json Parsing

July 14, 2018

Welcome to this post.

In this post, I am going to cover about JSON parsing in Dart.

What I will do on this project?
 1.  Get data from Rest API.
 2.  Parse the JSON Data

Let's Start-

First, take look at the data source. I will get the data from this link.
https://swapi.co/api/starships/

JSON sample.
This response you will find that link
{
    "count": 37, 
    "next": "https://swapi.co/api/starships/?page=2", 
    "previous": null, 
    "results": [
        {
            "name": "Executor", 
            "model": "Executor-class star dreadnought", 
            "manufacturer": "Kuat Drive Yards, Fondor Shipyards", 
            "cost_in_credits": "1143350000", 
            "length": "19000", 
            "max_atmosphering_speed": "n/a", 
            "crew": "279144", 
            "passengers": "38000", 
            "cargo_capacity": "250000000", 
            "consumables": "6 years", 
            "hyperdrive_rating": "2.0", 
            "MGLT": "40", 
            "starship_class": "Star dreadnought", 
            "pilots": [], 
            "films": [
                "https://swapi.co/api/films/2/", 
                "https://swapi.co/api/films/3/"
            ], 
            "created": "2014-12-15T12:31:42.547000Z", 
            "edited": "2017-04-19T10:56:06.685592Z", 
            "url": "https://swapi.co/api/starships/15/"
        },
      ...
    ]
}

This is the json Sample. I just take only results data. It's a collection of the result. SO create the model class first.

Model Class

We have so many things on the JSON result.
so you have to create all the field.
Note: If you don't need some field, simply skip those.
  final String name;
  final String model;
  final String manufacturer;
  final String cost_in_credits;
  final String length;
  final String max_atmosphering_speed;
  final String crew;
  final String passengers;
  final String cargo_capacity;
  final String consumables;
  final String hyperdrive_rating;
  final String MGLT;
  final String starship_class;
  final List films;
  final List pilots;
  final String created;
  final String edited;
  final String url;
Note: here films and pilots are Lists, not String.

Now create the constructor-
RestModel(
      {this.name,
      this.model,
      this.manufacturer,
      this.cost_in_credits,
      this.length,
      this.max_atmosphering_speed,
      this.crew,
      this.passengers,
      this.cargo_capacity,
      this.consumables,
      this.hyperdrive_rating,
      this.MGLT,
      this.starship_class,
      this.films,
      this.pilots,
      this.created,
      this.edited,
      this.url});

Now create a factory method-
take a map and return a new RestModel.
factory RestModel.fromJson(Map<String, dynamic> json) {
      return new RestModel(
          name: json["name"] as String,
          model: json["model"] as String,
          manufacturer: json["manufacturer"] as String,
          cost_in_credits: json["cost_in_credits"] as String,
          max_atmosphering_speed: json["max_atmosphering_speed"] as String,
          crew: json["crew"] as String,
          passengers: json["passengers"] as String,
          cargo_capacity: json["cargo_capacity"] as String,
          consumables: json["consumables"] as String,
          hyperdrive_rating: json["hyperdrive_rating"] as String,
          MGLT: json["MGLT"] as String,
          starship_class: json["starship_class"] as String,
          films: json["films"] as List,
          pilots: json["pilots"] as List,
          created: json["created"] as String,
          edited: json["edited"] as String,
          url: json["url"] as String,
      );
  }

See the full class code of RestModel in Github.

Parse JSON

Now time for getting data from the internet-
Create the main function
void main() async{
}

Save the link in a String.
final link = "https://swapi.co/api/starships/";

Create a new list. And the subtype of this list will be RestModel
List<RestModel> list = new List();

import HTTP package and make a request
var res = await http.get(Uri.encodeFull(link), headers: {"Accept": "application/json"});

next steps-
1. if the response code is 200 then the response is successful
2. decode the response code with the help of json class that include in the package 'dart:convert'
3. after decode it return a map.
4. take only 'result' from the map and save in a new variable.
5. loop this list and for every entry and return a new RestModel

See the code-

if (res.statusCode == 200) {
    var data = json.decode(res.body);
    var rest = data["results"] as List;
    for (var json in rest) {
	var model = new RestModel.fromJson(json);
	list.add(model);
	}
}

print the list
print("List Size: ${list.length}");

Output:
List Size: 10

Full code-

import 'package:http/http.dart' as http;
import 'dart:convert';
import 'RestModel.dart';


void main() async{

	final link = "https://swapi.co/api/starships/";

	List<RestModel> list = new List();

	var res = await http
			.get(Uri.encodeFull(link), headers: {"Accept": "application/json"});

	if (res.statusCode == 200) {
		var data = json.decode(res.body);
		var rest = data["results"] as List;
		for (var json in rest) {
			var model = new RestModel.fromJson(json);
			list.add(model);
		}
		print("List Size: ${list.length}");
	}
}

That's it.
If you have any quires then use the comment section. Feel free to put comments.
you can easily parse json.
Happy Coding.

Read More

Saturday, June 30, 2018

Searching Algorithms: Linear Search

June 30, 2018

welcome to this post.

Today I am going to talk about Searching Algorithms.
In this tutorial, I will cover 3 Searching Algorithms
  • Linear Search
  • Binary Search
  • Interpolation Search

So Let start with Linear Search

Linear Search:
From the name, you can get an idea. It searches linearly. One by one.
This algorithm starts the search from the beginning and continues until finding the
desired search index.

For example,
Assume an array from 0 to 10. and you are searching for10. so what will happen?

First, it checks
if 10 is equal to 0 => nope, then
if 10 is equal to 1 => nope, then
.................................................
continue this
if 10 is equal to 10 => yes.

Now it's finding the number.

So it starts from the beginning and continues until it's done.

Let's jump into the code
Create a class and it's constructor take the array size.
class DataK(size:int){
} 

create two variable,

  • one is an array that holds the data set
  • other is numberOfTry: an int type variable that will give information,
how many tries need to find the value.

val array: Array<Int> = Array(size,{i -> i})
var numberOfTry = 0

Now Just run a for loop from 1 to the given size and put the data into the array.
init {
    for (i in 1 until size){
         array[i-1] = i
     }
}

The complete Class code in GitHub
Note: This class is used in every searching Algorithms.

Now create the main method and initialize the data and give the size 100000.
val data = DataK(100000)

we want to find 9999
val search = 99999

Set the initial number of try to zero
var numberOfTry = 0

And the last declare a new variable, named it to result and this will hold the result.
everything is set, now I am ready for the main action

To search run a for loop from 0 to the data size and compare the index value with our searching number if find the break the loop and at the end increase the number of tries.

That's is the idea.
See code
for (i in 0 until (data.array.size - 1)) {
    val number = data.array[i]
    if (number == search) {
        result = number as Int
        break
    }

    numberOfTry++
}

Now result:
from the linear search if the result is -1 then the value does not exist and that means data is not found.

so, we print the number of tries to see it actually search or not if the result is not -1 then
we find the data.
print number of trials, to see how much try need to find our data

if (result != -1)
    println("Data found on: $numberOfTry")
else
    println("Data not found try: $numberOfTry")

Output:
Data found on: 99998

so, it takes 99998 try to find 99999.

Check the full source code in Github

Note: If you are from java. Check this on Github.

That is all about the Linear search algorithm.

It is a very simple algorithm. It is not widely used.

we will compare all of the searching algorithms after completing all of those.

In the next part, I will discuss Binary search.

Thank you for reading.
If you have any suggestion or any queries use the comment section.

Happy coding

Read More

Wednesday, June 20, 2018

Dart: Variable

June 20, 2018

Welcome to the series post.
The is the first post about Dart

From today I am starting Dart language tutorial.
I already posted a brief introduction about dart and I also try to answer why you choose the dart programming. Check this Dart Introduction

In the previous post, I write about some important concept about dart. Before starting I recommend for taking a look.

Main method:
First, see the code:
void main(List<String> lists) {
}
In the code, you see that the parameter of the main method is a list of string. I think this is as usual of other programming languages. But most interesting part is that you can also create the main method without this parameter.
void main() {
}

So, That's so simple.
Now write a hello world program, to print something on the console, use print() function.
void main(List<String> lists) {
  print("Hello world");
}
Output:
Hello world

That's is the hello world program.
Now you can modify this program as yourself.

Variables:
Var:
To declare any variable you can use var keyword.
var v = 10;
you can put any type of data, like, Int, Double, String or anything
var string = "String";
var int = 10;
var double  = 30.0;
var boolean = false;

If you don't specify the value by default it considers as null
var value; //value is null

dynamic
You can use another keyword available name dynamic.
dynamic s = "s";
this dynamic type of variables can also hold any type of data, like var
dynamic string = "String";
dynamic int = 10;
dynamic double  = 30.0;
dynamic boolean = false;

You can also specify the data type of the data
String value;
int number;
double number2;
bool status;

Multiple variables:
You can also initialize multiple variables at the same time.
var a,b,c,d,e;
also, you can specify the value
var a1 = 10,b2 = 20,c2 = 30;

final and const:
If you need a variable that's value is not change after the declaration, use final keyword
final name = "Shudipto";
also the option for specific variables
final String type = "Student"; //explicitly

If you need runtime constant variables, then use const keyword
const value = 1000;
specific variable
const String data = "data:$value";

Lest see an example-
var foo = const [];
final bar = const [];
const baz = const [];
Here, [] create an empty list. and const[] creates an empty immutable list, it's denoted as (EIL)
In the above code,
foo => foo is currently an EIL.
bar => bar will always be an EIL.
baz => baz is a compile-time constant EIL.

It is possible to change the value of a non-final, non-const variable,
even if it used to have a const value.
foo = [];

It is not possible to change the value of a final or const variable.
// bar = []; // Unhandled exception.
// baz = []; // Unhandled exception.

that's it of the variable.

Comments:
single line comment: as usual like other languages. use '//'
//single line comment

multiline comment:
/*
* multi line comment
*/


That's the ending of today post.
Today in this article, I covered Hello world program and variable and Comments.

Thank you for reading.

Happy coding.

Read More

Friday, June 8, 2018

Communication between View and ViewModel

June 08, 2018

Welcome to this post.

In this post, I am going to talk about, how to communicate between view and viewModel.

Let's take a look on ViewModel

ViewModel was introduced on Google I/O 17, a part of Lifecycle extensions. Now it's released version is 1.1.0.
lifecycle
Src: Medium

From the picture, you can see that it launch with the creation of activity. And it will be cleared only when the activity is finished. The biggest advantage is that it can survive configuration changes.
You should not put any view reference in the viewModel. Why?
The answer is so simple When activity recreated the also. So if you pass view to ViewModel then it creates a leak, because, on the recreation of activity, all the views are brand new, but your ViewModel is still holding the older view that already destroyed.
Don't do this.

Now a question, so how to communicate between view and ViewModel?

Case Study:
Imagine you build an app that has an option for the user signup. When the user clicks signup button then
you can show a dialog and after successful signup, we have to show a notification or perform any task. In this case how you contact view and ViewModel.

Let's start-
To solve this problem I create a class that inherited Mutable Live Data Class.
class SingleLiveEvent<T> : MutableLiveData<T>() {

    private val pending = AtomicBoolean(false)

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<T>) {

        if (hasActiveObservers()) {
            //Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
        }

        // Observe the internal MutableLiveData
        super.observe(owner, Observer<T> { t ->
            if (pending.compareAndSet(true, false)) {
                observer.onChanged(t)
            }
        })
    }

    @MainThread
    override fun setValue(t: T?) {
        pending.set(true)
        super.setValue(t)
    }

    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    fun call() {
        value = null
    }

    companion object {
        private const val TAG = "SingleLiveEvent"
    }
}

This is the sample from google, it is the blueprint of architecture component. Check this.
But If you want to set a value from the main thread then it's ok. you can use this without changing anything.

But what about the background thread?
If you want to set a value from a background thread, then you have to override postValue() method.
override fun postValue(value: T) {
    pending.set(true)
    super.postValue(value)
}
If you have any confuse, then check GitHub

Create a status class
enum class Status{
    LOGIN,
    SIGNUP,
    FAILED
}

Now come on ViewModel Code:
create an instance of SingleLiveEvent
val observableEvent = SingleLiveEvent<Status>()

I create 3 mock methods, just with a thread that wait for 2 seconds and set the value on the variable, observableEvent.

mockLogin()
just set value from the main thread and start a new background thread.
fun mockLogin(){
    observableEvent.value = Status.LOGIN
    background()
}

mockSignup()
start a thread and wait for 2s and set value. and also start a new background thread.
fun mockSignUp(){
        Thread({
            try {
                Thread.sleep(2000) //2 sec wait
            } catch (e:Exception){
                //nothing
            } finally {
                observableEvent.postValue(Status.SIGNUP)
                //do some task from background
                background()
            }
        }).start()
    }

background()
start a background thread and with the handler and wait for 2s
private fun background(){
        val thread = HandlerThread("Background")
        thread.start()

        Handler(thread.looper).post({

            //wait for 2 sec
            Thread({
                try {
                    Thread.sleep(2000) //2 sec wait
                } catch (e:Exception){
                    //nothing
                } finally {
                    observableEvent.postValue(Status.FAILED)
                }
            }).start()
        })
    }

Now time for activity code:
I have 3 view
  • progress bar
  • login button
  • signup button
First, hide the progress bar
val progressBar:ProgressBar = progressBar
progressBar.gone()
Note, here I use an extension function. see here 

set onclick event for every button and also called the method from ViewModel

Login:
hide progress bar
button.setOnClickListener {
    progressBar.vis()
    viewModel.mockLogin()
}

Sign up:
hide progress bar
button2.setOnClickListener {
    progressBar.vis()
    viewModel.mockSignUp()
}

now observe that event and show toast message. see the code
viewModel.observableEvent.observe(this, Observer {
    if (it == Status.LOGIN){
        progressBar.gone()
        "Login Successful".showToast()
    } else if (it == Status.SIGNUP) {
        progressBar.gone()
        "Sign up Successful".showToast()
    }

    if (it == Status.FAILED){
        "Job Failed from background thread".showToast()
    }
})
here, showToast is another extension function
private fun String.showToast(){
    Toast.makeText(context, this, Toast.LENGTH_SHORT).show()
}

Now run the code and click the button see the toast message.

So, that's it.
you can find this project on GitHub

Thanks for reading.
Hope this tutorial will help you a lot.

Happy coding.

Read More

Sunday, June 3, 2018

Dart: Introduction

June 03, 2018

Welcome to this post.
Recently I start to learn Dart programming language.

From today, I will post about dart programming language.

dart
Src: Dartlang


What is dart?
Dart is an object-oriented programming language, developed by Google. It is used to build web, server, and mobile applications(Flutter).

Before Learning darts, some important concept, we have to understand.
Concepts:

  • Everything in darts is object and object is an instance of Class.
  • Even variable, function and null are object too.
  • Type annotation is optional because it is strongly typed. So we can special type or dynamic
  • Dart support generic type (for example a list of integers: List
  • Top level function is supported, we also used functions that tied to an object or a class. And another cool thing is it supports nested function
  • It also supports top-level variable and tied variables. The instance variable, sometimes known as fields or properties.
  • Like Java, Dart has no keyword like public, protected, private, If variables start with underscore (_) that consider as package private.
  • Dart tools can report only two kinds of problems. The first one is warnings that just indications of your code might not work, but they don’t prevent your program from executing. The second one is errors, it can be either compile-time or run-time and finally, it prevents the code from executing at all


That's the concept of dart. Now come where we can use this language.
Application of Dart
Dart is a scalable language. SO we write a simple script or full-featured app. we use this mainly 3 areas. Like-

Flutter - we can write a mobile app, that will run both Android and Ios.
Web - we can write an app that can run in modern web browser.
Dart VM - we can write command line app or server.


I think that's enough introduction about dart. So we can start learning.
In this blog, I will try to cover the basic of Dart.

So, Let's create a list of learning path of Dart programming Language.

What I will cover in this series tutorial -
  • Tutorial
    • Hello word
    • Variable
    • Data type
    • Function
    • Operators
    • String operation
    • Collection
    • Control flow statement
    • Classes
    • Methods
    • Enumerated types
    • Generics
    • Library and visibility
    • Asynchrony support
This is the learning path about dart. I will go through every topic.

That's the deal.
Stay connected with my blog. 

Read More