Event.fromJson constructor

Event.fromJson(
  1. Map<String, dynamic>? json
)

Get Event from JSON.

Sample JSON: {calendarId: 00, eventId: 0000, eventTitle: Sample Event, eventDescription: This is a sample event, eventStartDate: 1563719400000, eventStartTimeZone: Asia/Hong_Kong, eventEndDate: 1640532600000, eventEndTimeZone: Asia/Hong_Kong, eventAllDay: false, eventLocation: Yuenlong Station, eventURL: null, availability: BUSY, attendees: {name: commonfolk, emailAddress: total.loss@hong.com, role: 1, isOrganizer: false, attendanceStatus: 3}, reminders: {minutes: 39}}

Implementation

Event.fromJson(Map<String, dynamic>? json) {
  if (json == null) {
    throw ArgumentError(ErrorMessages.fromJsonMapIsNull);
  }
  String? foundUrl;
  String? startLocationName;
  String? endLocationName;
  int? startTimestamp;
  int? endTimestamp;
  bool legacyJSON = false;
  var legacyName = {
    title: 'title',
    description: 'description',
    startTimestamp: 'start',
    endTimestamp: 'end',
    startLocationName: 'startTimeZone',
    endLocationName: 'endTimeZone',
    allDay: 'allDay',
    location: 'location',
    foundUrl: 'url',
  };
  legacyName.forEach((key, value) {
    if (json[value] != null) {
      key = json[value];
      legacyJSON = true;
    }
  });

  eventId = json['eventId'];
  calendarId = json['calendarId'];
  title = json['eventTitle'];
  description = json['eventDescription'];

  startTimestamp = json['eventStartDate'];
  startLocationName = json['eventStartTimeZone'];
  var startTimeZone = timeZoneDatabase.locations[startLocationName];
  startTimeZone ??= local;
  start = startTimestamp != null
      ? TZDateTime.fromMillisecondsSinceEpoch(startTimeZone, startTimestamp)
      : TZDateTime.now(local);

  endTimestamp = json['eventEndDate'];
  endLocationName = json['eventEndTimeZone'];
  var endLocation = timeZoneDatabase.locations[endLocationName];
  endLocation ??= startTimeZone;
  end = endTimestamp != null
      ? TZDateTime.fromMillisecondsSinceEpoch(endLocation, endTimestamp)
      : TZDateTime.now(local);
  allDay = json['eventAllDay'] ?? false;
  if (Platform.isAndroid && (allDay ?? false)) {
    // On Android, the datetime in an allDay event is adjusted to local
    // timezone, which can result in the wrong day, so we need to bring the
    // date back to midnight UTC to get the correct date
    var startOffset = start?.timeZoneOffset.inMilliseconds ?? 0;
    var endOffset = end?.timeZoneOffset.inMilliseconds ?? 0;
    // subtract the offset to get back to midnight on the correct date
    start = start?.subtract(Duration(milliseconds: startOffset));
    end = end?.subtract(Duration(milliseconds: endOffset));
    // The Event End Date for allDay events is midnight of the next day, so
    // subtract one day
    end = end?.subtract(const Duration(days: 1));
  }
  location = json['eventLocation'];
  availability = parseStringToAvailability(json['availability']);
  status = parseStringToEventStatus(json['eventStatus']);

  foundUrl = json['eventURL']?.toString();
  if (foundUrl?.isEmpty ?? true) {
    url = null;
  } else {
    url = Uri.dataFromString(foundUrl as String);
  }

  if (json['attendees'] != null) {
    attendees = json['attendees'].map<Attendee>((decodedAttendee) {
      return Attendee.fromJson(decodedAttendee);
    }).toList();
  }

  if (json['organizer'] != null) {
    // Getting and setting an organiser for iOS
    var organiser = Attendee.fromJson(json['organizer']);

    var attendee = attendees?.firstWhereOrNull((at) =>
        at?.name == organiser.name &&
        at?.emailAddress == organiser.emailAddress);
    if (attendee != null) {
      attendee.isOrganiser = true;
    }
  }

  if (json['recurrenceRule'] != null) {
    recurrenceRule = RecurrenceRule.fromJson(json['recurrenceRule']);
  }

  if (json['reminders'] != null) {
    reminders = json['reminders'].map<Reminder>((decodedReminder) {
      return Reminder.fromJson(decodedReminder);
    }).toList();
  }
  if (legacyJSON) {
    throw const FormatException(
        'legacy JSON detected. Please update your current JSONs as they may not be supported later on.');
  }
}