import "dart:convert"; import "dart:developer"; import 'package:dio/dio.dart'; import 'package:anyway/constants.dart'; import "package:anyway/structs/landmark.dart"; import "package:anyway/structs/trip.dart"; import "package:anyway/structs/preferences.dart"; Dio dio = Dio( BaseOptions( baseUrl: API_URL_BASE, connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 120), // also accept 500 errors, since we cannot rule out that the server is at fault. We still want to gracefully handle these errors validateStatus: (status) => status! <= 500, receiveDataWhenStatusError: true, // api is notoriously slow // headers: { // HttpHeaders.userAgentHeader: 'dio', // 'api': '1.0.0', // }, contentType: Headers.jsonContentType, responseType: ResponseType.json, ), ); fetchTrip( Trip trip, Future preferences, ) async { UserPreferences prefs = await preferences; Map data = { "preferences": prefs.toJson(), "start": trip.landmarks!.first.location, }; String dataString = jsonEncode(data); log(dataString); final response = await dio.post( "/trip/new", data: data ); // handle errors if (response.statusCode != 200) { trip.updateUUID("error"); if (response.data["detail"] != null) { trip.updateError(response.data["detail"]); log(response.data["detail"]); // throw Exception(response.data["detail"]); } } else { Map json = response.data; // only fill in the trip "meta" data for now trip.loadFromJson(json); // now fill the trip with landmarks // we are going to recreate ALL the landmarks from the information given by the api trip.landmarks.remove(trip.landmarks.first); String? nextUUID = json["first_landmark_uuid"]; while (nextUUID != null) { var (landmark, newUUID) = await fetchLandmark(nextUUID); trip.addLandmark(landmark); nextUUID = newUUID; } log(response.data.toString()); } } Future<(Landmark, String?)> fetchLandmark(String uuid) async { final response = await dio.get( "/landmark/$uuid" ); // handle errors if (response.statusCode != 200) { throw Exception('Failed to load landmark'); } if (response.data["detail"] != null) { throw Exception(response.data["detail"]); } log(response.data.toString()); Map json = response.data; String? nextUUID = json["next_uuid"]; return (Landmark.fromJson(json), nextUUID); }