New to dart, go easy on me.

I am starting to work on APIs and a part of my training is to fetch data from a World Time API. I created a separate class that fetches the data and imported it in the get time page in order to initialize it in initState. Here is my class:

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

class WorldTimeClass {
  String flag; // this is the link to a .png flag
  String url; // this is the suffix of the location e.g.: Europe/Berlin
  String time; // this is the time format to be displayed to the user
  String location; // this is the location, say Berlin

  WorldTimeClass({this.flag, this.url, this.time, this.location}); // class object

  Future<String> getData() async { // async method to fetch the data
    Response load = await get('http://worldtimeapi.org/api/timezone/$url');
    Map x(){if(load.statusCode == 200){ // if all goes well, fetch content from API
      print(load.statusCode); // this is so I can see that the operation is successful

    Map map = jsonDecode(load.body); // converting String to MAP
    return map;} // returning Map Object
    else{ // in case of error
      print('No Access');
      return {1:'NoAccess.'};} // had to return a Map Object since I declared Future<Map>
   }

    String datetime = x()['utc_datetime']; // fetching datetime String
    String offsetUTC = x()['utc_offset']; // fetching offset, e.g. +01:00
    DateTime dateTimeObjectConvert = DateTime.parse(datetime);
    // Below converts the datetime string to a DateTime Object and then converts the UTC Offset to a substring only '01' out of +01:00 and then converts it to an int Object and then adds it to the DateTime Object as a Duration (hours);
    dateTimeObjectConvert = dateTimeObjectConvert.add(Duration(hours: int.parse(offsetUTC.substring(1,3))));
    return time = dateTimeObjectConvert.toString(); // returning String to be displayed to user

  }

}

And here is my code inside the app page choose_location.dart:

Future<String> provisionalFunc() async {
    String getdata;
    WorldTimeClass instance = WorldTimeClass(location: 'Algiers', url: 'Africa/Algiers', flag: 'algeria.png');
    getdata = await instance.getData();
    return getdata;
  }

  @override
  void initState() {
    print('initState..');
    super.initState();
    print(provisionalFunc());
  }

Problem: In the terminal output I get this:

Restarted application in 1 174ms.
I/flutter (24151): initState..
I/flutter (24151): Instance of 'Future<String>'
I/flutter (24151): 200
I/flutter (24151): 200

Questions:

  1. Why do I get code: 200 twice ?
  2. Why do I get Instance of 'Future<String>' and how to get rid of it?
  3. How to print the time String variable in my terminal?


Solution 1: AskNilesh

Why do I get Instance of 'Future' and how to get rid of it?

How to print the time String variable in my terminal?

Try this way to get your time value from 'Future<String>'

  @override
  void initState() {
    super.initState();
    provisionalFunc().then((timeData) =>
    {
      print(timeData);
    });

  }

Why do I get code: 200 twice ?

Your status code is printing twice because some of the reason your Map x() {} is called twice if you print log outside this it will print only once

Try this way to get your time

Create a pojo class to parse your json

class TimeData {
  String abbreviation;
  String client_ip;
  String datetime;
  int day_of_week;
  int day_of_year;
  bool dst;
  int dst_offset;
  int raw_offset;
  String timezone;
  int unixtime;
  String utc_datetime;
  String utc_offset;
  int week_number;

  TimeData(
      {this.abbreviation,
      this.client_ip,
      this.datetime,
      this.day_of_week,
      this.day_of_year,
      this.dst,
      this.dst_offset,
      this.raw_offset,
      this.timezone,
      this.unixtime,
      this.utc_datetime,
      this.utc_offset,
      this.week_number});

  factory TimeData.fromJson(Map<String, dynamic> json) {
    return TimeData(
      abbreviation: json['abbreviation'],
      client_ip: json['client_ip'],
      datetime: json['datetime'],
      day_of_week: json['day_of_week'],
      day_of_year: json['day_of_year'],
      dst: json['dst'],
      dst_offset: json['dst_offset'],
      raw_offset: json['raw_offset'],
      timezone: json['timezone'],
      unixtime: json['unixtime'],
      utc_datetime: json['utc_datetime'],
      utc_offset: json['utc_offset'],
      week_number: json['week_number'],
    );
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['abbreviation'] = this.abbreviation;
    data['client_ip'] = this.client_ip;
    data['datetime'] = this.datetime;
    data['day_of_week'] = this.day_of_week;
    data['day_of_year'] = this.day_of_year;
    data['dst'] = this.dst;
    data['dst_offset'] = this.dst_offset;
    data['raw_offset'] = this.raw_offset;
    data['timezone'] = this.timezone;
    data['unixtime'] = this.unixtime;
    data['utc_datetime'] = this.utc_datetime;
    data['utc_offset'] = this.utc_offset;
    data['week_number'] = this.week_number;

    return data;
  }
}

now update your getData() method like this

Future<String> getData() async {
    // async method to fetch the data
    Response load = await get('http://worldtimeapi.org/api/timezone/$url');
    print(load.statusCode);

    if (load.statusCode == 200) {
      var timeDate = TimeData.fromJson(json.decode(load.body));
      String datetime = timeDate.utc_datetime; // fetching datetime String
      String offsetUTC = timeDate.utc_offset; // fetching offset, e.g. +01:00
      DateTime dateTimeObjectConvert = DateTime.parse(datetime);
      // Below converts the datetime string to a DateTime Object and then converts the UTC Offset to a substring only '01' out of +01:00 and then converts it to an int Object and then adds it to the DateTime Object as a Duration (hours);
      dateTimeObjectConvert =
          dateTimeObjectConvert.add(Duration(hours: int.parse(offsetUTC.substring(1, 3))));
      return time = dateTimeObjectConvert.toString();
    }else{
      return "No access";
    }

    // returning String to be displayed to user
  }

Now use like this

 @override
  void initState() {
    print('initState..');
    super.initState();
    provisionalFunc().then((timeData) => {print(timeData)});
  }

OUTPUT

enter image description here