The main function

Any Dart program, whether it be a script or a Flutter application, must specify the main function.

void main() {
  ///some code
}

The file that is regarded as the "entry point" for your program must have this function, which instructs Dart where the program begins. This will often be in a file called main.dart.

Input Output

Input

The stdn.readLineSync() method in the Dart programming language allows you to read standard input from the user via the console. You must import the dart:io library from the Dart libraries in order to accept input from the console.

Taking a string input from user:

// importing dart:io file
import 'dart:io';
 
void main()
{
    // Reading name of the user
    String? name = stdin.readLineSync();
}

Output

The ouput can simply printed using the command print().

// importing dart:io file
import 'dart:io';
 
void main()
{
    print('Enter your name:');
    // Reading name of the user
    String? name = stdin.readLineSync();
    print('Hello $name');
}

Input:

Karrar

Output:

Hello Karrar

Data Type

String

Dart String is a character sequence. It is used to store the value of the text. You can use single or double quotations to enclose the string. The triple-quotes can be used to generate the multiline string. Because strings are immutable, you cannot change them after they have been created.

Syntax

The String keyword in Dart can be used to declare a string. Below is a list of the string declaration's syntax.

String msg1 = 'Welcome to Unicoding';   
String msg2 = "This is double-quoted string example.";   
String msg3 = '''line1  
line2  
line3''' 

String Concatenation

The + or += operator is used to merge the two string. The example is given below.

String str1 = 'Welcome To ';   
String str2 = "Unicoding";   
String str3 = str1+str2;  
  
print(str3);    

Output:

Welcome To Unicoding

String Interpolation

The string interpolation is a technique to manipulate the string and produce a new string by adding another value. String interpolation is done using the ${expression}. The corresponding values are used to replace the expressions. Let's clarify with the next example.

var x = 26;  
var y = 10;  
  
print("The sumation is  = ${x+y}");  
  
var name = "Peter";  
var fav_num = 101;  
     
print("My name is ${name}, my favorite number is ${fav_num}");  

Escape sequences

Escape sequences can be used to insert tab, new line, and etc into an output stream.
Here is an example of \n starting a new line and \t adding a tab in between the string:

String str1 = "First line \nSecond line";
print(str1);

String str2 = "First line \tSecond line";
print(str2);

Output

First line
Second line
First line    Second line

Raw String

A raw string can be used to avoid escaping only backslashes and dollars.

String str1 = "Hello \tWorld";
print(str1);

String str2 = r"Hello \nWorld";
print(str2);

Output:

Hello     World
Hello \nWorld

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Properties & Methods

Property/Method Description
isEmpty If the string is empty, it returns true.
Length It returns the length of the string including whitespace.
toLowerCase() It converts all characters of the given string in lowercase.
toUpperCase() It converts all characters of the given string in uppercase.
trim() It eliminates all whitespace from the given string.
replaceAll() It replaces all substring that matches the specified pattern with a given string.
isEmpty If the string is empty, it returns true.
split() It splits the string at matches of the specified delimiter and returns the list of the substring.
substring() It returns the substring from start index, inclusive to end index.
toString() It returns the string representation of the given object.
contains() To check if a string contains other string.

Dart Number

The Number is the data type that is used to hold the numeric value. In Dart, It can be two types:

  1. Integer
  2. Double

Integer

The term "integer" refers to a set of whole integers that may be expressed without a fractional component. For example - 24, 40, -3565, 0, etc. You can have a signed or unsigned integer. The integer value is represented as a range of non-decimal values, from -263 to 263. In Dart, integer values are declared using the int keyword.

Rules for the integer value

  • An integer value must be a digit.
  • An integer number shouldn't have any decimal points.
  • Both negative and positive numbers are possible.
int id = 504;
int id2 = -90;

Let's look at the example below:

int l = 5;
int w = 6;  
int area = l*w;    
print("The area of rectangle = $area");   

Dart Double

The Double number are the numbers that can be written with floating-point numbers or number with larger decimal points. The double keyword is used to declare Double value in Dart.

double root = 1.41234;  
double rupees  = 100000;  

Example:

int radius = 5;  
double pi = 3.14;  
double area = pi*r*r;    
print("The area of circle = ${area}");   

parse() function

The parse() function converts the numeric string to the number.

Let's see the example below:

double a = double.parse("20.56");  
int b = int.parse("10");  
 
print("The sum is = ${a+b}");  

Output:

30.56

Arithmetic Operators

Basic Operations: We can use (+, -, /. *) for simple operations.

int a = 2;
int b = 3;
 
// Adding a and b
var c = a + b;
print("Sum of a and b is $c");
 
// Subtracting a and b
var d = a - b;
print("The difference between a and b is $d");
 
// Using unary minus
var e = -d;
print("The negation of difference between a and b is $e");
 
// Multiplication of a and b
var f = a * b;
print("The product of a and b is $f");
 
// Division of a and b
var g = b / a;
print("The quotient of a and b is $g");

Output:

Sum of a and b is 5
The difference between a and b is -1
The negation of difference between a and b is 1
Product of a and b is 6
The quotient of a and b is 1.5

Increment & decrement: We can use (++, , +=, -=) for increment and decrement as follow:

int i = 0;
print(i);
print(i++);
print(i--);

Output:

0
1
0

Another example:

int i = 2;
i += 4;    // equivalent to i = i + 4;
print(i);
i -= 3;    //equivalent to i = i - 3;
print(i);

Output:

6
3

Remider : We can use % to returns the remainder of the division.

print(5 % 3);
print(9 % 4);
print(10 % 5);

Output:

2
1
0

Truncating division: Truncating division is division where a fractional result is converted to an integer by rounding towards zero. We use ~/ for this operation.

print(5 ~/ 3);
print(9 ~/ 4);
print(10 ~/ 5);

Output:

1
2
2

Arithmetic Operators Table

Operators Meaning
+ Add
Subtract
* Multiply
/ Divide
~/ Divide, returning an integer result
% Get the remainder of an integer division (modulo)
++ Increment
- - Decrement

Number Properties

Properties Description
hashcode It returns the hash code of the given number.
isFinite If the given number is finite, then it returns true.
isInfinite If the number infinite it returns true.
isNan If the number is non-negative then it returns true.
isNegative If the number is negative then it returns true.
sign It returns -1, 0, or 1 depending upon the sign of the given number.
isEven If the given number is an even then it returns true.
isOdd If the given number is odd then it returns true.

Number Methods

Method Description
abs() It gives the absolute value of the given number.
ceil() It gives the ceiling value of the given number.
floor() It gives the floor value of the given number.
compareTo() It compares the value with other number.
remainder() It gives the truncated remainder after dividing the two numbers.
round() It returns the round of the number.
toDouble() It gives the double equivalent representation of the number.
toInt() Returns the integer equivalent representation of the number.
toString() Returns the String equivalent representation of the number
truncate() Returns the integer after discarding fraction digits.

Boolean

Only the values true and false are allowed by the Boolean data type in DART. A Boolean literal is declared by the keyword bool in DART.

The following is the syntax for defining a Boolean variable in DART:

bool myVar = true;
bool myVar = false

Other examples

int i = 5;
bool isNagative = i.isNegative;
bool isOdd = i.isOdd;
bool smallNumber = i < 10;
bool largeNumber = i >= 100;
bool isFive = i == 5;
print(isNagative);
print(isOdd);
print(smallNumber);
print(largeNumber);
print(isFive);

Output

false
true
true
false
true

Static & Dynamic

To understand this concept first we need to know the difference between static and dynamic. The statically typed languages are those which check the variable types at compile time like C, C++, Swift, Kotlin. In static programming languages, data types are known and checked at compile time while in Dynamic programming languages data types are checked during run-time. Languages like JS, Python R.

Now let’s compare dart with the static and dynamic.

Random test = 1;
//Error Random is not a defined Type

// for a number value
int test = 1;
test = "1"; // Error can't assign string to int variable
var test2 = "1";
test = 1; // Error can't assign int value to a string variable

In our first test if we define a variable with an unknown type or without a dart type dart will throw an error at compile time before running the code it means dart checks the variable types at compile-time So we can say Dart is a statically typed programming language where variable types are known at compile-time in dart.

With dart code, you can enjoy the static and dynamic typed both at the same time. Dart offer a dynamic variable that is checked at runtime, you can store any type of data in dynamic at runtime.

dynamic test = 1;
test = "it's a dynamic type";
test = 0.4;

Lists

Dart List is similar to an array, which is the ordered collection of the objects. The most well-known and often utilized collection in any other programming language is the array. The JavaScript array literals resemble the Dart list.

Initialize the List

The list's declaration syntax is shown below.

List list1 = [10, 15, 20, 25, 30];
List list2 = ['Ali', 0, 1, true, 'baghdad'];
List<double> list3 = [0.1, 2, 3.6, 1.5];
List<String> list3 = ['a', 'b', 'c'];

All components must be kept inside the square bracket ([]) and separated by commas to form the Dart list (,).

  • list1 - It is the list variable that refers to the list object.
  • Index - Each element has its index number that tells the element position in the list. The index number is used to access the particular element from the list, such as list_name[index]. The list indexing starts from 0 to length-1 where length denotes the numbers of the element present in the list. For example, - The length of the above list is 4.
  • Elements - The List elements refers to the actual value or dart object stored in the given list.

Access elements

Elements can be accessed by specify the index of the element or by conditional property.

List list1 = [10, 15, 20, 25, 30];
print(list1.first);
print(list1.last);
print(list1[2]);
print(list1[4]);

print(list1.elementAt(1));

Output

10
30
20
30
15

where() Method

You may use this function to get a list containing elements that satisfy a condition.

List list1 = [10, 12, 20, 25, 33];
print(list1.where((element)=> element <= 20).toList());
print(list1.where((element)=> (element % 5) == 0).toList());

Output

[10, 12, 20]
[10, 20, 25]

firstWhere() Method

Return the first element that statify the condition.

List list1 = ['Ali Ahmed', 'Mustafa Mohammed', 'Salam Kareem', 'Akram Mustafa'];
print(list1.firstWhere((element)=> element.contains('Mustafa')));

Output

Mustafa Mohammed

Inserting Element

Dart provides four methods which are used to insert the elements into the lists. These methods are given below.

  • add()
  • addAll()
  • insert()
  • insertAll()

The add() Method

This method is used to insert the specified value at the end of the list. It can add one element at a time and returns the modified list object.

List list = [1, 2, 3];
print(list);
list.add(4);
print(list);

Output

[1, 2, 3]
[1, 2, 3, 4]

The addAll() Method

This method is used to insert the multiple values to the given list. Each value is separated by the commas and enclosed with a square bracket ([]). The syntax is given below.

List list = [1, 2, 3];
print(list);
list.addAll([4, 5, 6]);
print(list);

Output

[1, 2, 3]
[1, 2, 3, 4, 5, 6]

The insert() Method

The insert() method provides the facility to insert an element at specified index position. We can specify the index position for the value to be inserted in the list. The syntax is given below.

List list = [1, 2, 3];
print(list);
list.insert(1, 4);    // Add 4 at index 1
print(list);

Output

[1, 2, 3]
[1, 4, 2, 3]

The insertAll() Method

The insertAll() function is used to insert the multiple value at the specified index position. It accepts index position and list of values as an argument. The syntax is given below.

List list = [1, 2, 3];
print(list);
list.addAll(0, [4, 5, 6]);
print(list);

Output

[1, 2, 3]
[4, 5, 6, 1, 2, 3]

Updating List

The Dart provides the facility to update the list and we can modify the list by simply accessing its element and assign it a new value. The syntax is given below.

List list = [1, 2, 3];
print(list);
list[1] = 7;
print(list);

Output

[1, 2, 3]
[1, 7, 3]

Removing List Elements

The Dart provides following functions to remove the list elements.

  • remove()
  • removeAt()
  • removeLast()
  • removeRange()

The remove() Method

It removes one element at a time from the given list. It accepts element as an argument. It removes the first occurrence of the specified element in the list if there are multiple same elements. The syntax is given below.

List list = [1, 2, 3];
print(list);
list.remove(2);
print(list);

Output

[1, 2, 3]
[1, 3]

The removeAt() Method

It removes an element from the specified index position and returns it. The syntax is given below.

List list = [1, 2, 3];
print(list);
list.removeAt(0);
print(list);

Output

[1, 2, 3]
[2, 3]

The removeLast() Method

The removeLast() method is used to remove the last element from the given list. The syntax is given below.

List list = [1, 2, 3];
print(list);
list.removeLast();
print(list);

Output

[1, 2, 3]
[1, 2]

The removeRange() Method

This method removes the item within the specified range. It accepts two arguments - start index and end index. It eliminates all element which lies in between the specified range. The syntax is given below.

List list = [1, 2, 3, 4, 5, 6];
list.removeRange(2, 4);
print(list);

Output

[1, 2, 5, 6]

Iterating List elements

The Dart List can be iterated using the forEach method. Let's have a look at the following example.

List list1 = ["Baghdad","Basrah","Najaf","Arbil"];  
list1.forEach((element){  
    print(element);  
});  
Baghdad
Basrah
Najaf
Arbil

Properties

Properties Explanations
first It is used to get the first element in the given set.
isEmpty If the set does not contain any element, it returns true.
isNotEmpty If the set contains at least one element, it returns true.
length It returns the length of the given set.
last It is used to get the last element in the given set.

Set

It is the same as an list, but it doesn't allow storing the duplicate values. The set must contain unique values.

Set set = {1, 2, 3, 1, 2};  
print(set); 
set.add(3);
print(set);
{1, 2, 3}
{1, 2, 3}

Convert Type

Set can be converted to a List, and vice versa using toList() and toSet() methods.

List list = [1, 2, 3, 4, 2, 3];  
print(list); 
Set set = list.toSet();
print(set);
print(set.toList());
[1, 2, 3, 4, 2, 3]
{1, 2, 3}
[1, 2, 3]

Map

Dart Map is an object that stores data in the form of a key-value pair. Each value is associated with its key, and it is used to access its corresponding value. Both keys and values can be any type. In Dart Map, each key must be unique, but the same value can occur multiple times. The Map representation is quite similar to Python Dictionary. The Map can be declared by using curly braces {} ,and each key-value pair is separated by the commas(,). The value of the key can be accessed by using a square bracket([]).

Declaring a Dart Map

Dart Map can be defined as follow

example 1

 var student = {'name':'Ali','age':'22'};   
 print(student);   

Output

{name: Ali, age: 22}

example 2:

var student = {};   
student['name'] = 'ali';
student['age'] = '22';
print(student);   

Output

{name: Ali, age: 22}

Properties

Property Description
Keys Returns an iterable object representing keys
Values Returns an iterable object representing values
Length Returns the size of the Map
isEmpty Returns true if the Map is an empty Map
isNotEmpty Returns true if the Map is an empty Map

Methods

Method Description
addAll() Adds all key-value pairs of other to this map.
clear() Removes all pairs from the map.
remove() Removes key and its associated value, if present, from the map.
forEach() Applies f to each key-value pair of the map.

Control Flow Statement

To regulate the flow of a Dart program, control statements or a control flow statements are used. In all programming languages, these statements have an important role in determining whether or not other statements will be executed. In most cases, the code statement is executed sequentially. Depending on the given condition, we could need to execute or skip a group of statements, jump to another statement, or repeat the execution of the statements.

A control statement in Dart enables a smooth program flow. A Dart program can be altered, redirected, or repeated based on the application logic by using the control flow statements.

Categories of Flow Statement

Dart's control flow statements may be divided into the three categories listed below:

  • Decision-making statements
  • Looping statements
  • Jump statements

Decision-making statement

Dart provides following types of Decision-making statement.

  • If Statement
  • If-else Statements
  • If else if Statement
  • Switch Case Statement
// if - else bool isSuccessed = true; if(isSuccessed){ print('Operation Successed!.'); }else{ print('Failed'); } // If else if int i = 20; if(i < 10){ print('The number is small.'); }else if (i > 10 && i < 100){ print('The number is large); }else{ print('The number is very large'); } // Switch int weather = 48; switch(weather) { case weather < 0: { print('The weather is freezing.'); } break; case weather < 10: { print('The weather is cold'); } break; case weather < 20: { print('The weather is cool'); } break; case weather < 30: { print('The weather is fine'); } break; case weather < 40: { print('The weather is hot'); } break; case weather > 40: { print('Welocme in Iraq!'); } break; }

Dart Looping Statements

Dart looping statements are used to execute the block of code multiple-times for the given number of time until it matches the given condition.
Dart provides following types of the looping statements:

  • for loop
  • for-in loop
  • while loop
  • do while loop
// for for(int i = 0; i < 10; i++){ print('Current loop is $i'); } // for-in List cities = ['Baghdad', 'Erbil', 'Basra', 'Najaf']; for(String x in cities){ print('Current city is $x'); } // while loop int x = 5; while(x < 10){ print('The loop is not closed and the number is $x'); x++; } // do while int y = 20; do{ print(y); y++; }while(y == 10);

Dart Jump Statements

Jump statements are used to jump from another statement, or we can say that it transfers the execution to another statement from the c

continue

for(int i = 0; i <= 5; i++){ if(i == 3) continue; print(i); }

Output

0
1
2
4
5

break

for(int i = 0; i <= 1000; i++){ print(i); if(i == 4) break; }

Output

0
1
2
3
4

Enum

An enumeration is a set of values called as elements, members, etc. This is essential when we carried out the operation with the limited set of values available for variable. For example - you can think of the days of the month can only be one of the seven days - Sun, Mon, Tue, Wed, Thur, Fri, Sat.
Enums are used when we know all possible values at compile-time, such as choices on a menu, rounding modes, command-line flags, etc.

Initilizing the enum

//define an enumeration enum Level { easy, noraml, hard } //print all the values print(Level.values); //Define an Level Level myLevel = Level.easy; print(myLevel); print(myLevel.name); print(myLevel.index);

Output

[Level.easy, Level.noraml, Level.hard]
Level.easy
easy
0

Null Safety

When you opt into null safety, types in your code are non-nullable by default, meaning that variables can’t contain null unless you say they can. With null safety, your runtime null-dereference errors turn into edit-time analysis errors.

With null safety, all of the variables in the following code are non-nullable:

// In null-safe Dart, none of these can ever be null. int i = 42; String name = 'ahmed'; bool b = true;

To indicate that a variable might have the value null, just add ? to its type declaration:

int? i = null; String? name; bool? b;

We can use (!) on a nullable value to tell the compiler that the variable will not be null in this line. you should use it only when you 100% sure that the variable will not be null.

String? x; x = '5'; int.parse(x!);

Null-aware operators

Dart offers some handy operators for dealing with values that might be null. One is the ??= assignment operator, which assigns a value to a variable only if that variable is currently null:

int? a; // = null a ??= 3; print(a); //3. a ??= 5; print(a); //3.

Another null-aware operator is ??, which returns the expression on its left unless that expression’s value is null, in which case it evaluates and returns the expression on its right:

int? a; // = null print(a??7); //7. a = 5; print(a??7); //5.

Conditional property access

To guard access to a property or method of an object that might be null, put a question mark (?) before the dot (.):

myObject?.someProperty

The preceding code is equivalent to the following:

if(myObject == null) {return null;} else {return myObject.someProperty}

You can chain multiple uses of ?. together in a single expression:

myObject?.someProperty?.someValue

Functions

A dart function is a collection of codes that when put together, carry out a certain operation. It is used to divide the lengthy code into smaller modules so that it may be reused as required. Programs using functions are easier to read and debug. It strengthens the modular approach and increases code reuse.

Let's say we need to run operations repeatedly while the user inputs data in a basic calculator software. Each calculator operator can have a distinct function written for it. We may do repetitive operations like adding, subtracting, multiplying, and dividing without continually writing code by using the functions. By calling, we may utilize the functions more than once.

The function gives you the ability to run a code several times with various values. A function can be called anytime as its parameter and returns some value to where it called.

Let's understand the general syntax of the defining function:

  • return type - It can be any data type such as void, integer, float, etc. The return type must be matched with the returned * * value of the function.
  • function name - It should be an appropriate and valid identifier.
  • parameter list - It denotes the list of the parameters, which is necessary when we called a function.
  • return value - A function returns a value after complete its execution.
return_type func_name (parameter_list){ //some code return value; }

Define & Call Methods

// define method double circleArea(int radius){ double pi = 3.14; double area = radius * radius * pi; return area; } /// call the method int radius = 5; double area = circleArea(radius); print(area);

Output

78.5

It is not neccessary to return data. We can use methods to do something without return.

example:

void printValue(dynamic value){ print(value); } String text = 'Unicoding Bootcamp'; printValue(text);

Output

Unicoding Bootcamp

Optional Parameters

Optional parameters are parameters which don't have to be specified when calling given function. Optional parameters must be declared after required parameters. Additionally, optional parameters can have a default value, which is used once the function invocation doesn't specify it.

void printValue(dynamic v1, [dynamic v2, dynamic v3 = 'value 3']){ print(v1); if(v2 != null) print(v2); print(v3); } printValue('hello'); print('='*20); printValue('hello', 'world'); print('='*20); printValue('hello', 'world', '!');

Output

hello
value 3
====================
hello
world
value 3
====================
hello
world
!

Named Parameters

We define named parameters by listing them between curly brackets {}, e.g., {int a, int b, …}.
Named parameters are optional unless they’re explicitly marked as required. When calling a function, you can specify named arguments using paramName: value.
Here is the same sum function, but this time, we write it with named parameters.

void printValue({required dynamic v1, dynamic v2, dynamic v3 = 'value 3'}){ print(v1); if(v2 != null) print(v2); print(v3); } printValue(v1: 'hello'); print('='*20); printValue(v1: 'hello', v2:'world'); print('='*20); printValue(v1: 'hello', v2: 'world', v3: '!');

Output

hello
value 3
====================
hello
world
value 3
====================
hello
world
!

Asynchronous

Asynchronous operations let your program complete work while waiting for another operation to finish. Here are some common asynchronous operations:

Fetching data over a network.
Writing to a database.
Reading data from a file.

Such asynchronous computations usually provide their result as a Future. To interact with these asynchronous results, you can use the async and await keywords.

main() async { String response = await callApi(); print(response); } Future<String> callApi() async { await Future.delayed(Duration(seconds: 5)); return 'reponse'; }

To make a method asynchronous, we should add:

1- Change the return type (if exist) Future<Object> instead of Object.
2- Add async before the curly bracket.
3- add await before the asynchronous function.

Exceptions

Problems that occur while a program is being executed are referred to as exceptions.  When an exception occurs, the program's normal flow is interrupted, and the program or application terminates unexpectedly.

Using the catch Block

The try block embeds code that might possibly result in an exception. The on block is used when the exception type needs to be specified. The catch block is used when the handler needs the exception object.
Syntax

try { // code that might throw an exception } on Exception1 { // exception handling code } catch (e) { // exception handling } finally { // code that should always execute; irrespective of the exception }

You sould use (on) or (catch) or both. (finally) is optional.
example 1:

int x = 12; int y = 0; try { int res = x ~/ y; } catch(e) { print(e); }

example 2:

int x = 12; int y = 0; int res; try { res = x ~/ y; } on IntegerDivisionByZeroException { print('Cannot divide by zero'); } finally { print('Finally block executed'); }

Throwing an Exception

The follwoing example shows how to throw an exception:

main() { try { test_age(-2); } catch(e) { print(e); } } void test_age(int age) { if(age<0) { throw Exception('Age cannot be negative'); } }

Class

Dart is an object-oriented language. It supports object-oriented programming features like classes, interfaces, etc. A class encapsulates data for the object. Dart gives built-in support for this concept called class.

Declaring a Class

Use the class keyword to declare a class in Dart. A class definition starts with the keyword class followed by the class name; and the class body enclosed by a pair of curly braces. The syntax for the same is given below:

class Class_name { //fields //getters/setters //constructors //functions }

I will add the rest as soon as I can.
here is the example that we discusss in the last meeting.

class Person { String name; int age; String? address; static int currentYear = 2022; Person({required this.name, required this.age, this.address}); Person copyWith({ String? name, int? age, String? address, }) { return Person( name: name ?? this.name, age: this.age, address: address ?? this.address); } Map<String, dynamic> get toMap => {'name': name, 'age': age, 'address': address ?? 'No Address'}; static Person fromMap(Map<String, dynamic> data) => Person( name: data['name'], age: data['age'], address: data['address'], ); void toTitleCase(){ name = name.substring(0,1).toUpperCase() + name.substring(1).toLowerCase(); } set birthday(int year){ age = currentYear-year; } int get birthday => currentYear-age; }