Category: 6. Advance Topics

https://cdn3d.iconscout.com/3d/premium/thumb/3d-software-settings-icon-download-in-png-blend-fbx-gltf-file-formats–setting-configuration-preferences-printing-pack-science-technology-icons-8549424.png?f=webp

  • Collection

    Dart doesn’t support the array to store the data, unlike the other programming language. We can use the Dart collection in place of array data structure. We can enable the other classes of the collection in our Dart script by using the dart::core library.

    Dart collection can be classified as follows.

    Dart CollectionDescription
    ListA list is the collection of the ordered group of collection. The dart::core library offers the list class that allows us to create and modify the list. It provides the following types of lists.Fixed Length List – We cannot change the list’s length at runtime.Growable List – We can change the length of the list at run-time.
    SetA set is the collection of the objects in which each object can be declared at once. The dart::core library offers the Set class to use its facilities.
    MapsThe maps are the collection of the key-value pair of data. Each value is stored with a particular key. The key and value can be any type in the dart. A Map is a dynamic collection. We can say that map can be modified at the run-time. The dart::core library makes available the Map class to work with it.
    QueueA queue is the collection of the where data stores in the first-in-first-out format. It can be manipulated at both ends. Simply, we can enter the element from one end and delete it from another end.

    Iterating Collections

    The dart::core library provides the iterator class, which enables the easy collection traversal. As we know that, every collection contains an iterator property. This property returns an iterator that point to the objects in the collection. Let’s understand the following example.

    Example –

    import 'dart:collection';   
    
    void main() {   
    
       Queue que = new Queue();   
    
       que.addAll([10,20,30]);    
    
       Iterator i= que.iterator;   
    
         
    
       while(i.moveNext()) {   
    
          print(i.current);   
    
       }   
    
    } 

      Output

      10
      20
      30
      

      Explanation:

      In the above code, the moveNext() function returned the Boolean value that indicating whether there is a subsequent entry. The current property of the returns the object of that iterator currently points to.

      HashMap <K, V Class>

      The HashMap class is based on the implementation of the Map. As we discussed earlier, the key must be unique and must have consistent Object == (equal to operator) and Object.hashCode implementations. We can also use null as a key. The elements in the Map may in any order. The iteration order only changes if the map is modified. If we iterate the map, the value of the map is iterated in the same order as their associated key.

    1. Typedef

      In Dart, the typedef is used to generate an alias for function type that we can use it as type annotation for declaring variables and return types of that function type. An alias of function type can be used as type annotation in variable declaration or function return type. A typedef stores the type information when we assigned the function type to a variable.

      Declaring a typedef

      typedef keyword is used to create an alias for function that will be the same as the actual functions. We can also create a function prototype with a list of parameters. The syntax is given below.

      Syntax:

      typedef function_name(parameters)   

      Example –

      Let’s create an alias of MultiOperation(int n1, int n2) that contains two parameters of the integer type.

      typedef MultiOperation(int n1, int n2);   // function signature  

      Assigning typedef Variable

      We can assign any function with the same parameter to the typedef variable. The syntax is given below.

      Syntax:

      type_def var_name = function_name;  

      Let’s understand the following example, where we define the two functions with the same signature as the MultiOperation.

      Sum(int n1, int n2) {  
      
            print("Sum of the two number:${n1+n2}");  
      
      }  
      
      Sub(int n1, intn2 ) {  
      
            print("Subtraction of the two number:${n1-n2}");  
      
         
      
      }  

        Calling Function with typedef

        We can invoke function by passing the same parameter by using the typdef variable. The syntax is given below.

        Syntax:

        var_name(parameter);  

        Example:

        MultiOperation mp;  
        
        mp = Sum;  
        
        mp(20,10);  
        
        mp = Sub;  
        
        mp(30,20);

          The mp is a typedef variable, which can be used to refer any method that accepts two integer parameters. The function reference can be switched at runtime by using the typedefs.

          Complete Program using typedef

          Let’s have a look at the following example.

          typedef MultiOperation(int num1, int num2);  // typedef function signature  
          
          Sum(int n1, int n2) {  
          
                print("Sum of the two number:${n1+n2}");  
          
          }  
          
          Sub(int n1, int n2 ) {  
          
                print("Subtraction of the two number:${n1-n2}");  
          
             
          
          }  
          
            
          
          void main() {  
          
          MultiOperation mp = Sum;  
          
          print("JavaTpoint - Dart typedef Example");  
          
            
          
          mp(20,10);  
          
          mp = Sub;  
          
          mp(30,20);  
          
          }

          Output:

          JavaTpoint - Dart typedef Example
          Sum of the two numbers: 30
          Subtraction of the two numbers: 10
          

          Explanation:

          In the above code, we created the alias of the MultiOperation() function using the typedef keyword. We defined two more functions Sum() and Sub(), which have same signature as the typedef function.

          Then, we assigned the typedef variable mp that referred to both functions Sum() function and Sub() function. Now, we invoked the function by passing the required argument, and it printed the result to the screen.

          Typedef as Parameter

          We can use the typedef method as a parameter. In the following example, we are creating an additional function to the above program NumericOperaion(int n1, int n2, MultiOperation mp) with the two integer variables and typedef ManyOperation mp as its parameter.

          Example –

          typedef MultiOperation(int num1, int num2);  // typedef function signature  
          
            
          
          Sum(int n1, int n2) {  
          
                print("Sum of the two number:${n1+n2}");  
          
          }  
          
          Sub(int n1, int n2 ) {  
          
                print("Subtraction of the two number:${n1-n2}");  
          
          }  
          
             
          
          NumericOperation(int n1, int n2, MultiOperation mp){  
          
                print("Inside Operation");  
          
                mp(n1,n2);  
          
                   }  
          
            
          
          void main() {  
          
          print("JavaTpoint - Dart typedef Example");  
          
          NumericOperation(20, 10, Sum);  
          
          NumericOperation(20, 10, Sub);  
          
          }  

            Output:

            JavaTpoint - Dart typedef Example
            Inside Operation
            Sum of the two number: 30
            Inside Operation
            Subtraction of the two number: 10
            

            In the above code, we didn’t need to create a typedef variable to the refer to each method; we just called the NumericOperation() function by passing the required value and typedef variable mp. It performed the given operations and printed the result.

            Dart Debugging

            Debugging is the process of identifying and eliminating of existing and possible errors in the Dart program that can cause ambiguity and uncertainty during the program execution. Debugging is essential to detect and fixes the bugs to run the program smoothly or without interruption.

            Debugging becomes easier if you are using the IDE for the Dart program. Here we are assuming that you have installed the most common and suitable IDE WebStorme in your system. The WebStorm Editor allows us to step by step debugging.

            What are Breakpoints?

            Breakpoints are the checkpoint of the program to break the program at a specific point to checks its behavior. We can add the breakpoints in the program to check the bugs within that specific area.

            How to add Breakpoints in WebStorm?

            We can add the breakpoints in WebStorm by simply click on a line number in the left bar to add a breakpoint. After adding the breakpoints, run the program in the debug mode, it will give the Debugger window where we can verify that how the breakpoint works. We can also change the values and see the difference in the watches window.

            Dart Typedef
          1. Exceptions

            Dart Exceptions are the run-time error. It is raised when the program gets execution. The program doesn’t report the error at compile time when the program runs internally and if Dart compiler found something not appropriate. Then, it reports run-time error and the execution of program is terminated abnormally. This type of error is called Exceptions. For example – A given number is divided by the zero or we try to access the elements from the empty list.

            Dart supports the following types of built-in exceptions.

            Sr.ExceptionsDescription
            1.DefferedLoadExceptionIt is thrown when a deferred library fails to load.
            2.FromatExceptionIt is the exception which is thrown
            3.IntegerDivisionByZeroExceptionIt is thrown when number is divided by zero.
            4.IOEExceptionIt is the base class of input-output related exception.
            5.IsolateSpawnExceptionIt is thrown when an isolated cannot be created.
            6.TimeoutIt is thrown when a schedule timeout happens while waiting for an async result.

            The main objective of the exception is to handle the run-time error and prevent the program from terminating abruptly. Every exception in the Dart is a subtype of the pre-defined class Exception. Dart provides the following techniques to handle the exceptions.

            The try/on/catch Blocks

            The try block is used to hold the block of code that might be thrown an exception. The on block is used to when we require specifying the exceptions. The catch block is used to when handler needs the exception object.

            If the try block finds the error, it throws to the catch block and the catch block has the code to handle the error. The try block must be followed by the exactly one block either on/ catch or one finally block.

            The syntax of exceptional handling is the given below.

            Syntax:

            try {
            // code that might throw an exception
            }
            on Exception1 {
            // Specify the exception
            }
            Catch Exception2 {
            // code for handling exception
            }
            

            One should remember the following points.

            • We can handle the multiple exceptions using the more than one catch block.
            • The on block and the catch block is mutually inclusive that means we can associate the both – the on block and catch block with the try block.

            In the following example, the variable x is divided by the y variable respectively. The code is thrown when it tries to divide by the zero. The on block consists of the code to handle the exception. Let’s understand the following code.

            Example – Using the on block

            void main() {   
            
               int x = 12;   
            
               int y = 0;   
            
               int res;    
            
                 
            
               try {  
            
                  res = x ~/ y;   
            
               }   
            
               on IntegerDivisionByZeroException {   
            
                  print('Cannot divide by zero');   
            
               }   
            
            }

            Output

            Cannot divide by zero
            

            Explanation:

            In the above code, we declared the three variable x, y and res in main () function. We written the suspect code in try block divided the x by the 0 that might be thrown an exception. The try block found the error the control transferred to the on block that has the code to handle the error. By using this, the program did not stop its execution.

            Let’s understand the following example using the catch block.

            Example – Using the catch Block

            void main() {   
            
               int x = 12;   
            
               int y = 0;   
            
               int res;    
            
                 
            
               try {    
            
                  res = x ~/ y;   
            
               }    
            
            // It returns the built-in exception related to the occurring exception  
            
               catch(E) {   
            
                  print(E);   
            
               }   
            
            } 

            Output

            IntegerDivisionByZeroException
            

            Now look at the example of on…catch block together

            Example 3: on…catch block

            void main() {   
            
               int x = 12;   
            
               int y = 0;   
            
               int res;    
            
                 
            
               try {   
            
                  res = x ~/ y;   
            
               }    
            
               on IntegerDivisionByZeroException catch(E) {   
            
                  print(E);   
            
               }   
            
            }  

            Output

            IntegerDivisionByZeroException
            

            The Finally Block

            The finally block always executes whether there is exception occur or not. It executes unconditionally after the try/on/catch.

            The syntax of finally block is given below.

            Syntax –

            try {   
            
               // code that may be throw an exception   
            
            }    
            
            on Exception1 {   
            
               // exception handling code or specifying the exception  
            
            }    
            
            catch Exception2 {   
            
               //  code for exception handling   
            
            }    
            
            finally {   
            
               // code that should always execute; whether exception or not.  
            
            } 

            Let’s understand the following example of finally block.

            Example –

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

            Output

            Cannot divide by zero
            Finally block executed
            

            Throwing an Exception

            We can raise an exception explicitly or forcefully. The explicitly raised exception should be handled to avoid the program from existing sharply. The syntax is given below.

            Syntax:

            throw new Exception_name()  

            Let’s understand the following example.

            Example –

            main() {   
            
               try {   
            
                  check_marks(-10);   
            
               }   
            
               catch(e) {   
            
                  print('The marks cannot be negative');   
            
               }   
            
            }    
            
            void check_marks(int marks) {   
            
               if(marks<0) {   
            
                  throw new FormatException();  // Raising explanation externally  
            
               }   
            
            } 

            Output

            The marks cannot be negative
            

            Custom Exceptions

            As we discussed above, each of the exception in dart is the subtype of the built-in class Exception. Dart provide the flexibility to create custom exception by extending the existing exception class. The syntax is given below.

            Syntax: Defining the Exception

            class Custom_exception_Name implements Exception {   
            
               // can contain constructors, variables and methods   
            
            }   

            Let’s understand the following code.

            Example –

            class AmtException implements Exception {   
            
               String expMsg() => 'Entered Amount should be greater than zero';   
            
            }    
            
            void main() {   
            
               try {   
            
                  withdraw_amt(-1);   
            
               }   
            
               catch(E) {   
            
                  print(E.expMsg());   
            
               }    
            
               finally {   
            
                  print('Ending requested operation.....');   
            
               }   
            
            }    
            
            void withdraw_amt(int amt) {   
            
               if (amt <= 0) {   
            
                  throw new AmtException();   
            
               }   
            
            }    

            Output

            Entered Amount should be greater than zero
            Ending requested operation.....
            

            Explanation:

            In the above example, we created a custom exception, AmtException. The code raised the exception if the entered amount is not within the excepted range and we enclosed the function invocation in the try…catch block.