问:
Flutter Table Calendar : Showing Event from API to Table Calendar
I want to show Calendar and including event, the event already exists from API. I searching plugin fit to my case and I found Table Calendar Plugin. I read the example to show the event Manually and found it :

```<code>@override
  void initState() {
    super.initState();
    final _selectedDay = DateTime.now();

    _events = {
      _selectedDay.subtract(Duration(days: 30)): ['Event A0', 'Event B0', 'Event C0'],
      _selectedDay.subtract(Duration(days: 27)): ['Event A1'],
      _selectedDay.subtract(Duration(days: 20)): ['Event A2', 'Event B2', 'Event C2', 'Event D2'],
      _selectedDay.subtract(Duration(days: 16)): ['Event A3', 'Event B3'],
      _selectedDay.subtract(Duration(days: 10)): ['Event A4', 'Event B4', 'Event C4'],
      _selectedDay.subtract(Duration(days: 4)): ['Event A5', 'Event B5', 'Event C5'],
      _selectedDay.subtract(Duration(days: 2)): ['Event A6', 'Event B6'],
      _selectedDay: ['Event A7', 'Event B7', 'Event C7', 'Event D7'],
      _selectedDay.add(Duration(days: 1)): ['Event A8', 'Event B8', 'Event C8', 'Event D8'],
      _selectedDay.add(Duration(days: 3)): Set.from(['Event A9', 'Event A9', 'Event B9']).toList(),
      _selectedDay.add(Duration(days: 7)): ['Event A10', 'Event B10', 'Event C10'],
      _selectedDay.add(Duration(days: 11)): ['Event A11', 'Event B11'],
      _selectedDay.add(Duration(days: 17)): ['Event A12', 'Event B12', 'Event C12', 'Event D12'],
      _selectedDay.add(Duration(days: 22)): ['Event A13', 'Event B13'],
      _selectedDay.add(Duration(days: 26)): ['Event A14', 'Event B14', 'Event C14'],
    };

    _selectedEvents = _events[_selectedDay] ?? [];
    _calendarController = CalendarController();

    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );

    _animationController.forward();
  }
</code>```

But the above example to show event is static, I need to show event already exist from my API to Table Calendar dynamically.

 I'm so new for this package, How can I handle my case?

Result API

```<code>{
    "status": "ok",
    "message": "Event Is Found",
    "data": [
        {
            "kodeEvent": "1",
            "tanggalEvent": "2020-01-15",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Lombok",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8cd198530_202002181405.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "0",
            "createTime": "2020-01-29 16:37:26",
            "updateBy": "",
            "updateTime": "2020-02-18 14:05:53"
        },
        {
            "kodeEvent": "2",
            "tanggalEvent": "2020-03-31",
            "judulEvent": "Bangun Kembali 100 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Jakarta",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d3d74b44_202002181407.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:07:41",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        },
        {
            "kodeEvent": "3",
            "tanggalEvent": "2020-01-31",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Bandung",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d72e2d37_202002181408.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:08:34",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        }
    ]
}
</code>```

Model

```<code>import 'dart:convert';

class EventModel {
  String kodeEvent;
  DateTime tanggalEvent;
  String judulEvent;
  String lokasiEvent;
  String isiEvent;
  String fotoEvent;
  String waktuEvent;
  String statusEvent;
  String createBy;
  DateTime createTime;
  String updateBy;
  String updateTime;

  EventModel({
    this.kodeEvent,
    this.tanggalEvent,
    this.judulEvent,
    this.lokasiEvent,
    this.isiEvent,
    this.fotoEvent,
    this.waktuEvent,
    this.statusEvent,
    this.createBy,
    this.createTime,
    this.updateBy,
    this.updateTime,
  });

  factory EventModel.fromJson(Map<String, dynamic> json) => EventModel(
        kodeEvent: json["kodeEvent"],
        tanggalEvent: DateTime.parse(json["tanggalEvent"]),
        judulEvent: json["judulEvent"],
        lokasiEvent: json["lokasiEvent"],
        isiEvent: json["isiEvent"],
        fotoEvent: json["fotoEvent"],
        waktuEvent: json["waktuEvent"],
        statusEvent: json["statusEvent"],
        createBy: json["createBy"],
        createTime: DateTime.parse(json["createTime"]),
        updateBy: json["updateBy"],
        updateTime: json["updateTime"],
      );
}

</code>```

Event Screen

```<code>class _EventScreenState extends State<EventScreen> {
  Future<List<EventModel>> getAllEvent;

  CalendarController calendarController;
  @override
  void initState() {
    super.initState();
    calendarController = CalendarController();
    getAllEvent = eventApi.getAllEvent();
  }

  @override
  void dispose() {
    calendarController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          TableCalendar(
            calendarController: calendarController,
            startingDayOfWeek: StartingDayOfWeek.monday,
            events: ,
          ),
          FutureBuilder(
            future: getAllEvent,
            builder: (BuildContext context,
                AsyncSnapshot<List<EventModel>> snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return ErrorFutureBuilder(errorText: snapshot.error);
                } else {
                  return ListView.builder(
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) {
                      final result = snapshot.data[index];
                      return Text(result.tanggalEvent);
                    },
                  );
                }
              } else {
                return LoadingFutureBuilder();
              }
            },
          ),
        ],
      ),
    );
  }
}

</code>```

GetAllEvent

```<code> Future<List<EventModel>> getAllEvent() async {
    try {
      final response = await http.get(_baseUrl);
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List eventList = responseJson['data'];
        final result = eventList
            .map<EventModel>((json) => EventModel.fromJson(json))
            .toList();
        return result;
      } else {
        throw CustomError(responseJson['message']);
      }
    } catch (e) {
      return Future.error(e.toString());
    }
  }
</code>```

My Current Result

答:
You can copy paste run full code below

I simulate network delay with 3 seconds.

code snippet for you model

```<code>Future<Map<DateTime, List>> getTask1() async {
    Map<DateTime, List> mapFetch = {};
    List<EventModel> event = await getAllEvent();
    for (int i = 0; i < event.length; i++) {
      var createTime = DateTime(event[i].createTime.year,
          event[i].createTime.month, event[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event[i].tanggalEvent];
      } else {
        print(event[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)
          ..addAll([event[i].tanggalEvent]);
      }
    }

    return mapFetch;
  }
</code>```

code snippet

```<code>    WidgetsBinding.instance.addPostFrameCallback((_) {
          getTask().then((val) => setState(() {
            _events = val;
          }));
          //print( ' ${_events.toString()} ');
        });

     Future<Map<DateTime, List>> getTask() async {
            Map<DateTime, List> mapFetch = {};

            await Future.delayed(const Duration(seconds: 3), () {});

            String responseString = '''
{
    "status": "ok",
    "message": "Event Is Found",
  ...
                Event event = eventFromJson(responseString);

    for (int i = 0; i < event.data.length; i++) {
      var createTime = DateTime(event.data[i].createTime.year,
          event.data[i].createTime.month, event.data[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event.data[i].tanggalEvent];
      } else {
        print(event.data[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)..addAll([event.data[i].tanggalEvent]);
      }
    }

    return mapFetch;
    }
</code>```

working demo

full code

```import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'dart:convert';

Event eventFromJson(String str) => Event.fromJson(json.decode(str));

String eventToJson(Event data) => json.encode(data.toJson());

class Event {
  String status;
  String message;
  List<Datum> data;

  Event({
    this.status,
    this.message,
    this.data,
  });

  factory Event.fromJson(Map<String, dynamic> json) => Event(
        status: json["status"],
        message: json["message"],
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "status": status,
        "message": message,
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
      };
}

class Datum {
  String kodeEvent;
  DateTime tanggalEvent;
  String judulEvent;
  String lokasiEvent;
  String isiEvent;
  String fotoEvent;
  String waktuEvent;
  String statusEvent;
  String createBy;
  DateTime createTime;
  String updateBy;
  String updateTime;

  Datum({
    this.kodeEvent,
    this.tanggalEvent,
    this.judulEvent,
    this.lokasiEvent,
    this.isiEvent,
    this.fotoEvent,
    this.waktuEvent,
    this.statusEvent,
    this.createBy,
    this.createTime,
    this.updateBy,
    this.updateTime,
  });

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        kodeEvent: json["kodeEvent"],
        tanggalEvent: DateTime.parse(json["tanggalEvent"]),
        judulEvent: json["judulEvent"],
        lokasiEvent: json["lokasiEvent"],
        isiEvent: json["isiEvent"],
        fotoEvent: json["fotoEvent"],
        waktuEvent: json["waktuEvent"],
        statusEvent: json["statusEvent"],
        createBy: json["createBy"],
        createTime: DateTime.parse(json["createTime"]),
        updateBy: json["updateBy"],
        updateTime: json["updateTime"],
      );

  Map<String, dynamic> toJson() => {
        "kodeEvent": kodeEvent,
        "tanggalEvent":
            "${tanggalEvent.year.toString().padLeft(4, '0')}-${tanggalEvent.month.toString().padLeft(2, '0')}-${tanggalEvent.day.toString().padLeft(2, '0')}",
        "judulEvent": judulEvent,
        "lokasiEvent": lokasiEvent,
        "isiEvent": isiEvent,
        "fotoEvent": fotoEvent,
        "waktuEvent": waktuEvent,
        "statusEvent": statusEvent,
        "createBy": createBy,
        "createTime": createTime.toIso8601String(),
        "updateBy": updateBy,
        "updateTime": updateTime,
      };
}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  List _selectedEvents;
  int _counter = 0;
  Map<DateTime, List> _events;
  CalendarController _calendarController;
  AnimationController _animationController;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  Future<List<EventModel>> getAllEvent() async {
    try {
      //final response = await http.get(_baseUrl);

      String responseString = '''
{
    "status": "ok",
    "message": "Event Is Found",
    "data": [
        {
            "kodeEvent": "1",
            "tanggalEvent": "2020-01-15",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Lombok",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8cd198530_202002181405.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "0",
            "createTime": "2020-01-29 16:37:26",
            "updateBy": "",
            "updateTime": "2020-02-18 14:05:53"
        },
        {
            "kodeEvent": "2",
            "tanggalEvent": "2020-03-31",
            "judulEvent": "Bangun Kembali 100 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Jakarta",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d3d74b44_202002181407.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:07:41",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        },
        {
            "kodeEvent": "3",
            "tanggalEvent": "2020-01-31",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Bandung",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d72e2d37_202002181408.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:08:34",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        }
    ]
}
    ''';

      final Map<String, dynamic> responseJson = json.decode(responseString);
      if (responseJson["status"] == "ok") {
        List eventList = responseJson['data'];
        final result = eventList
            .map<EventModel>((json) => EventModel.fromJson(json))
            .toList();
        return result;
      } else {
        //throw CustomError(responseJson['message']);
      }
    } catch (e) {
      return Future.error(e.toString());
    }
  }

  Future<Map<DateTime, List>> getTask1() async {
    Map<DateTime, List> mapFetch = {};
    List<EventModel> event = await getAllEvent();
    for (int i = 0; i < event.length; i++) {
      var createTime = DateTime(event[i].createTime.year,
          event[i].createTime.month, event[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event[i].tanggalEvent];
      } else {
        print(event[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)
          ..addAll([event[i].tanggalEvent]);
      }
    }

    return mapFetch;
  }

  Future<Map<DateTime, List>> getTask() async {
    Map<DateTime, List> mapFetch = {};

    await Future.delayed(const Duration(seconds: 3), () {});

    /*String link = baseURL + fetchTodoByDate;
    var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
    if (res.statusCode == 200) {
      // need help in creating fetch logic here
    }*/

    String responseString = '''
{
    "status": "ok",
    "message": "Event Is Found",
    "data": [
        {
            "kodeEvent": "1",
            "tanggalEvent": "2020-01-15",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Lombok",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8cd198530_202002181405.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "0",
            "createTime": "2020-01-29 16:37:26",
            "updateBy": "",
            "updateTime": "2020-02-18 14:05:53"
        },
        {
            "kodeEvent": "2",
            "tanggalEvent": "2020-03-31",
            "judulEvent": "Bangun Kembali 100 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Jakarta",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d3d74b44_202002181407.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:07:41",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        },
        {
            "kodeEvent": "3",
            "tanggalEvent": "2020-01-31",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Bandung",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d72e2d37_202002181408.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:08:34",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        }
    ]
}
    ''';

    Event event = eventFromJson(responseString);

    for (int i = 0; i < event.data.length; i++) {
      var createTime = DateTime(event.data[i].createTime.year,
          event.data[i].createTime.month, event.data[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event.data[i].tanggalEvent];
      } else {
        print(event.data[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)
          ..addAll([event.data[i].tanggalEvent]);
      }
    }

    return mapFetch;
  }

  void _onDaySelected(DateTime day, List events) {
    print('CALLBACK: _onDaySelected');
    setState(() {
      _selectedEvents = events;
    });
  }

  @override
  void initState() {
    final _selectedDay = DateTime.now();
    _selectedEvents = [];
    _calendarController = CalendarController();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );

    _animationController.forward();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      getTask1().then((val) => setState(() {
            _events = val;
          }));
      //print( ' ${_events.toString()} ');
    });
    super.initState();
  }

  @override
  void dispose() {
    _calendarController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _buildTableCalendarWithBuilders(),
            const SizedBox(height: 8.0),
            const SizedBox(height: 8.0),
            Expanded(child: _buildEventList()),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  Widget _buildTableCalendarWithBuilders() {
    return TableCalendar(
      //locale: 'pl_PL',
      calendarController: _calendarController,
      events: _events,
      //holidays: _holidays,
      initialCalendarFormat: CalendarFormat.month,
      formatAnimation: FormatAnimation.slide,
      startingDayOfWeek: StartingDayOfWeek.sunday,
      availableGestures: AvailableGestures.all,
      availableCalendarFormats: const {
        CalendarFormat.month: '',
        CalendarFormat.week: '',
      },
      calendarStyle: CalendarStyle(
        outsideDaysVisible: false,
        weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
        holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
      ),
      daysOfWeekStyle: DaysOfWeekStyle(
        weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
      ),
      headerStyle: HeaderStyle(
        centerHeaderTitle: true,
        formatButtonVisible: false,
      ),
      builders: CalendarBuilders(
        selectedDayBuilder: (context, date, _) {
          return FadeTransition(
            opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
            child: Container(
              margin: const EdgeInsets.all(4.0),
              padding: const EdgeInsets.only(top: 5.0, left: 6.0),
              color: Colors.deepOrange[300],
              width: 100,
              height: 100,
              child: Text(
                '${date.day}',
                style: TextStyle().copyWith(fontSize: 16.0),
              ),
            ),
          );
        },
        todayDayBuilder: (context, date, _) {
          return Container(
            margin: const EdgeInsets.all(4.0),
            padding: const EdgeInsets.only(top: 5.0, left: 6.0),
            color: Colors.amber[400],
            width: 100,
            height: 100,
            child: Text(
              '${date.day}',
              style: TextStyle().copyWith(fontSize: 16.0),
            ),
          );
        },
        markersBuilder: (context, date, events, holidays) {
          final children = <Widget>[];

          if (events.isNotEmpty) {
            children.add(
              Positioned(
                right: 1,
                bottom: 1,
                child: _buildEventsMarker(date, events),
              ),
            );
          }

          if (holidays.isNotEmpty) {
            children.add(
              Positioned(
                right: -2,
                top: -2,
                child: _buildHolidaysMarker(),
              ),
            );
          }

          return children;
        },
      ),
      onDaySelected: (date, events) {
        _onDaySelected(date, events);
        _animationController.forward(from: 0.0);
      },
      onVisibleDaysChanged: _onVisibleDaysChanged,
    );
  }

  void _onVisibleDaysChanged(
      DateTime first, DateTime last, CalendarFormat format) {
    print('CALLBACK: _onVisibleDaysChanged');
  }

  Widget _buildEventsMarker(DateTime date, List events) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      decoration: BoxDecoration(
        shape: BoxShape.rectangle,
        color: _calendarController.isSelected(date)
            ? Colors.brown[500]
            : _calendarController.isToday(date)
                ? Colors.brown[300]
                : Colors.blue[400],
      ),
      width: 16.0,
      height: 16.0,
      child: Center(
        child: Text(
          '${events.length}',
          style: TextStyle().copyWith(
            color: Colors.white,
            fontSize: 12.0,
          ),
        ),
      ),
    );
  }

  Widget _buildHolidaysMarker() {
    return Icon(
      Icons.add_box,
      size: 20.0,
      color: Colors.blueGrey[800],
    );
  }

  Widget _buildEventList() {
    return ListView(
      children: _selectedEvents
          .map((event) => Container(
                decoration: BoxDecoration(
                  border: Border.all(width: 0.8),
                  borderRadius: BorderRadius.circular(12.0),
                ),
                margin:
                    const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
                child: ListTile(
                  title: Text(event.toString()),
                  onTap: () => print('$event tapped!'),
                ),
              ))
          .toList(),
    );
  }
}

class EventModel {
  String kodeEvent;
  DateTime tanggalEvent;
  String judulEvent;
  String lokasiEvent;
  String isiEvent;
  String fotoEvent;
  String waktuEvent;
  String statusEvent;
  String createBy;
  DateTime createTime;
  String updateBy;
  String updateTime;

  EventModel({
    this.kodeEvent,
    this.tanggalEvent,
    this.judulEvent,
    this.lokasiEvent,
    this.isiEvent,
    this.fotoEvent,
    this.waktuEvent,
    this.statusEvent,
    this.createBy,
    this.createTime,
    this.updateBy,
    this.updateTime,
  });

  factory EventModel.fromJson(Map<String, dynamic> json) => EventModel(
        kodeEvent: json["kodeEvent"],
        tanggalEvent: DateTime.parse(json["tanggalEvent"]),
        judulEvent: json["judulEvent"],
        lokasiEvent: json["lokasiEvent"],
        isiEvent: json["isiEvent"],
        fotoEvent: json["fotoEvent"],
        waktuEvent: json["waktuEvent"],
        statusEvent: json["statusEvent"],
        createBy: json["createBy"],
        createTime: DateTime.parse(json["createTime"]),
        updateBy: json["updateBy"],
        updateTime: json["updateTime"],
      );
}
```

Body:
I want to show Calendar and including event, the event already exists from API. I searching plugin fit to my case and I found Table Calendar Plugin. I read the example to show the event Manually and found it :

@override
  void initState() {
    super.initState();
    final _selectedDay = DateTime.now();

    _events = {
      _selectedDay.subtract(Duration(days: 30)): ['Event A0', 'Event B0', 'Event C0'],
      _selectedDay.subtract(Duration(days: 27)): ['Event A1'],
      _selectedDay.subtract(Duration(days: 20)): ['Event A2', 'Event B2', 'Event C2', 'Event D2'],
      _selectedDay.subtract(Duration(days: 16)): ['Event A3', 'Event B3'],
      _selectedDay.subtract(Duration(days: 10)): ['Event A4', 'Event B4', 'Event C4'],
      _selectedDay.subtract(Duration(days: 4)): ['Event A5', 'Event B5', 'Event C5'],
      _selectedDay.subtract(Duration(days: 2)): ['Event A6', 'Event B6'],
      _selectedDay: ['Event A7', 'Event B7', 'Event C7', 'Event D7'],
      _selectedDay.add(Duration(days: 1)): ['Event A8', 'Event B8', 'Event C8', 'Event D8'],
      _selectedDay.add(Duration(days: 3)): Set.from(['Event A9', 'Event A9', 'Event B9']).toList(),
      _selectedDay.add(Duration(days: 7)): ['Event A10', 'Event B10', 'Event C10'],
      _selectedDay.add(Duration(days: 11)): ['Event A11', 'Event B11'],
      _selectedDay.add(Duration(days: 17)): ['Event A12', 'Event B12', 'Event C12', 'Event D12'],
      _selectedDay.add(Duration(days: 22)): ['Event A13', 'Event B13'],
      _selectedDay.add(Duration(days: 26)): ['Event A14', 'Event B14', 'Event C14'],
    };

    _selectedEvents = _events[_selectedDay] ?? [];
    _calendarController = CalendarController();

    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );

    _animationController.forward();
  }

But the above example to show event is static, I need to show event already exist from my API to Table Calendar dynamically.

 I'm so new for this package, How can I handle my case?

Result API

{
    "status": "ok",
    "message": "Event Is Found",
    "data": [
        {
            "kodeEvent": "1",
            "tanggalEvent": "2020-01-15",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Lombok",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8cd198530_202002181405.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "0",
            "createTime": "2020-01-29 16:37:26",
            "updateBy": "",
            "updateTime": "2020-02-18 14:05:53"
        },
        {
            "kodeEvent": "2",
            "tanggalEvent": "2020-03-31",
            "judulEvent": "Bangun Kembali 100 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Jakarta",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d3d74b44_202002181407.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:07:41",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        },
        {
            "kodeEvent": "3",
            "tanggalEvent": "2020-01-31",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Bandung",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.

Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d72e2d37_202002181408.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:08:34",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        }
    ]
}

Model

import 'dart:convert';

class EventModel {
  String kodeEvent;
  DateTime tanggalEvent;
  String judulEvent;
  String lokasiEvent;
  String isiEvent;
  String fotoEvent;
  String waktuEvent;
  String statusEvent;
  String createBy;
  DateTime createTime;
  String updateBy;
  String updateTime;

  EventModel({
    this.kodeEvent,
    this.tanggalEvent,
    this.judulEvent,
    this.lokasiEvent,
    this.isiEvent,
    this.fotoEvent,
    this.waktuEvent,
    this.statusEvent,
    this.createBy,
    this.createTime,
    this.updateBy,
    this.updateTime,
  });

  factory EventModel.fromJson(Map<String, dynamic> json) => EventModel(
        kodeEvent: json["kodeEvent"],
        tanggalEvent: DateTime.parse(json["tanggalEvent"]),
        judulEvent: json["judulEvent"],
        lokasiEvent: json["lokasiEvent"],
        isiEvent: json["isiEvent"],
        fotoEvent: json["fotoEvent"],
        waktuEvent: json["waktuEvent"],
        statusEvent: json["statusEvent"],
        createBy: json["createBy"],
        createTime: DateTime.parse(json["createTime"]),
        updateBy: json["updateBy"],
        updateTime: json["updateTime"],
      );
}

Event Screen

class _EventScreenState extends State<EventScreen> {
  Future<List<EventModel>> getAllEvent;

  CalendarController calendarController;
  @override
  void initState() {
    super.initState();
    calendarController = CalendarController();
    getAllEvent = eventApi.getAllEvent();
  }

  @override
  void dispose() {
    calendarController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          TableCalendar(
            calendarController: calendarController,
            startingDayOfWeek: StartingDayOfWeek.monday,
            events: ,
          ),
          FutureBuilder(
            future: getAllEvent,
            builder: (BuildContext context,
                AsyncSnapshot<List<EventModel>> snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return ErrorFutureBuilder(errorText: snapshot.error);
                } else {
                  return ListView.builder(
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) {
                      final result = snapshot.data[index];
                      return Text(result.tanggalEvent);
                    },
                  );
                }
              } else {
                return LoadingFutureBuilder();
              }
            },
          ),
        ],
      ),
    );
  }
}

GetAllEvent

 Future<List<EventModel>> getAllEvent() async {
    try {
      final response = await http.get(_baseUrl);
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List eventList = responseJson['data'];
        final result = eventList
            .map<EventModel>((json) => EventModel.fromJson(json))
            .toList();
        return result;
      } else {
        throw CustomError(responseJson['message']);
      }
    } catch (e) {
      return Future.error(e.toString());
    }
  }

My Current Result

Body:
You can copy paste run full code below

I simulate network delay with 3 seconds.

code snippet for you model

Future<Map<DateTime, List>> getTask1() async {
    Map<DateTime, List> mapFetch = {};
    List<EventModel> event = await getAllEvent();
    for (int i = 0; i < event.length; i++) {
      var createTime = DateTime(event[i].createTime.year,
          event[i].createTime.month, event[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event[i].tanggalEvent];
      } else {
        print(event[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)
          ..addAll([event[i].tanggalEvent]);
      }
    }

    return mapFetch;
  }

code snippet

    WidgetsBinding.instance.addPostFrameCallback((_) {
          getTask().then((val) => setState(() {
            _events = val;
          }));
          //print( ' ${_events.toString()} ');
        });

     Future<Map<DateTime, List>> getTask() async {
            Map<DateTime, List> mapFetch = {};

            await Future.delayed(const Duration(seconds: 3), () {});

            String responseString = '''
{
    "status": "ok",
    "message": "Event Is Found",
  ...
                Event event = eventFromJson(responseString);

    for (int i = 0; i < event.data.length; i++) {
      var createTime = DateTime(event.data[i].createTime.year,
          event.data[i].createTime.month, event.data[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event.data[i].tanggalEvent];
      } else {
        print(event.data[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)..addAll([event.data[i].tanggalEvent]);
      }
    }

    return mapFetch;
    }

working demo

full code

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'dart:convert';

Event eventFromJson(String str) => Event.fromJson(json.decode(str));

String eventToJson(Event data) => json.encode(data.toJson());

class Event {
  String status;
  String message;
  List<Datum> data;

  Event({
    this.status,
    this.message,
    this.data,
  });

  factory Event.fromJson(Map<String, dynamic> json) => Event(
        status: json["status"],
        message: json["message"],
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "status": status,
        "message": message,
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
      };
}

class Datum {
  String kodeEvent;
  DateTime tanggalEvent;
  String judulEvent;
  String lokasiEvent;
  String isiEvent;
  String fotoEvent;
  String waktuEvent;
  String statusEvent;
  String createBy;
  DateTime createTime;
  String updateBy;
  String updateTime;

  Datum({
    this.kodeEvent,
    this.tanggalEvent,
    this.judulEvent,
    this.lokasiEvent,
    this.isiEvent,
    this.fotoEvent,
    this.waktuEvent,
    this.statusEvent,
    this.createBy,
    this.createTime,
    this.updateBy,
    this.updateTime,
  });

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        kodeEvent: json["kodeEvent"],
        tanggalEvent: DateTime.parse(json["tanggalEvent"]),
        judulEvent: json["judulEvent"],
        lokasiEvent: json["lokasiEvent"],
        isiEvent: json["isiEvent"],
        fotoEvent: json["fotoEvent"],
        waktuEvent: json["waktuEvent"],
        statusEvent: json["statusEvent"],
        createBy: json["createBy"],
        createTime: DateTime.parse(json["createTime"]),
        updateBy: json["updateBy"],
        updateTime: json["updateTime"],
      );

  Map<String, dynamic> toJson() => {
        "kodeEvent": kodeEvent,
        "tanggalEvent":
            "${tanggalEvent.year.toString().padLeft(4, '0')}-${tanggalEvent.month.toString().padLeft(2, '0')}-${tanggalEvent.day.toString().padLeft(2, '0')}",
        "judulEvent": judulEvent,
        "lokasiEvent": lokasiEvent,
        "isiEvent": isiEvent,
        "fotoEvent": fotoEvent,
        "waktuEvent": waktuEvent,
        "statusEvent": statusEvent,
        "createBy": createBy,
        "createTime": createTime.toIso8601String(),
        "updateBy": updateBy,
        "updateTime": updateTime,
      };
}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  List _selectedEvents;
  int _counter = 0;
  Map<DateTime, List> _events;
  CalendarController _calendarController;
  AnimationController _animationController;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  Future<List<EventModel>> getAllEvent() async {
    try {
      //final response = await http.get(_baseUrl);

      String responseString = '''
{
    "status": "ok",
    "message": "Event Is Found",
    "data": [
        {
            "kodeEvent": "1",
            "tanggalEvent": "2020-01-15",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Lombok",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8cd198530_202002181405.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "0",
            "createTime": "2020-01-29 16:37:26",
            "updateBy": "",
            "updateTime": "2020-02-18 14:05:53"
        },
        {
            "kodeEvent": "2",
            "tanggalEvent": "2020-03-31",
            "judulEvent": "Bangun Kembali 100 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Jakarta",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d3d74b44_202002181407.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:07:41",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        },
        {
            "kodeEvent": "3",
            "tanggalEvent": "2020-01-31",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Bandung",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d72e2d37_202002181408.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:08:34",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        }
    ]
}
    ''';

      final Map<String, dynamic> responseJson = json.decode(responseString);
      if (responseJson["status"] == "ok") {
        List eventList = responseJson['data'];
        final result = eventList
            .map<EventModel>((json) => EventModel.fromJson(json))
            .toList();
        return result;
      } else {
        //throw CustomError(responseJson['message']);
      }
    } catch (e) {
      return Future.error(e.toString());
    }
  }

  Future<Map<DateTime, List>> getTask1() async {
    Map<DateTime, List> mapFetch = {};
    List<EventModel> event = await getAllEvent();
    for (int i = 0; i < event.length; i++) {
      var createTime = DateTime(event[i].createTime.year,
          event[i].createTime.month, event[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event[i].tanggalEvent];
      } else {
        print(event[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)
          ..addAll([event[i].tanggalEvent]);
      }
    }

    return mapFetch;
  }

  Future<Map<DateTime, List>> getTask() async {
    Map<DateTime, List> mapFetch = {};

    await Future.delayed(const Duration(seconds: 3), () {});

    /*String link = baseURL + fetchTodoByDate;
    var res = await http.post(Uri.encodeFull(link), headers: {"Accept": "application/json"});
    if (res.statusCode == 200) {
      // need help in creating fetch logic here
    }*/

    String responseString = '''
{
    "status": "ok",
    "message": "Event Is Found",
    "data": [
        {
            "kodeEvent": "1",
            "tanggalEvent": "2020-01-15",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Lombok",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8cd198530_202002181405.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "0",
            "createTime": "2020-01-29 16:37:26",
            "updateBy": "",
            "updateTime": "2020-02-18 14:05:53"
        },
        {
            "kodeEvent": "2",
            "tanggalEvent": "2020-03-31",
            "judulEvent": "Bangun Kembali 100 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Jakarta",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d3d74b44_202002181407.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:07:41",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        },
        {
            "kodeEvent": "3",
            "tanggalEvent": "2020-01-31",
            "judulEvent": "Bangun Kembali 200 Masjid dan Mushalla Anti Gempa",
            "lokasiEvent": "Bandung",
            "isiEvent": "Gempa Bumi dahsyat bertubi-tubi guncang lombok, kini Pulau seribu Masjid lemah tak berdaya, Lebih dari 500 Masjid dan Mushalla rata dengan tanah, kini ibadah saudara kita harus bertebaran dimana-mana , masih banyak warga yang tak bisa melaksanakan shalat dengan nyaman. Lokasi masjid dan mushalla sudah tak dapat dipake kembali , semua rusak parah dan bahkan sudh rata dengan tanah.<br /><br />Terpaksa mereka shalat di luar, tempat terbuka , bahkan di atas reruntuhan bangunan rumah sekalipun. Kini tak kurang dari 300 Masjid dan Mushalla yang dilaporkan rusak, dan lebih dari 70 masjid yang hancur rata dengan tanah karena gempa. semua masjid ini tersebar di 3 kabupaten (lombok utara, lombok barat dan lombok timur).",
            "fotoEvent": "event_5e4b8d72e2d37_202002181408.jpg",
            "waktuEvent": "09:00 s.d Selesai",
            "statusEvent": "t",
            "createBy": "",
            "createTime": "2020-02-18 14:08:34",
            "updateBy": "",
            "updateTime": "0000-00-00 00:00:00"
        }
    ]
}
    ''';

    Event event = eventFromJson(responseString);

    for (int i = 0; i < event.data.length; i++) {
      var createTime = DateTime(event.data[i].createTime.year,
          event.data[i].createTime.month, event.data[i].createTime.day);
      var original = mapFetch[createTime];
      if (original == null) {
        print("null");
        mapFetch[createTime] = [event.data[i].tanggalEvent];
      } else {
        print(event.data[i].tanggalEvent);
        mapFetch[createTime] = List.from(original)
          ..addAll([event.data[i].tanggalEvent]);
      }
    }

    return mapFetch;
  }

  void _onDaySelected(DateTime day, List events) {
    print('CALLBACK: _onDaySelected');
    setState(() {
      _selectedEvents = events;
    });
  }

  @override
  void initState() {
    final _selectedDay = DateTime.now();
    _selectedEvents = [];
    _calendarController = CalendarController();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 400),
    );

    _animationController.forward();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      getTask1().then((val) => setState(() {
            _events = val;
          }));
      //print( ' ${_events.toString()} ');
    });
    super.initState();
  }

  @override
  void dispose() {
    _calendarController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _buildTableCalendarWithBuilders(),
            const SizedBox(height: 8.0),
            const SizedBox(height: 8.0),
            Expanded(child: _buildEventList()),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

  Widget _buildTableCalendarWithBuilders() {
    return TableCalendar(
      //locale: 'pl_PL',
      calendarController: _calendarController,
      events: _events,
      //holidays: _holidays,
      initialCalendarFormat: CalendarFormat.month,
      formatAnimation: FormatAnimation.slide,
      startingDayOfWeek: StartingDayOfWeek.sunday,
      availableGestures: AvailableGestures.all,
      availableCalendarFormats: const {
        CalendarFormat.month: '',
        CalendarFormat.week: '',
      },
      calendarStyle: CalendarStyle(
        outsideDaysVisible: false,
        weekendStyle: TextStyle().copyWith(color: Colors.blue[800]),
        holidayStyle: TextStyle().copyWith(color: Colors.blue[800]),
      ),
      daysOfWeekStyle: DaysOfWeekStyle(
        weekendStyle: TextStyle().copyWith(color: Colors.blue[600]),
      ),
      headerStyle: HeaderStyle(
        centerHeaderTitle: true,
        formatButtonVisible: false,
      ),
      builders: CalendarBuilders(
        selectedDayBuilder: (context, date, _) {
          return FadeTransition(
            opacity: Tween(begin: 0.0, end: 1.0).animate(_animationController),
            child: Container(
              margin: const EdgeInsets.all(4.0),
              padding: const EdgeInsets.only(top: 5.0, left: 6.0),
              color: Colors.deepOrange[300],
              width: 100,
              height: 100,
              child: Text(
                '${date.day}',
                style: TextStyle().copyWith(fontSize: 16.0),
              ),
            ),
          );
        },
        todayDayBuilder: (context, date, _) {
          return Container(
            margin: const EdgeInsets.all(4.0),
            padding: const EdgeInsets.only(top: 5.0, left: 6.0),
            color: Colors.amber[400],
            width: 100,
            height: 100,
            child: Text(
              '${date.day}',
              style: TextStyle().copyWith(fontSize: 16.0),
            ),
          );
        },
        markersBuilder: (context, date, events, holidays) {
          final children = <Widget>[];

          if (events.isNotEmpty) {
            children.add(
              Positioned(
                right: 1,
                bottom: 1,
                child: _buildEventsMarker(date, events),
              ),
            );
          }

          if (holidays.isNotEmpty) {
            children.add(
              Positioned(
                right: -2,
                top: -2,
                child: _buildHolidaysMarker(),
              ),
            );
          }

          return children;
        },
      ),
      onDaySelected: (date, events) {
        _onDaySelected(date, events);
        _animationController.forward(from: 0.0);
      },
      onVisibleDaysChanged: _onVisibleDaysChanged,
    );
  }

  void _onVisibleDaysChanged(
      DateTime first, DateTime last, CalendarFormat format) {
    print('CALLBACK: _onVisibleDaysChanged');
  }

  Widget _buildEventsMarker(DateTime date, List events) {
    return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      decoration: BoxDecoration(
        shape: BoxShape.rectangle,
        color: _calendarController.isSelected(date)
            ? Colors.brown[500]
            : _calendarController.isToday(date)
                ? Colors.brown[300]
                : Colors.blue[400],
      ),
      width: 16.0,
      height: 16.0,
      child: Center(
        child: Text(
          '${events.length}',
          style: TextStyle().copyWith(
            color: Colors.white,
            fontSize: 12.0,
          ),
        ),
      ),
    );
  }

  Widget _buildHolidaysMarker() {
    return Icon(
      Icons.add_box,
      size: 20.0,
      color: Colors.blueGrey[800],
    );
  }

  Widget _buildEventList() {
    return ListView(
      children: _selectedEvents
          .map((event) => Container(
                decoration: BoxDecoration(
                  border: Border.all(width: 0.8),
                  borderRadius: BorderRadius.circular(12.0),
                ),
                margin:
                    const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
                child: ListTile(
                  title: Text(event.toString()),
                  onTap: () => print('$event tapped!'),
                ),
              ))
          .toList(),
    );
  }
}

class EventModel {
  String kodeEvent;
  DateTime tanggalEvent;
  String judulEvent;
  String lokasiEvent;
  String isiEvent;
  String fotoEvent;
  String waktuEvent;
  String statusEvent;
  String createBy;
  DateTime createTime;
  String updateBy;
  String updateTime;

  EventModel({
    this.kodeEvent,
    this.tanggalEvent,
    this.judulEvent,
    this.lokasiEvent,
    this.isiEvent,
    this.fotoEvent,
    this.waktuEvent,
    this.statusEvent,
    this.createBy,
    this.createTime,
    this.updateBy,
    this.updateTime,
  });

  factory EventModel.fromJson(Map<String, dynamic> json) => EventModel(
        kodeEvent: json["kodeEvent"],
        tanggalEvent: DateTime.parse(json["tanggalEvent"]),
        judulEvent: json["judulEvent"],
        lokasiEvent: json["lokasiEvent"],
        isiEvent: json["isiEvent"],
        fotoEvent: json["fotoEvent"],
        waktuEvent: json["waktuEvent"],
        statusEvent: json["statusEvent"],
        createBy: json["createBy"],
        createTime: DateTime.parse(json["createTime"]),
        updateBy: json["updateBy"],
        updateTime: json["updateTime"],
      );
}


来源: stackexchange

问:
Get duration of an audio file - Android
I am trying to the duration of my audio files by clicking on them through a ListView. In this list view I am correctly displaying the names on them and I am able to play them, but I would like to know its duration.

I have looked for different questions in Stackoverflow which actually seem to answer this question but I am not truly able to do it so I will leave here my attempt. I have tried to follow this answer but it does not work so I assume that I am falling getting or understanding the Uri.

The file is stored at /raw/

JAVA - 1st attempt

```<code>listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // play desired audio
            Field[] fields = R.raw.class.getFields();
            if(soundMap.selectedEncoder != null) {
                //Log.d(TAG,  String.valueOf(soundMap.getX()) + " " + String.valueOf(soundMap.getY()));
                soundMap.selectedEncoder.play(position, audioFiles[position]);

                // Get duration of the audio file
                Uri uri = Uri.parse("/raw/"+fields[position].getName());
                MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                mmr.setDataSource(getApplicationContext(), uri);
                String durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                //int audioFileDuration = Integer.parseInt(durationStr);

            }
        }
    });
</code>```

The audios are stored at the raw folder. I have also tried to add .mp3 to the uri

ERROR

E/AndroidRuntime: FATAL EXCEPTION: main
      Process: myapp, PID: 26303
      java.lang.IllegalArgumentException

JAVA - 2nd attempt

```<code>File audioFile = new File("/raw/"+fields[position].getName()+ ".mp3");
                    mmr.setDataSource(context, Uri.fromFile(audioFile));
                    String time = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                    long timeInMillisec = Long.parseLong(time );
</code>```

EDIT - 3rd attempt
In the end I have used MediaPlayer

```<code>AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.andthenturnleft);
                if (afd == null) return;
                try {
                    mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int audioFileDuration = mediaPlayer.getDuration();
                /*try {
</code>```

and I get the duration of the file. Nevertheless, first I get the following error:

E/MediaPlayerNative: Attempt to call getDuration in wrong state:
  mPlayer=0xf6f4e7a0, mCurrentState=2

I assume that the error is generated because during the first attempt to get the duration the MediaPlayer is not ready yet. I would like to stop the code until is ready. Nevertheless, in the end I get audioFileDuration with a value of 24 which is not possible because it should return the value in milliseconds and the file is 2seconds long.

4th attempt

```<code>String path = context.getFilesDir().getAbsolutePath();
                try {
                    mediaPlayer.setDataSource(path + fields[position].getName() + ".mp3");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int audioFileDuration = mediaPlayer.getDuration();
</code>```

the problem is this case is that I get  a value of 0 because it does not find the file

open failed: ENOENT (No such file or directory)

How could I properly get the path of the file?

SOLVED
I have posted my own solution. I just needed to find a new way to set the path of the file and I finally managed to do it.

答:
```<code>    implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.14'

            FFmpegMediaMetadataRetriever metadataRetriever = new FFmpegMediaMetadataRetriever();
                metadataRetriever = new FFmpegMediaMetadataRetriever();
                metadataRetriever.setDataSource(url);
        LogMessage.v("1::Duration" + retriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
</code>```

ContentLicense: CC BY-SA 4.0

Title: Get duration of an audio file - Android

Body:
I am trying to the duration of my audio files by clicking on them through a ListView. In this list view I am correctly displaying the names on them and I am able to play them, but I would like to know its duration.

I have looked for different questions in Stackoverflow which actually seem to answer this question but I am not truly able to do it so I will leave here my attempt. I have tried to follow this answer but it does not work so I assume that I am falling getting or understanding the Uri.

The file is stored at /raw/

JAVA - 1st attempt

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // play desired audio
            Field[] fields = R.raw.class.getFields();
            if(soundMap.selectedEncoder != null) {
                //Log.d(TAG,  String.valueOf(soundMap.getX()) + " " + String.valueOf(soundMap.getY()));
                soundMap.selectedEncoder.play(position, audioFiles[position]);

                // Get duration of the audio file
                Uri uri = Uri.parse("/raw/"+fields[position].getName());
                MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                mmr.setDataSource(getApplicationContext(), uri);
                String durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                //int audioFileDuration = Integer.parseInt(durationStr);

            }
        }
    });

The audios are stored at the raw folder. I have also tried to add .mp3 to the uri

ERROR

E/AndroidRuntime: FATAL EXCEPTION: main
      Process: myapp, PID: 26303
      java.lang.IllegalArgumentException

JAVA - 2nd attempt

File audioFile = new File("/raw/"+fields[position].getName()+ ".mp3");
                    mmr.setDataSource(context, Uri.fromFile(audioFile));
                    String time = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                    long timeInMillisec = Long.parseLong(time );

EDIT - 3rd attempt
In the end I have used MediaPlayer

AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.andthenturnleft);
                if (afd == null) return;
                try {
                    mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int audioFileDuration = mediaPlayer.getDuration();
                /*try {

and I get the duration of the file. Nevertheless, first I get the following error:

E/MediaPlayerNative: Attempt to call getDuration in wrong state:
  mPlayer=0xf6f4e7a0, mCurrentState=2

I assume that the error is generated because during the first attempt to get the duration the MediaPlayer is not ready yet. I would like to stop the code until is ready. Nevertheless, in the end I get audioFileDuration with a value of 24 which is not possible because it should return the value in milliseconds and the file is 2seconds long.

4th attempt

String path = context.getFilesDir().getAbsolutePath();
                try {
                    mediaPlayer.setDataSource(path + fields[position].getName() + ".mp3");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                int audioFileDuration = mediaPlayer.getDuration();

the problem is this case is that I get  a value of 0 because it does not find the file

open failed: ENOENT (No such file or directory)

How could I properly get the path of the file?

SOLVED
I have posted my own solution. I just needed to find a new way to set the path of the file and I finally managed to do it.


问:
Use Azure custom vision model with Node.js
i am new to Tensorflow.js so, i don't quite understand it completely.
I have trained an object detection model using Azure Custom Vision (customvision.ai) and as described in there documentation i exported the model for Tensorflow.js for offline use in my Node.js Project.

They have a very brief guide on Github (https://github.com/microsoft/customvision-tfjs) on how to use the model with Tensorflow.js, i tried following the steps but was not able to run it.

If anyone has experience with Tensorflow.js, please help me in this i am stuck on it for past 3 days.

This is the Code that i am trying to execute, i am getting Error

'await can only be used with async functions'

even though the loadModelAsync() function is Async.

```<code>const cvstfjs = require('@microsoft/customvision-tfjs');

let model = new cvstfjs.ObjectDetectionModel();
await model.loadModelAsync('model.json');
const image = document.getElementById('image');
const result = await model.executeAsync(image);
</code>```

答:
Did you see ONNX.js  that run ONNX models using JavaScript.
https://github.com/microsoft/onnxjs

Body:
i am new to Tensorflow.js so, i don't quite understand it completely.
I have trained an object detection model using Azure Custom Vision (customvision.ai) and as described in there documentation i exported the model for Tensorflow.js for offline use in my Node.js Project.

They have a very brief guide on Github (https://github.com/microsoft/customvision-tfjs) on how to use the model with Tensorflow.js, i tried following the steps but was not able to run it.

If anyone has experience with Tensorflow.js, please help me in this i am stuck on it for past 3 days.

This is the Code that i am trying to execute, i am getting Error

'await can only be used with async functions'

even though the loadModelAsync() function is Async.

const cvstfjs = require('@microsoft/customvision-tfjs');

let model = new cvstfjs.ObjectDetectionModel();
await model.loadModelAsync('model.json');
const image = document.getElementById('image');
const result = await model.executeAsync(image);


问:
Is there a way to get job creation date in laravel?
Is there a way to get a queue job's creation date in laravel while executing the job? My queue driver is redis and I can't change that.</p>

答: Apparently, there's no built-in way for getting the job creation date in laravel for redis and as @PtrTon stated, you'd have to store that yourself.</p>


问:
React Axios how to correctly pass in config as parameter?
Does anyone know how to pass in config in Axios?
It works when the option that is passed in is "method:'GET'", but it won't work when options are "method:'POST,data:jsondata". it returns error 500 with 'GET' method. Why is it still a 'GET' method, is there a workaround or I'm doing it wrong?
I want to call only this function when using Axios.

```<code> fetchWithToken(url, options) {
        const headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' }
        if (this.loggedIn) {
            headers['Authorization'] = 'Bearer ' + this.getToken()
            return axios(url, { headers, options })
                .then(response => { return response })
        }
}
</code>```

答:
There is a syntax problem with your method. You are passing the object which has another object, which you should use as parameter in your axios request.

I would do it like this:

```<code> fetchWithToken = (url, options)=>{
  const headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' }
  if (this.loggedIn) {
      headers['Authorization'] = 'Bearer ' + this.getToken()
      return axios({url: url, headers: headers, data: options.data, method: options.method})
          .then(response => { return response })
   }
}

const obj = {method:'POST', data:""};
fetchWithToken(url, obj);
</code>```

So you now can call fetchWithToken(url,{method:'POST',data:jsondata})

Body:
Does anyone know how to pass in config in Axios?
It works when the option that is passed in is "method:'GET'", but it won't work when options are "method:'POST,data:jsondata". it returns error 500 with 'GET' method. Why is it still a 'GET' method, is there a workaround or I'm doing it wrong?
I want to call only this function when using Axios.

 fetchWithToken(url, options) {
        const headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' }
        if (this.loggedIn) {
            headers['Authorization'] = 'Bearer ' + this.getToken()
            return axios(url, { headers, options })
                .then(response => { return response })
        }
}

Body:
There is a syntax problem with your method. You are passing the object which has another object, which you should use as parameter in your axios request.

I would do it like this:

 fetchWithToken = (url, options)=>{
  const headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' }
  if (this.loggedIn) {
      headers['Authorization'] = 'Bearer ' + this.getToken()
      return axios({url: url, headers: headers, data: options.data, method: options.method})
          .then(response => { return response })
   }
}

const obj = {method:'POST', data:""};
fetchWithToken(url, obj);

So you now can call fetchWithToken(url,{method:'POST',data:jsondata})


问:
Is there a keyboard shortcut for "Select all" in a terminal in Visual Studio Code?
Headline says it all:

Is there a keyboard shortcut for "Select all" in a terminal in Visual Studio Code?

I tried all the usual suspects (Ctrl-A, Ctrl-Shift-A) on Windows but none of them works.

答: Just right click then click select all.

Body: Just right click then click select all.


问:
Select multiple result by grouping same values from single column?
I am creating an email alert to send out three email separately from the below table:

```<code>|**ID** |**Name**      |**Company**    |**Count**|
|1      |John          |Apple          |2        |
|2      |Bill          |Microsoft      |2        |
|3      |Steve         |Apple          |2        |
|4      |Elon          |Tesla          |1        |
|5      |Satya         |Microsoft      |2        |
</code>```

I desire to get all three different result to send the email separately

```<code>|**ID** |**Name**      |**Company**    |
|1      |John          |Apple          |
|3      |Steve         |Apple          |

AND

|**ID** |**Name**      |**Company**    |
|2      |Bill          |Microsoft      |
|5      |Satya         |Microsoft      |

AND

|**ID** |**Name**      |**Company**    |
|4      |Elon          |Tesla          |
</code>```

How could I get the desired result as above in SQL?

答: SELECT * FROM your_table ORDER BY Company;

Body:
I am creating an email alert to send out three email separately from the below table:

|**ID** |**Name**      |**Company**    |**Count**|
|1      |John          |Apple          |2        |
|2      |Bill          |Microsoft      |2        |
|3      |Steve         |Apple          |2        |
|4      |Elon          |Tesla          |1        |
|5      |Satya         |Microsoft      |2        |

I desire to get all three different result to send the email separately

|**ID** |**Name**      |**Company**    |
|1      |John          |Apple          |
|3      |Steve         |Apple          |

AND

|**ID** |**Name**      |**Company**    |
|2      |Bill          |Microsoft      |
|5      |Satya         |Microsoft      |

AND

|**ID** |**Name**      |**Company**    |
|4      |Elon          |Tesla          |

How could I get the desired result as above in SQL?


问:
Handle error on user authentication with Firebase
I have a Firebase conecction to my React Native app, and I authenticate an user via email and password. However, each time a user enters a correct email and password, it stills shows me the alert I programmed to show whenever a user inputs a wrong email/password, then it redirects the user to the next page, showing that the user authentication was succesful.

What can I do to prevent the alert from showing up when an user authentication was sucessful?
Here's my code

```<code>firebase.auth().signInWithEmailAndPassword(this.state.username, this.state.password).catch(
        Alert.alert(
          'Error',
          'Incorrect data',
          [
            { text: 'Ok' }
          ],
          { cancelable: false }
        )
).then(() => this.props.navigation.navigate('Age'));
</code>```

答:
Try this code</p>

```<code>    try {
      firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => this.props.navigation.navigate('Age'));
    }
    catch (error) {
      console.log(error);
       Alert.alert(
          error,
          'Incorrect data',
          [
            { text: 'Ok' }
          ],
          { cancelable: false }
        )
    }

</code>```

Body:
I have a Firebase conecction to my React Native app, and I authenticate an user via email and password. However, each time a user enters a correct email and password, it stills shows me the alert I programmed to show whenever a user inputs a wrong email/password, then it redirects the user to the next page, showing that the user authentication was succesful.

What can I do to prevent the alert from showing up when an user authentication was sucessful?
Here's my code

firebase.auth().signInWithEmailAndPassword(this.state.username, this.state.password).catch(
        Alert.alert(
          'Error',
          'Incorrect data',
          [
            { text: 'Ok' }
          ],
          { cancelable: false }
        )
).then(() => this.props.navigation.navigate('Age'));

Body:
Try this code

    try {
      firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => this.props.navigation.navigate('Age'));
    }
    catch (error) {
      console.log(error);
       Alert.alert(
          error,
          'Incorrect data',
          [
            { text: 'Ok' }
          ],
          { cancelable: false }
        )
    }


问:
Batch renaming files with Bash
How can Bash rename a series of packages to remove their version numbers? I've been toying around with both expr and %%, to no avail.

Examples:

Xft2-2.1.13.pkg becomes Xft2.pkg

jasper-1.900.1.pkg becomes jasper.pkg

xorg-libXrandr-1.2.3.pkg becomes xorg-libXrandr.pkg

答:
This seems to work assuming that

everything ends with $pkg

your version #'s always start with a "-"

strip off the .pkg, then strip off -..

```<code>for x in $(ls); do echo $x $(echo $x | sed 's/\.pkg//g' | sed 's/-.*//g').pkg; done
</code>```

OwnerDisplayName: Nerdling

ContentLicense: CC BY-SA 3.0

Title: Batch renaming files with Bash

Body:
This seems to work assuming that

everything ends with $pkg

your version #'s always start with a "-"

strip off the .pkg, then strip off -..

for x in $(ls); do echo $x $(echo $x | sed 's/\.pkg//g' | sed 's/-.*//g').pkg; done

OwnerDisplayName: Steve B.

ContentLicense: CC BY-SA 2.5


问:
Get public properties that aren’t static with PHP Reflection
I need to use PHP Reflection API to get all the publicly accessible properties for a class that aren’t static.

In order to get just the public properties that are not static, the only way I could see to do it was to get the IS_STATIC properties and use array_diff() to get only the public ones.

Final class looks like this :

```<code>class foo {
    public static $a;
    public static $b;
    public static $c;

    public $d;
    public $e;
    public $f;

    public function reflect()
    {
        $reflection = new ReflectionClass($this);
        $public = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
        $static = $reflection->getProperties(ReflectionProperty::IS_STATIC);
        $properties = array_diff($public, $static);
        foreach($properties as $property) {
            echo $property->name . "n";
        }
    }

}
</code>```

Call:

```<code>$foo = new foo;
$foo->reflect();
</code>```

The output from reflect() now looks like this :

```<code>d
e
f
</code>```

Question : Is there a better way to do this ?

Note : My original class is too long! This class is an example similer to mine.

答:
The fastest way is definitely use get_object_vars, for your case:

```<code>print_r(get_object_vars($foo));
// outputs
Array
(
    [d] =>
    [e] =>
    [f] =>
)
</code>```

Keys are propertes' names.

But instantiating an instance can be quite heavy. So, you still can use reflection and a little of filtering:

```<code>public function reflect()
{
    $reflection = new ReflectionClass($this);
    $properties =  array_filter(
        $reflection->getProperties(ReflectionProperty::IS_PUBLIC),
        function ($property) {
            return !$property->isStatic();
        }
    );
    foreach($properties as $property) {
        echo $property->name . "\n";
    }
}
</code>```

Body:
I need to use PHP Reflection API to get all the publicly accessible properties for a class that aren’t static.

In order to get just the public properties that are not static, the only way I could see to do it was to get the IS_STATIC properties and use array_diff() to get only the public ones.

Final class looks like this :

class foo {
    public static $a;
    public static $b;
    public static $c;

    public $d;
    public $e;
    public $f;

    public function reflect()
    {
        $reflection = new ReflectionClass($this);
        $public = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
        $static = $reflection->getProperties(ReflectionProperty::IS_STATIC);
        $properties = array_diff($public, $static);
        foreach($properties as $property) {
            echo $property->name . "n";
        }
    }

}

Call:

$foo = new foo;
$foo->reflect();

The output from reflect() now looks like this :

d
e
f

Question : Is there a better way to do this ?

Note : My original class is too long! This class is an example similer to mine.

Body:
The fastest way is definitely use get_object_vars, for your case:

print_r(get_object_vars($foo));
// outputs
Array
(
    [d] =>
    [e] =>
    [f] =>
)

Keys are propertes' names.

But instantiating an instance can be quite heavy. So, you still can use reflection and a little of filtering:

public function reflect()
{
    $reflection = new ReflectionClass($this);
    $properties =  array_filter(
        $reflection->getProperties(ReflectionProperty::IS_PUBLIC),
        function ($property) {
            return !$property->isStatic();
        }
    );
    foreach($properties as $property) {
        echo $property->name . "\n";
    }
}


问:
AmCharts animated line on map chart
I want to use amCharts for create connection map.

I take this demo: https://www.amcharts.com/demos/animations-along-lines

But, I want to have a growing line instead of an plane. Can this be implemented?

```<code>var planeImage = plane.createChild(am4core.Sprite);
planeImage.scale = 0.08;
planeImage.horizontalCenter = "middle";
planeImage.verticalCenter = "middle";
planeImage.path = "m2,106h28l24,30h72l-44,-133h35l80,132h98c21,0 21,34 0,34l-98,0 -80,134h-35l43,-133h-71l-24,30h-28l15,-47";
planeImage.fill = chart.colors.getIndex(2).brighten(-0.2);
planeImage.strokeOpacity = 0;
</code>```

答:
The issue can be closed.
I found solution from documentation: https://www.amcharts.com/docs/v4/tutorials/animating-map-lines-with-css/</p>

Title: AmCharts animated line on map chart

Body:
I want to use amCharts for create connection map.

I take this demo: https://www.amcharts.com/demos/animations-along-lines

But, I want to have a growing line instead of an plane. Can this be implemented?

var planeImage = plane.createChild(am4core.Sprite);
planeImage.scale = 0.08;
planeImage.horizontalCenter = "middle";
planeImage.verticalCenter = "middle";
planeImage.path = "m2,106h28l24,30h72l-44,-133h35l80,132h98c21,0 21,34 0,34l-98,0 -80,134h-35l43,-133h-71l-24,30h-28l15,-47";
planeImage.fill = chart.colors.getIndex(2).brighten(-0.2);
planeImage.strokeOpacity = 0;


问:
Why does it get same value?? and how to attach currency sign after result?
Why does it get same value?? and how to attach currency sign after result?
also, How to make it more briefly? I want to amend the repeating code.

function changeSign() {
  var currencySelect = document.getElementById("CurrencyID").value;
}

function changeCurrency() {

  var inputVal = parseFloat(document.getElementById("inputMoney").value);
  var currencyVal = parseFloat(document.getElementById("inputMoney"));

  if (document.getElementById("Euro")) {

    if (document.getElementById("Us1")) {

      currencyVal = (inputVal * 1.08);

    } else if (document.getElementById("Uk1")) {

      currencyVal = (inputVal * 0.83);

    } else if (document.getElementById("Ja1")) {

      currencyVal = (inputVal * 118.88);

    } else if (document.getElementById("Ca1")) {

      currencyVal = (inputVal * 1.43);
    }
  }

  document.getElementById("demo").textContent = currencyVal;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><b>Choose Convert : </b><br><br>
<select name="CurrencyConverter" id="CurrencyID" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;" onchange="changeSign()">
  <option id="Euro" value="€">Euro (EUR)</option>
  <option id="Us" value="$">US Dollar (USD)</option>
  <option id="Uk" value="£">UK Pound Sterling (GBP)</option>
  <option id="Ja" value="¥">Japanese Yen (JPY)</option>
  <option id="Ca" value="$">Canadian Dollor (CAD)</option>
</select>
<br>

<b>Choose Convert : </b><br><br>
<select name="CurrencyConverter" id="CurrencyID" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;">
  <option id="Euro1" value="€">Euro (EUR)</option>
  <option id="Us1" value="$">US Dollar (USD)</option>
  <option id="Uk1" value="£">UK Pound Sterling (GBP)</option>
  <option id="Ja1" value="¥">Japanese Yen (JPY)</option>
  <option id="Ca1" value="$">Canadian Dollor (CAD)</option>
</select>
<br>

<label>
                <br>
                <input name="inputMoney" id="inputMoney" type="text" class="text ui-widget-content ui-corner-all"
                    style="width: 196px; height:22px;" oninput="changeCurrency()"
                    >
            </label><br><br>

</div>
</div>

<p>value: <span id="demo"></span></p></code>```

答:
1- you are not getting value of select's
2- you need InnerHTML not inner text
3- I guess simple map would be better than if elses

function changeSign() {
  var currencySelect = document.getElementById("CurrencyID").value;
}

function changeCurrency() {

  var inputVal = parseFloat(document.getElementById("inputMoney").value);
  var exchange={"euro;euro;":1,
"euro;dollar;":1.08,"euro;pound;":0.83,"euro;yen;":1118.88,"euro;#36;":1.43
};
var ev=document.getElementById("CurrencyID1").value+document.getElementById("CurrencyID2").value;
currencyVal=exchange[ev] *inputVal;

  document.getElementById("demo").innerHTML = currencyVal +" &"+document.getElementById("CurrencyID2").value;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><b>Choose Convert : </b><br><br>
<select name="CurrencyConverter" id="CurrencyID1" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;" onchange="changeSign()">
  <option id="Euro" value="euro;">Euro (EUR)</option>
  <option id="Us" value="dollar;">US Dollar (USD)</option>
  <option id="Uk" value="pound;">UK Pound Sterling (GBP)</option>
  <option id="Ja" value="yen;">Japanese Yen (JPY)</option>
  <option id="Ca" value="#36;">Canadian Dollor (CAD)</option>
</select>
<br>

<b>Choose Convert : </b><br><br>
<select name="CurrencyConverter" id="CurrencyID2" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;">
  <option id="Euro1" value="euro;">Euro (EUR)</option>
  <option id="Us1" value="dollar;">US Dollar (USD)</option>
  <option id="Uk1" value="pound;">UK Pound Sterling (GBP)</option>
  <option id="Ja1" value="yen;">Japanese Yen (JPY)</option>
  <option id="Ca1" value="#36;">Canadian Dollor (CAD)</option>
</select>
<br>

<label>
                <br>
                <input name="inputMoney" id="inputMoney" type="text" class="text ui-widget-content ui-corner-all"
                    style="width: 196px; height:22px;" oninput="changeCurrency()"
                    >
            </label><br><br>

</div>
</div>

<p>value: <span id="demo"></span></p></code>```

Body:
Why does it get same value?? and how to attach currency sign after result?
also, How to make it more briefly? I want to amend the repeating code.

function changeSign() {
  var currencySelect = document.getElementById("CurrencyID").value;
}

function changeCurrency() {

  var inputVal = parseFloat(document.getElementById("inputMoney").value);
  var currencyVal = parseFloat(document.getElementById("inputMoney"));

  if (document.getElementById("Euro")) {

    if (document.getElementById("Us1")) {

      currencyVal = (inputVal * 1.08);

    } else if (document.getElementById("Uk1")) {

      currencyVal = (inputVal * 0.83);

    } else if (document.getElementById("Ja1")) {

      currencyVal = (inputVal * 118.88);

    } else if (document.getElementById("Ca1")) {

      currencyVal = (inputVal * 1.43);
    }
  }

  document.getElementById("demo").textContent = currencyVal;
}

Choose Convert :

<select name="CurrencyConverter" id="CurrencyID" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;" onchange="changeSign()">
  <option id="Euro" value="€">Euro (EUR)</option>
  <option id="Us" value="$">US Dollar (USD)</option>
  <option id="Uk" value="£">UK Pound Sterling (GBP)</option>
  <option id="Ja" value="¥">Japanese Yen (JPY)</option>
  <option id="Ca" value="$">Canadian Dollor (CAD)</option>
</select>

Choose Convert :

<select name="CurrencyConverter" id="CurrencyID" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;">
  <option id="Euro1" value="€">Euro (EUR)</option>
  <option id="Us1" value="$">US Dollar (USD)</option>
  <option id="Uk1" value="£">UK Pound Sterling (GBP)</option>
  <option id="Ja1" value="¥">Japanese Yen (JPY)</option>
  <option id="Ca1" value="$">Canadian Dollor (CAD)</option>
</select>

                <input name="inputMoney" id="inputMoney" type="text" class="text ui-widget-content ui-corner-all"
                    style="width: 196px; height:22px;" oninput="changeCurrency()"
                    >

value:

Body:
1- you are not getting value of select's
2- you need InnerHTML not inner text
3- I guess simple map would be better than if elses

function changeSign() {
  var currencySelect = document.getElementById("CurrencyID").value;
}

function changeCurrency() {

  var inputVal = parseFloat(document.getElementById("inputMoney").value);
  var exchange={"euro;euro;":1,
"euro;dollar;":1.08,"euro;pound;":0.83,"euro;yen;":1118.88,"euro;#36;":1.43
};
var ev=document.getElementById("CurrencyID1").value+document.getElementById("CurrencyID2").value;
currencyVal=exchange[ev] *inputVal;

  document.getElementById("demo").innerHTML = currencyVal +" &"+document.getElementById("CurrencyID2").value;
}

<b>Choose Convert : </b><br><br>
<select name="CurrencyConverter" id="CurrencyID1" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;" onchange="changeSign()">
  <option id="Euro" value="euro;">Euro (EUR)</option>
  <option id="Us" value="dollar;">US Dollar (USD)</option>
  <option id="Uk" value="pound;">UK Pound Sterling (GBP)</option>
  <option id="Ja" value="yen;">Japanese Yen (JPY)</option>
  <option id="Ca" value="#36;">Canadian Dollor (CAD)</option>
</select>
<br>

<b>Choose Convert : </b><br><br>
<select name="CurrencyConverter" id="CurrencyID2" class="text ui-widget-content ui-corner-all" style="width: 200px; height:30px;">
  <option id="Euro1" value="euro;">Euro (EUR)</option>
  <option id="Us1" value="dollar;">US Dollar (USD)</option>
  <option id="Uk1" value="pound;">UK Pound Sterling (GBP)</option>
  <option id="Ja1" value="yen;">Japanese Yen (JPY)</option>
  <option id="Ca1" value="#36;">Canadian Dollor (CAD)</option>
</select>
<br>

<label>
                <br>
                <input name="inputMoney" id="inputMoney" type="text" class="text ui-widget-content ui-corner-all"
                    style="width: 196px; height:22px;" oninput="changeCurrency()"
                    >
            </label><br><br>

</div>
</div>

<p>value: <span id="demo"></span></p>