Dart Programming with All topics and sub-topics

Dart Programming - Chapter #1 Topics Explained

This chapter seems to cover the fundamental building blocks of Dart programming. Let's go through each topic:

(1) Variables

  • Simple Explanation: Think of variables as labeled boxes where you can store information. These boxes have names (variable names) and hold different types of data (like numbers, text, etc.).

  • Subtopics:

    • What are Variables? Variables are used to store data that your program can use and manipulate. They are like containers that hold values.

    • Data Types: Dart is a strongly-typed language, meaning you generally specify the type of data a variable will hold. Common data types in Dart include:

      • int (Integers): Whole numbers (e.g., 10, -5, 0).

                int age = 30;
          int score = -100;
        

        content_copy download

        Use code with caution.Dart

      • double (Floating-point numbers): Numbers with decimal points (e.g., 3.14, -2.5).

                double price = 99.99;
          double temperature = 25.5;
        

        content_copy download

        Use code with caution.Dart

      • String (Text): Sequences of characters enclosed in single or double quotes (e.g., "hello", 'Dart').

                String name = "Alice";
          String message = 'Welcome to Dart!';
        

        content_copy download

        Use code with caution.Dart

      • bool (Boolean): Represents true or false values.

                bool isRaining = true;
          bool isLoggedIn = false;
        

        content_copy download

        Use code with caution.Dart

      • dynamic: A special type that can hold any type of data. Use it sparingly as it reduces type safety.

                dynamic something = "This is a string";
          something = 123; // You can change the type later
        

        content_copy download

        Use code with caution.Dart

      • var: Dart can often infer the data type. You can use var and Dart will figure out the type based on the value you assign.

                var city = "London"; // Dart infers 'city' is a String
          var count = 5;      // Dart infers 'count' is an int
        

        content_copy download

        Use code with caution.Dart

    • Declaration and Initialization:

              // Declaration and Initialization together
        String studentName = "Bob";
        int numberOfBooks = 5;

        // Declaration first, then initialization
        double pi; // Declaration
        pi = 3.14159; // Initialization

content_copy download

Use code with caution.Dart

  • final and const: Keywords for variables that cannot be changed after they are initialized.

    • final: Value is set once when the variable is accessed for the first time or at runtime.

              final String appName = "My Dart App"; // Value set at runtime
      

      content_copy download

      Use code with caution.Dart

    • const: Value must be known at compile-time (when you write the code). Used for values that are truly constant throughout the program.

              const double gravity = 9.8; // Value known when you write the code
      

      content_copy download

      Use code with caution.Dart

(2) Strings

  • Simple Explanation: Strings are just text in programming. Think of them as words, sentences, or any sequence of characters.

  • Subtopics:

    • What are Strings? Strings are used to represent text. They are sequences of characters.

    • String Literals: How you write strings in your code:

      • Single quotes '...':

                String singleQuoteString = 'Hello';
        

        content_copy download

        Use code with caution.Dart

      • Double quotes "...":

                String doubleQuoteString = "World";
        

        content_copy download

        Use code with caution.Dart

      • Triple quotes '''...''' or """...""": For multi-line strings.

                String multiLineString = '''
          This is a string
          that spans multiple lines.
          ''';
          String anotherMultiLine = """
          You can also use
          double triple quotes.
          """;
        

        content_copy download

        Use code with caution.Dart

    • String Interpolation: Inserting variables or expressions inside strings. Use the $ symbol.

              String name = "Charlie";
        int age = 25;
        String message = "My name is $name and I am $age years old.";
        print(message); // Output: My name is Charlie and I am 25 years old.
      
        // For more complex expressions, use ${expression}
        int apples = 3;
        int oranges = 2;
        String fruitCount = "Total fruits: ${apples + oranges}";
        print(fruitCount); // Output: Total fruits: 5
      

      content_copy download

      Use code with caution.Dart

    • String Concatenation: Joining strings together using the + operator.

              String firstName = "John";
        String lastName = "Doe";
        String fullName = firstName + " " + lastName; // Adding a space in between
        print(fullName); // Output: John Doe
      

      content_copy download

      Use code with caution.Dart

    • String Methods (Basic): Dart provides many built-in functions to work with strings (methods). Here are a few examples:

      • length: Gets the number of characters in a string.

                String text = "Dart";
          int length = text.length; // length will be 4
        

        content_copy download

        Use code with caution.Dart

      • toUpperCase() and toLowerCase(): Convert case.

                String lower = "hello";
          String upper = lower.toUpperCase(); // upper will be "HELLO"
          String original = upper.toLowerCase(); // original will be "hello"
        

        content_copy download

        Use code with caution.Dart

      • substring(startIndex, endIndex): Extracts a part of the string.

                String longText = "Programming";
          String sub = longText.substring(0, 4); // sub will be "Prog" (from index 0 up to, but not including, index 4)
        

        content_copy download

        Use code with caution.Dart

(3) Conditions

  • Simple Explanation: Conditions are like making decisions in your program. "If" something is true, "then" do this, "otherwise" (else) do something else.

  • Subtopics:

    • if statement: Executes a block of code only if a condition is true.

              int temperature = 20;
        if (temperature > 15) {
          print("It's warm enough.");
        }
      

      content_copy download

      Use code with caution.Dart

    • if-else statement: Executes one block of code if the condition is true, and another block if it's false.

              int age = 17;
        if (age >= 18) {
          print("You are an adult.");
        } else {
          print("You are a minor.");
        }
      

      content_copy download

      Use code with caution.Dart

    • if-else if-else statement: For checking multiple conditions in sequence.

              int score = 75;
        if (score >= 90) {
          print("Grade A");
        } else if (score >= 80) {
          print("Grade B");
        } else if (score >= 70) {
          print("Grade C");
        } else {
          print("Grade D or lower");
        }
      

      content_copy download

      Use code with caution.Dart

    • Comparison Operators: Used to create conditions (expressions that evaluate to true or false).

      • \== (equal to)

      • != (not equal to)

      • \> (greater than)

      • < (less than)

      • \>= (greater than or equal to)

      • <= (less than or equal to)

              int a = 10;
        int b = 5;
        print(a == b); // false
        print(a != b); // true
        print(a > b);  // true
        print(a < b);  // false

content_copy download

Use code with caution.Dart

  • Logical Operators: Used to combine conditions.

              bool isSunny = true;
        bool isWarm = true;
        if (isSunny && isWarm) { // Both must be true
          print("It's a nice day!");
        }

        bool hasDiscount = true;
        bool isStudent = false;
        if (hasDiscount || isStudent) { // At least one must be true
          print("You get a discount!");
        }

        bool isLoggedIn = false;
        if (!isLoggedIn) { // Not logged in (isLoggedIn is false, !false is true)
          print("Please log in.");
        }

content_copy download

Use code with caution.Dart

(4) Loops

  • Simple Explanation: Loops are for repeating actions. Instead of writing the same code multiple times, you can use a loop to execute a block of code again and again until a condition is met.

  • Subtopics:

    • for loop: Used when you know how many times you want to repeat something, or when you want to iterate over a sequence.

      • Basic for loop:

                for (int i = 0; i < 5; i++) { // i starts at 0, loops as long as i < 5, increments i by 1 each time
            print("Iteration: $i");
          }
          // Output:
          // Iteration: 0
          // Iteration: 1
          // Iteration: 2
          // Iteration: 3
          // Iteration: 4
        

        content_copy download

        Use code with caution.Dart

      • for...in loop: Iterates over elements of a collection (like a list or string).

                List<String> colors = ["red", "green", "blue"];
          for (String color in colors) {
            print("Color: $color");
          }
          // Output:
          // Color: red
          // Color: green
          // Color: blue
        
          String message = "Hello";
          for (String char in message.split('')) { // Split string into characters
            print("Character: $char");
          }
          // Output:
          // Character: H
          // Character: e
          // Character: l
          // Character: l
          // Character: o
        

        content_copy download

        Use code with caution.Dart

    • while loop: Repeats a block of code as long as a condition is true. You don't always know how many times it will run beforehand.

              int count = 0;
        while (count < 3) {
          print("Count is: $count");
          count++; // Increment count to eventually make the condition false
        }
        // Output:
        // Count is: 0
        // Count is: 1
        // Count is: 2
      

      content_copy download

      Use code with caution.Dart

    • do-while loop: Similar to while, but the code block is executed at least once before the condition is checked.

              int number = 5;
        do {
          print("Number is: $number");
          number--;
        } while (number > 0); // Condition is checked after the first execution
        // Output:
        // Number is: 5
        // Number is: 4
        // Number is: 3
        // Number is: 2
        // Number is: 1
      

      content_copy download

      Use code with caution.Dart

    • break and continue: Control flow within loops.

      • break: Immediately exits the loop.

                for (int i = 0; i < 10; i++) {
            if (i == 5) {
              break; // Exit the loop when i is 5
            }
            print("Number: $i");
          }
          // Output (stops at 4):
          // Number: 0
          // Number: 1
          // Number: 2
          // Number: 3
          // Number: 4
        

        content_copy download

        Use code with caution.Dart

      • continue: Skips the rest of the current iteration and goes to the next iteration of the loop.

                for (int i = 0; i < 5; i++) {
            if (i == 2) {
              continue; // Skip iteration when i is 2
            }
            print("Number: $i");
          }
          // Output (skips 2):
          // Number: 0
          // Number: 1
          // Number: 3
          // Number: 4
        

        content_copy download

        Use code with caution.Dart

(5) Functions

  • Simple Explanation: Functions are reusable blocks of code that perform a specific task. Think of them like mini-programs within your main program. You give them input (arguments), they do something, and they might give you output (return value).

  • Subtopics:

    • What are Functions? Functions help you organize code, make it reusable, and easier to understand.

    • Function Definition: Creating a function. It usually has:

      • Return Type: What kind of data the function will give back (or void if it doesn't return anything).

      • Function Name: A name to identify and call the function.

      • Parameters (optional): Input values the function can receive.

      • Function Body: The code that the function executes (inside curly braces {}).

              // Function that adds two numbers and returns the sum (return type is int)
        int add(int num1, int num2) { // 'int' return type, 'add' function name, 'num1' and 'num2' parameters
          int sum = num1 + num2;
          return sum; // Return the sum
        }

        // Function that prints a greeting (no return value, so return type is 'void')
        void greet(String name) { // 'void' return type, 'greet' function name, 'name' parameter
          print("Hello, $name!");
        }

content_copy download

Use code with caution.Dart

  • Function Call: Using (executing) a function. You use the function name followed by parentheses () and provide any necessary arguments.

            int result = add(5, 3); // Calling the 'add' function with arguments 5 and 3, storing the returned value in 'result'
      print("Sum: $result"); // Output: Sum: 8
    
      greet("Alice"); // Calling the 'greet' function with argument "Alice"
      // Output: Hello, Alice!
    

    content_copy download

    Use code with caution.Dart

  • Return Values: Functions can send back a result using the return keyword. If a function has a return type other than void, it must return a value of that type.

            int multiply(int a, int b) {
        return a * b; // Returns the product of a and b
      }
    
      int product = multiply(4, 6); // 'product' will store the returned value (24)
    

    content_copy download

    Use code with caution.Dart

  • Parameters (Arguments): Input values passed to a function.

    • Positional Parameters: Arguments are passed based on their position in the function call. (These are the default).

              void printDetails(String name, int age) { // 'name' is first, 'age' is second
          print("Name: $name, Age: $age");
        }
        printDetails("Bob", 28); // "Bob" is for 'name', 28 is for 'age'
      

      content_copy download

      Use code with caution.Dart

    • Named Parameters: Arguments are passed using their names. Make code more readable, especially with many parameters. Use curly braces {} in the function definition and specify names when calling.

              void setVolume({int level = 50}) { // 'level' is a named parameter with a default value of 50
          print("Volume level set to: $level");
        }
      
        setVolume(level: 75); // Calling with named parameter 'level'
        setVolume();        // Calling without argument, uses default value (50)
      

      content_copy download

      Use code with caution.Dart

    • Optional Parameters: Parameters that don't have to be provided when calling the function. Can be positional or named. Use square brackets [] for optional positional, and curly braces {} with default values for optional named (as shown above in named parameters example).

              // Optional positional parameter (lastName is optional)
        String getFullName(String firstName, [String? lastName]) { // 'String?' means lastName can be String or null
          if (lastName != null) {
            return "$firstName $lastName";
          } else {
            return firstName;
          }
        }
      
        print(getFullName("Alice", "Smith")); // Output: Alice Smith
        print(getFullName("Alice"));        // Output: Alice (lastName is not provided, so it's null)
      

      content_copy download

      Use code with caution.Dart

  • Arrow Functions (Shorthand for simple functions): A concise way to define functions with a single expression. Use =>.

            int square(int number) => number * number; // Arrow function for squaring a number
    
      int result = square(7); // result will be 49
    

    content_copy download

    Use code with caution.Dart

(6) Lists

  • Simple Explanation: Lists are ordered collections of items. Think of them like shopping lists or to-do lists – you have a sequence of things in a specific order. In Dart, lists can hold items of the same type or different types (though it's usually better to keep them of the same type for clarity).

  • Subtopics:

    • What are Lists? Lists are used to store multiple values in a single variable, maintaining the order of items.

    • Creating Lists:

      • List Literals (most common): Using square brackets [].

                List<int> numbers = [1, 2, 3, 4, 5]; // List of integers
          List<String> fruits = ["apple", "banana", "orange"]; // List of strings
          List mixedList = [1, "hello", true, 3.14]; // List with mixed types (use sparingly)
        

        content_copy download

        Use code with caution.Dart

      • Using List() constructor: Less common for simple lists, but can be used to create lists with specific properties.

                List<int> emptyList = List.empty(); // Creates an empty list
          List<int> fixedLengthList = List.filled(5, 0); // List of 5 elements, all initialized to 0
        

        content_copy download

        Use code with caution.Dart

    • Accessing List Elements: Use indices (positions) to get elements. Indices start from 0 for the first element.

              List<String> colors = ["red", "green", "blue"];
        String firstColor = colors[0]; // firstColor will be "red" (index 0)
        String secondColor = colors[1]; // secondColor will be "green" (index 1)
        String thirdColor = colors[2];  // thirdColor will be "blue" (index 2)
        // colors[3]; // Error! Index out of range (list only has indices 0, 1, 2)
      

      content_copy download

      Use code with caution.Dart

    • Adding and Removing Elements:

      • add(element): Adds an element to the end of the list.

                List<String> animals = ["dog", "cat"];
          animals.add("elephant"); // animals is now ["dog", "cat", "elephant"]
        

        content_copy download

        Use code with caution.Dart

      • insert(index, element): Inserts an element at a specific index.

                List<String> cities = ["London", "Paris"];
          cities.insert(1, "Berlin"); // cities is now ["London", "Berlin", "Paris"] (inserted at index 1)
        

        content_copy download

        Use code with caution.Dart

      • remove(element): Removes the first occurrence of an element from the list.

                List<String> items = ["apple", "banana", "apple"];
          items.remove("apple"); // items is now ["banana", "apple"] (first "apple" removed)
        

        content_copy download

        Use code with caution.Dart

      • removeAt(index): Removes the element at a specific index.

                List<String> names = ["Alice", "Bob", "Charlie"];
          names.removeAt(1); // names is now ["Alice", "Charlie"] (element at index 1, "Bob", removed)
        

        content_copy download

        Use code with caution.Dart

    • List Properties and Methods (Basic):

      • length: Gets the number of elements in the list.

                List<int> numbers = [10, 20, 30];
          int count = numbers.length; // count will be 3
        

        content_copy download

        Use code with caution.Dart

      • isEmpty and isNotEmpty: Check if the list is empty or not.

                List<int> emptyList = [];
          print(emptyList.isEmpty);    // true
          print(emptyList.isNotEmpty); // false
        
          List<int> nonEmptyList = [1, 2];
          print(nonEmptyList.isEmpty);    // false
          print(nonEmptyList.isNotEmpty); // true
        

        content_copy download

        Use code with caution.Dart

      • clear(): Removes all elements from the list, making it empty.

                List<String> data = ["item1", "item2"];
          data.clear(); // data is now an empty list []
        

        content_copy download

        Use code with caution.Dart

    • Iterating through Lists: Using loops to go through each element.

      • for loop with index:

                List<String> fruits = ["apple", "banana", "orange"];
          for (int i = 0; i < fruits.length; i++) {
            print("Fruit at index $i: ${fruits[i]}");
          }
          // Output:
          // Fruit at index 0: apple
          // Fruit at index 1: banana
          // Fruit at index 2: orange
        

        content_copy download

        Use code with caution.Dart

      • for...in loop (more concise):

                List<String> fruits = ["apple", "banana", "orange"];
          for (String fruit in fruits) {
            print("Fruit: $fruit");
          }
          // Output:
          // Fruit: apple
          // Fruit: banana
          // Fruit: orange
        

        content_copy download

        Use code with caution.Dart

(7) Map

  • Simple Explanation: Maps are collections of key-value pairs. Think of a dictionary where you look up a word (the key) to find its definition (the value). Keys must be unique within a map, and they are used to access the associated values.

  • Subtopics:

    • What are Maps? Maps store data in pairs of keys and values. Keys are like labels to find values.

    • Creating Maps:

      • Map Literals (most common): Using curly braces {} with key-value pairs separated by colons :.

                Map<String, String> countryCodes = { // Key type String, Value type String
            "USA": "United States",
            "GBR": "United Kingdom",
            "JPN": "Japan"
          };
        
          Map<String, int> ages = { // Key type String, Value type int
            "Alice": 30,
            "Bob": 25,
            "Charlie": 35
          };
        
          Map mixedMap = { // Mixed types for keys and values (use sparingly)
            1: "one",
            "two": 2,
            true: "yes"
          };
        

        content_copy download

        Use code with caution.Dart

      • Using Map() constructor:

                Map<String, String> emptyMap = Map(); // Creates an empty map
        

        content_copy download

        Use code with caution.Dart

    • Accessing Map Values: Use the key within square brackets [] to get the associated value.

              Map<String, String> countryCodes = {
          "USA": "United States",
          "GBR": "United Kingdom",
          "JPN": "Japan"
        };
      
        String usaName = countryCodes["USA"]; // usaName will be "United States"
        String ukName = countryCodes["GBR"];  // ukName will be "United Kingdom"
        // String franceName = countryCodes["FRA"]; // Will return null because "FRA" key is not in the map
      

      content_copy download

      Use code with caution.Dart

    • Adding and Updating Map Entries:

      • Adding/Updating: Use the key in square brackets and assign a value. If the key already exists, its value is updated; if not, a new key-value pair is added.

                Map<String, String> cities = {"USA": "New York"};
          cities["GBR"] = "London"; // Adds "GBR": "London"
          cities["USA"] = "Washington D.C."; // Updates value for "USA"
          print(cities); // Output: {USA: Washington D.C., GBR: London}
        

        content_copy download

        Use code with caution.Dart

    • Removing Map Entries:

      • remove(key): Removes the entry associated with the given key. Returns the value that was removed, or null if the key wasn't found.

                Map<String, int> scores = {"Alice": 85, "Bob": 92, "Charlie": 78};
          int? removedScore = scores.remove("Bob"); // Removes "Bob" entry, removedScore will be 92
          print(scores); // Output: {Alice: 85, Charlie: 78}
        

        content_copy download

        Use code with caution.Dart

    • Map Properties and Methods (Basic):

      • length: Gets the number of key-value pairs in the map.

                Map<String, String> dataMap = {"key1": "value1", "key2": "value2"};
          int size = dataMap.length; // size will be 2
        

        content_copy download

        Use code with caution.Dart

      • isEmpty and isNotEmpty: Check if the map is empty or not.

                Map<String, String> emptyMap = {};
          print(emptyMap.isEmpty);    // true
          print(emptyMap.isNotEmpty); // false
        
          Map<String, String> nonEmptyMap = {"a": "b"};
          print(nonEmptyMap.isEmpty);    // false
          print(nonEmptyMap.isNotEmpty); // true
        

        content_copy download

        Use code with caution.Dart

      • keys: Returns an iterable (like a list) of all keys in the map.

      • values: Returns an iterable of all values in the map.

                Map<String, int> ages = {"Alice": 30, "Bob": 25};
          Iterable<String> mapKeys = ages.keys; // keys will be ("Alice", "Bob")
          Iterable<int> mapValues = ages.values; // values will be (30, 25)
        
          print(mapKeys.toList());   // Convert to list to print: [Alice, Bob]
          print(mapValues.toList()); // Convert to list to print: [30, 25]
        

        content_copy download

        Use code with caution.Dart

      • containsKey(key): Checks if the map contains a specific key.

      • containsValue(value): Checks if the map contains a specific value.

                Map<String, int> ages = {"Alice": 30, "Bob": 25};
          print(ages.containsKey("Alice")); // true
          print(ages.containsKey("Charlie")); // false
          print(ages.containsValue(25)); // true
          print(ages.containsValue(40)); // false
        

        content_copy download

        Use code with caution.Dart

      • clear(): Removes all entries from the map, making it empty.

                Map<String, String> dataMap = {"a": "b", "c": "d"};
          dataMap.clear(); // dataMap is now an empty map {}
        

        content_copy download

        Use code with caution.Dart

    • Iterating through Maps:

      • Using forEach: A concise way to iterate over key-value pairs.

                Map<String, String> products = {"apple": "fruit", "car": "vehicle"};
          products.forEach((key, value) { // 'key' and 'value' are parameters for each entry
            print("Key: $key, Value: $value");
          });
          // Output:
          // Key: apple, Value: fruit
          // Key: car, Value: vehicle
        

        content_copy download

        Use code with caution.Dart

      • Using for...in with entries: More explicit way to access entries.

                Map<String, String> products = {"apple": "fruit", "car": "vehicle"};
          for (var entry in products.entries) { // 'entry' is a MapEntry object
            print("Key: ${entry.key}, Value: ${entry.value}");
          }
          // Output: (same as above)
        

        content_copy download

        Use code with caution.Dart

(8) Classes

  • Simple Explanation: Classes are blueprints for creating objects. Think of a class like a cookie cutter and objects as the cookies. The cookie cutter (class) defines the shape and properties, and each cookie (object) is a real instance of that shape. Classes are fundamental to Object-Oriented Programming (OOP).

  • Subtopics:

    • What are Classes and Objects?

      • Class: A template or blueprint for creating objects. It defines the properties (data) and methods (actions) that objects of that class will have.

      • Object (Instance): A specific realization of a class. It's a concrete entity created based on the class blueprint.

    • Defining a Class: Use the class keyword.

              class Dog { // Class name 'Dog' (PascalCase convention)
          // Properties (fields/attributes)
          String name;
          String breed;
          int age;
      
          // Constructor (special method to create objects)
          Dog(String name, String breed, int age) {
            this.name = name; // 'this' refers to the current object
            this.breed = breed;
            this.age = age;
          }
      
          // Methods (functions that objects can perform)
          void bark() {
            print("Woof!");
          }
      
          void displayInfo() {
            print("Name: ${this.name}, Breed: ${this.breed}, Age: ${this.age}");
          }
        }
      

      content_copy download

      Use code with caution.Dart

    • Creating Objects (Instances): Use the class name followed by parentheses () to create an object. This is called instantiation.

              void main() {
          // Creating objects of the 'Dog' class
          Dog myDog = Dog("Buddy", "Golden Retriever", 3); // Calling the constructor
          Dog anotherDog = Dog("Lucy", "Labrador", 5);
      
          // Accessing object properties (using dot notation '.')
          print(myDog.name); // Output: Buddy
          print(anotherDog.breed); // Output: Labrador
      
          // Calling object methods
          myDog.bark();      // Output: Woof!
          anotherDog.displayInfo(); // Output: Name: Lucy, Breed: Labrador, Age: 5
        }
      

      content_copy download

      Use code with caution.Dart

    • Properties (Fields/Attributes): Variables defined inside a class that hold data associated with objects.

      • In the Dog class example, name, breed, and age are properties.
    • Methods (Functions within a Class): Functions defined inside a class that define the behavior of objects. They can operate on the object's properties.

      • In the Dog class example, bark() and displayInfo() are methods.
    • Constructors: Special methods with the same name as the class. They are automatically called when you create a new object of the class. Constructors are used to initialize the object's properties.

      • The Dog(String name, String breed, int age) part in the Dog class is a constructor.

      • Default Constructor: If you don't define a constructor, Dart provides a default constructor with no parameters.

      • Custom Constructors: You can define constructors with parameters to initialize objects in a specific way (like in the Dog example).

    • this Keyword: Inside a class method or constructor, this refers to the current object being worked with. It's often used to distinguish between object properties and method/constructor parameters that have the same name.

      • In the Dog constructor, this.name = name; assigns the value of the constructor parameter name to the object's property name.

(9) Async and Await (Asynchronous Programming)

  • Simple Explanation: Imagine you order food at a restaurant. You don't just stand there blocking everything until your food is ready. You do other things (like talk to friends, read a book) while waiting. Asynchronous programming in Dart is similar. It allows your program to start a long-running task (like fetching data from the internet, reading a file) and continue doing other things without waiting for that task to finish immediately. When the long task is done, your program gets notified and can process the result.

  • Subtopics:

    • What is Asynchronous Programming? Programming that allows tasks to run independently without blocking the main program flow. This is crucial for tasks that might take time, like network requests or file operations, to keep your app responsive.

    • Future: Represents the eventual result of an asynchronous operation. Think of it as a placeholder for a value that will be available sometime in the future. A Future can be in one of three states:

      • Pending: The operation is still in progress.

      • Completed with a value: The operation finished successfully, and the Future holds the result.

      • Completed with an error: The operation failed, and the Future holds an error/exception.

    • async Keyword: Marks a function as asynchronous. A function declared as async implicitly returns a Future. Inside an async function, you can use await.

              // Function that simulates a delayed task (like fetching data)
        Future<String> fetchData() async { // 'async' keyword, return type Future<String>
          await Future.delayed(Duration(seconds: 2)); // Simulate 2 seconds delay
          return "Data fetched successfully!"; // Return value (String) wrapped in a Future
        }
      

      content_copy download

      Use code with caution.Dart

    • await Keyword: Used inside an async function. It pauses the execution of that function until the Future it's waiting on completes (either with a value or an error).

              void main() async { // 'main' function can also be async
          print("Starting data fetch...");
          String result = await fetchData(); // 'await' waits for fetchData() to complete
          print(result); // Print the result when fetchData() is done
          print("Data processing complete.");
        }
      
        // Output (approximately):
        // Starting data fetch...
        // (waits for 2 seconds)
        // Data fetched successfully!
        // Data processing complete.
      

      content_copy download

      Use code with caution.Dart

      • Without await, fetchData() would return a Future object immediately, and the result variable would hold a Future, not the actual string result. await is essential to get the value out of the Future when it's ready.
    • Error Handling with async and await: Use try-catch blocks to handle potential errors in asynchronous operations.

              Future<String> fetchDataWithError() async {
          await Future.delayed(Duration(seconds: 1));
          throw Exception("Failed to fetch data!"); // Simulate an error
        }
      
        void main() async {
          try {
            print("Starting data fetch...");
            String result = await fetchDataWithError(); // Might throw an exception
            print(result); // This line will not be reached if there's an error
          } catch (e) {
            print("Error occurred: $e"); // Catch and handle the error
          } finally {
            print("Fetch operation finished (with or without error)."); // Optional 'finally' block
          }
        }
      
        // Output (approximately):
        // Starting data fetch...
        // (waits for 1 second)
        // Error occurred: Exception: Failed to fetch data!
        // Fetch operation finished (with or without error).
      

      content_copy download

      Use code with caution.Dart

(10) File Handling

  • Simple Explanation: File handling is about reading and writing data to files on your computer's storage. Your program can read information from files (like settings, text, data) and can save information to files (like user data, logs, generated content).

  • Subtopics:

    • What is File Handling? Interacting with files to store and retrieve data persistently.

    • dart:io Library: Dart's built-in library for input/output operations, including file handling. You need to import it: import 'dart:io';

    • Reading from a File:

      • File class: Represents a file. Create a File object to work with a specific file.

      • readAsString() method: Reads the entire content of a text file as a String (asynchronously, returns a Future<String>).

              import 'dart:io';

        void readFileContent() async {
          File myFile = File('my_document.txt'); // Assuming 'my_document.txt' is in the same directory

          try {
            String contents = await myFile.readAsString(); // Asynchronous read
            print("File contents:\n$contents");
          } catch (e) {
            print("Error reading file: $e");
          }
        }

        void main() {
          readFileContent();
        }

content_copy download

Use code with caution.Dart

  • readAsLines() method: Reads the file line by line and returns a Future<List<String>> (a list of strings, where each string is a line).

            // ... (import 'dart:io'; and similar setup as above)
    
      void readFileLines() async {
        File myFile = File('my_document.txt');
        try {
          List<String> lines = await myFile.readAsLines();
          print("File lines:");
          for (String line in lines) {
            print(line);
          }
        } catch (e) {
          print("Error reading file lines: $e");
        }
      }
    
      void main() {
        readFileLines();
      }
    

    content_copy download

    Use code with caution.Dart

    • Writing to a File:
  • writeAsString(content) method: Writes a string to a file. You can choose to append to the file or overwrite it. (Asynchronous, returns a Future<File>).

            import 'dart:io';
    
      void writeFileContent() async {
        File myFile = File('output.txt');
    
        try {
          await myFile.writeAsString("This is some text to write to the file.\n"); // Overwrites file content
          await myFile.writeAsString("Appending more text.\n", mode: FileMode.append); // Appends to the file
          print("Text written to file.");
        } catch (e) {
          print("Error writing to file: $e");
        }
      }
    
      void main() {
        writeFileContent();
      }
    

    content_copy download

    Use code with caution.Dart

    • FileMode.append: Used in writeAsString to append to an existing file instead of overwriting it.

    • FileMode.write (default): Overwrites the file (or creates it if it doesn't exist).

    • File Paths: Specifying the location of a file.
  • Relative Paths: Paths relative to the location of your Dart script (e.g., 'my_document.txt', 'data/settings.json').

  • Absolute Paths: Full paths from the root of the file system (e.g., '/home/user/documents/my_document.txt' on Linux/macOS, 'C:\\Users\\User\\Documents\\my_document.txt' on Windows). Using relative paths is generally more portable.

    • Error Handling (for File Operations): File operations can fail (file not found, permission issues, etc.). Always use try-catch blocks to handle potential errors gracefully. See the try-catch examples in reading and writing above.

Important Notes:

  • Examples Assume Text Files: The file handling examples focus on reading and writing text files (.txt). Dart can also handle binary files, but that's a bit more advanced.

  • Asynchronous Operations: File operations (and network operations) in Dart are typically asynchronous to prevent blocking the main program thread. This is why async and await are used with file methods like readAsString() and writeAsString().

  • File Paths: Be careful with file paths. Make sure the files you are trying to read or write exist in the expected location, or handle potential "file not found" errors.

This detailed explanation should give you a solid understanding of the topics covered in "Dart Programming Chp#1." Remember to practice with code examples to solidify your learning! Let me know if you have any more questions.