Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Find closest date to today from API results

I’ve come across a problem which I cannot figure out. I’m trying to display single event on my home screen which is next upcoming by date. That event comes from list of events in the api.
Currently I am using listview.builder to display those events however when I set item count to 1 I cannot get the next event by date to be displayed. I was trying to display all events in listview.builder and then filter but I couldn’t get it to work.

I need to display events in that order but they need to be shown 1 by 1 based on todays time. So when current time is the same as the events time next event will be shown:
firstImage

And this is what I’m getting when the itemCount is 1. This is the last event from the list

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

which I tried to reverse but no success. secondImage

This is code for the ListView.builder

ListView.builder(
        reverse: true,
        shrinkWrap: true,
        physics: ClampingScrollPhysics(),
        // itemCount: 1,
        itemCount: 1,
        itemBuilder: (context, index) {
          var x = eventController.event.value!.data![index];
          DateTime formattedStartDate = new DateFormat('yyyy-MM-dd hh:mm')
              .parse(eventController
                  .event.value!.data![index].eventStartDate
                  .toString());
          DateTime splitStartDate = new DateTime(
              formattedStartDate.year,
              formattedStartDate.month,
              formattedStartDate.day,
              formattedStartDate.hour,
              formattedStartDate.minute);

          DateTime today = DateTime.now();
          bool isAfter = splitStartDate.isAfter(today);
          
          return Column(
            children: [
              isAfter == true
                  ? GestureDetector(
                      onTap: () {
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => EventDetails(
                                    event: eventController
                                        .event.value!.data![index])));
                      },
                      child: EventTileMain(
                          eventController.event.value!.data![index]))
                  : Container()
            ],
          );
        });

This is model calss of event:

    // To parse this JSON data, do
//
//     final event = eventFromJson(jsonString);

import 'dart:convert';

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

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

class Event {
  Event({
    this.success,
    this.data,
    this.code,
    this.count,
  });

  bool? success;
  List<Datum>? data;
  int? code;
  int? count;

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

  Map<String, dynamic> toJson() => {
    "success": success,
    "data": List<dynamic>.from(data!.map((x) => x.toJson())),
    "code": code,
    "count": count,
  };
}

class Datum {
  Datum({
    this.id,
    this.postTitle,
    this.postContent,
    this.postName,
    this.postUrl,
    this.organizer,
    this.venue,
    this.category,
    this.speaker,
    this.eventStartDate,
    this.eventEndDate,
    this.eventDate,
    this.featuredImage,
  });

  String? id;
  String? postTitle;
  String? postContent;
  String? postName;
  String? postUrl;
  List<Category>? organizer;
  List<Category>? venue;
  List<Category>? category;
  dynamic speaker;
  String? eventStartDate;
  String? eventEndDate;
  DateTime? eventDate;
  String? featuredImage;

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
    id: json["ID"],
    postTitle: json["post_title"],
    postContent: json["post_content"],
    postName: json["post_name"],
    postUrl: json["post_url"],
    organizer: List<Category>.from(json["organizer"].map((x) => Category.fromJson(x))),
    venue: List<Category>.from(json["venue"].map((x) => Category.fromJson(x))),
    category: List<Category>.from(json["category"].map((x) => Category.fromJson(x))),
    speaker: json["speaker"],
    eventStartDate: json["event_start_date"],
    eventEndDate: json["event_end_date"],
    eventDate: DateTime.parse(json["event_date"]),
    featuredImage: json["featured_image"],
  );

  Map<String, dynamic> toJson() => {
    "ID": id,
    "post_title": postTitle,
    "post_content": postContent,
    "post_name": postName,
    "post_url": postUrl,
    "organizer": List<dynamic>.from(organizer!.map((x) => x.toJson())),
    "venue": List<dynamic>.from(venue!.map((x) => x.toJson())),
    "category": List<dynamic>.from(category!.map((x) => x.toJson())),
    "speaker": speaker,
    "event_start_date": eventStartDate,
    "event_end_date": eventEndDate,
    "event_date": eventDate!.toIso8601String(),
    "featured_image": featuredImage,
  };
}

class Category {
  Category({
    this.id,
    this.name,
  });

  int? id;
  Name? name;

  factory Category.fromJson(Map<String, dynamic> json) => Category(
    id: json["id"],
    name: nameValues.map[json["name"]],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "name": nameValues.reverse![name],
  };
}

enum Name { AUDITORIUM, SEMINAR, XPOSURE, XPOSURE_INTERNATIONAL_PHOTOGRAPHY_FESTIVAL, TOR_SEIDEL, XPOSURE_AUDITORIUM }

final nameValues = EnumValues({
  "Auditorium": Name.AUDITORIUM,
  "Seminar": Name.SEMINAR,
  "Tor Seidel": Name.TOR_SEIDEL,
  "Xposure": Name.XPOSURE,
  "Xposure Auditorium": Name.XPOSURE_AUDITORIUM,
  "Xposure International Photography Festival": Name.XPOSURE_INTERNATIONAL_PHOTOGRAPHY_FESTIVAL
});

class EnumValues<T> {
  Map<String, T> map;
  Map<T, String>? reverseMap;

  EnumValues(this.map);

  Map<T, String>? get reverse {
    if (reverseMap == null) {
      reverseMap = map.map((k, v) => new MapEntry(v, k));
    }
    return reverseMap;
  }
}

API call

class EventApi {
  static var client = http.Client();
  static Future<Event?> fetchEvents() async {
    final response = await client.get(Uri.parse(
        'https://xposure.ae/api/v1/events/'));
        // 'https://xposure.ae/wp-json/wp/auditorium/v1/events'));
    if (response.statusCode == 200) {
      var jsonString = response.body;
      return eventFromJson(jsonString);
    } else {
      return null;
    }
  }
}

If you need more information please let me know.

>Solution :

you can try this:

ListView.builder(
        reverse: true,
        shrinkWrap: true,
        physics: ClampingScrollPhysics(),
        // itemCount: 1,
        itemCount: 1,
        itemBuilder: (context, index) {

          var now = DateTime.now();
          Datum? closestEvent;
          eventController.event.value!.data!.forEach((element) {
            var elementDate =
               DateFormat('yyyy-MM-dd hh:mm').parse(element.eventStartDate);
            if (closestEvent == null) {
              if (elementDate.isAfter(now)) {
                 closestEvent = element;
              }
            } else {
               var closestDate = DateFormat('yyyy-MM-dd hh:mm').parse(closestEvent!.eventStartDate);
               if (elementDate.isAfter(now) && elementDate.isBefore(closestDate)) {
                   closestEvent = element;
               }
             }
          });

          return Column(
            children: [
              isAfter == true
                  ? GestureDetector(
                      onTap: () {
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => EventDetails(
                                    event: closestEvent)));
                      },
                      child: EventTileMain(
                          closestEvent))
                  : Container()
            ],
          );
        });

you can simply make a widget function and remove your listview, like this:

Widget buildEventWidget(BuildContext context){

   var now = DateTime.now();
          Datum? closestEvent;
          eventController.event.value!.data!.forEach((element) {
            var elementDate =
               DateFormat('yyyy-MM-dd hh:mm').parse(element.eventStartDate);
            if (closestEvent == null) {
              if (elementDate.isAfter(now)) {
                 closestEvent = element;
              }
            } else {
               var closestDate = DateFormat('yyyy-MM-dd hh:mm').parse(closestEvent!.eventStartDate);
               if (elementDate.isAfter(now) && elementDate.isBefore(closestDate)) {
                   closestEvent = element;
               }
             }
          });

    return Column(
            children: [
              isAfter == true
                  ? GestureDetector(
                      onTap: () {
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => EventDetails(
                                    event: closestEvent)));
                      },
                      child: EventTileMain(
                          closestEvent))
                  : Container()
            ],
          );

}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading