Skip to content

Latest commit

 

History

History
427 lines (328 loc) · 9.79 KB

File metadata and controls

427 lines (328 loc) · 9.79 KB

Futures, Asysnc and Await

  • Async means that this function is asynchronous and you might need to wait a bit to get its result.
  • Await literally means - wait here until this function is finished and you will get its return value.
  • Future is a type that ‘comes from the future’ and returns value from your asynchronous function.
  • It can complete with success(.then) or with an error(.catchError).
  • .Then((value){…}) is a callback that’s called when future completes successfully(with a value).

Example for Synchronous

import 'dart:io';

void main() {
  performTasks();
}

void performTasks() {
  task1();
  task2();
  task3();
}

void task1() {
  String result = 'task 1 data';
  print('Task 1 complete');
}

void task2() {
  Duration threeSeconds = Duration(seconds: 3);
  sleep(threeSeconds);
  String result = 'task 2 data';
  print('Task 2 complete');
}

void task3() {
  String result = 'task 3 data';
  print('Task 3 complete');
}

Example for Asynchronous

import 'dart:io';

void main() {
  performTasks();
}

void performTasks() {
  task1();
  task2();
  task3();
}

void task1() {
  String result = 'task 1 data';
  print('Task 1 complete');
}

void task2() {
  Duration threeSeconds = Duration(seconds: 3);
  Future.delayed(threeSeconds, () {
    String result = 'task 2 data';
    print('Task 2 complete');
  });
}

void task3() {
  String result = 'task 3 data';
  print('Task 3 complete');
}

Example for Futures, Asysnc and Await

import 'dart:io';

void main(){
  performTasks();
}

void performTasks() async{
  task1();
  String taskTwoResult = await task2();
  task3(taskTwoResult);
}

void task1() {
  String result = 'task 1 data';
  print('Task 1 complete');
}

Future task2() async{
  Duration threeSeconds = Duration(seconds: 3);
  String result;
  Future.delayed(threeSeconds, () {
    result = 'task 2 data';
    print('Task 2 complete');
  });

  return result;
}

void task3(String resultData) {
  String result = 'task 3 data';
  print('Task 3 complete$resultData');
}

Widgets Lifecycle Methods

Stateless Widget

  • A stateless widget can only be drawn once when the Widget is loaded/built.
  • A stateless widget cannot be redrawn based on any events or user actions.
  • In the below exampl, Screen is a Stateless widget and it has overridden the function called Widget build(BuildContet context) which returns one widget.
  • So, whenever Screen is instantiated, it will call the build(...) function and draw the widgets returned by this function.
class Screen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return null;
  }
}

Stateful Widget

  • The Stateful widget is mutable that's why it can be drawn multiple times within its lifetime.
  • It is useful when we dynamically update screen of app on user actions.
  • The build(...) method of state can be called multiple times during its lifetime and every build may return new or different widgets based on mulitple parameters.
class ScreenState extends State<Screen> {
  @override
  void initState(){
    super.initState();
    // This will called at first(i.e) which gets triggered when the state gets initially initialized.
  }
  @override
  void didChangeDependencies(){
    super.didChangeDependencies();
    // Additional code
  }
  @override
  void dispose(){
    // This calls when the screen gets destroyed
    super.dispose();
  }
  @override
  Widget build(BuildContext context){
    //This calls once initializes the UI(i.e) when the widgets are actually build and show up on screen
    return null;
  }
  @override
  void deactivate() {
    // This called when the stateful widget gets destroyed
    super.deactivate();
  }
}

Exception Handling and Null Aware Operators

  • The Exception Handling is a mechanism to handle the runtime errors so that normal flow of the application can be maintained.
  • In Java, all exception classes are descendants of class Throwable.
  • four keyword Types -> try, catch, finally and throw
  • Types -> Checked Exception, Unchecked Exception and Errors

Checked Exception

  • Checked exception is checked at compile time.
  • This exception type extends the Throwable class.
  • Example: IOException, SQLException, FileNotFoundException, ClassNotFoundException etc.

Unchecked Exception

  • Unchecked exceptions are not checked at compile-time, but they are checked at runtime.
  • Example: ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc.

Error

  • Error is irrecoverable.
  • Example: OutOfMemoryError, VirtualMachineError, AssertionError etc.

Example

main() {
 
  String myString = 'abc';
  
  try{
    double myStringAsDouble = double.parse(myString);
    print(myStringAsDouble + 5);
  } catch(e){
    print(e);
  }
}

Null Aware Operators

  • Null-aware operators in dart allow you to make computations based on whether or not a value is null.
  • It’s shorthand for longer expressions.

Syntax

mVariable ?? defaultValue

Getting Current Location

  • A Flutter geolocation plugin which provides easy access to platform specific location services (FusedLocationProviderClient or if not available the LocationManager on Android and CLLocationManager on iOS).

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  geolocator: ^6.2.1

AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Info.plist

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>

loading_screen.dart

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    getLocation();
  }

  void getLocation() async {
    try {
      Position position = await Geolocator.getCurrentPosition(
          desiredAccuracy: LocationAccuracy.low);
      print(position);
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

API [Application Programming Interface]

  • API request is a way of sending messages to software on another computer over the internet or over a network.
  • A web browser will usually make GET requests and POST requests.
  • Note: For getting the json sample response visit, https://openweathermap.org/api (or) https://www.coinapi.io/pricing?apikey
  • Two Types of Response -> JSON and XML.

JSON

  • JSON stands for JavaScript Object Notation.
  • It's an open-standard file format that is used for browser-server communications.
  • It's a language-independent data format.
{key:value}

XML

  • XML stands for Extensible Markup Language.
  • It's a set of rules that help the users to encode documents in a human-readable format and machine-readable.
<key>value</key>

loading_screen.dart

import 'package:flutter/material.dart';
import 'package:clima/services/location.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    getLocation();
  }

  void getLocation() async {
    Location mLocation = Location();
    await mLocation.getCurrentLocation();

    print(mLocation.latitude);
    print(mLocation.longitude);
  }

  void getData() async {
    http.Response response = await http.get(
        'http://samples.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=1c56d238e55dbd7e02da908c3292da01'); // you have to add your own app id
    if (response.statusCode == 200) {
      String data = response.body;
      var decodeData = jsonDecode(data);

      double longitude = decodeData['coord']['lon'];
      String weatherDescription = decodeData['weather'][0]['description'];
    } else {
      print(response.statusCode);
    }
  }

  @override
  Widget build(BuildContext context) {
    getData();
    return Scaffold();
  }
}

Passing Data to a State Object

  • The simplest way to send data from a widget to another is by its constructor.

loading_screen.dart

class _LoadingScreenState extends State<LoadingScreen> {
  double latitude;
  double longitude;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    getLocationData();
  }

  void getLocationData() async {
    Location mLocation = Location();
    await mLocation.getCurrentLocation();

    latitude = mLocation.latitude;
    longitude = mLocation.longitude;

    NetworkHelper networkHelper = NetworkHelper(
        'http://api.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&appid=$apiKey');

    var weatherData = await networkHelper.getData();

    Navigator.push(context, MaterialPageRoute(builder: (context) {
      return LocationScreen(locationWeather: weatherData);
    }));
  }
}

location_screen.dart

class LocationScreen extends StatefulWidget {
  LocationScreen({this.locationWeather});

  final locationWeather;

  @override
  _LocationScreenState createState() => _LocationScreenState();
}

class _LocationScreenState extends State<LocationScreen> {
  double longitude;
  String weatherDescription;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    updateUI(widget.locationWeather);
  }

  void updateUI(dynamic weatherData) {
    longitude = weatherData['coord']['lon'];
    weatherDescription = weatherData['weather'][0]['description'];
  }
}