How to handle exeptions in flutter?
Why i cant have response.data?
...................................
rhtrhehrh regjnoeriwjgnowiermnfgorewmfelrg
Future addFine(String apiToken, String uin, int type) async {
try {
Response response = await _dio.post(apiEndpoint + "fines",
options: Options(headers: {"Authorization": apiToken}),
data: {"uin": uin, "type": type});
print(response.data);
print(response.statusMessage);
print(response.statusCode);
} catch (error, stacktrace) {
print(error);
print(stacktrace);
return null;
}
}
my stack trace
I/flutter ( 5580): DioError [DioErrorType.RESPONSE]: Http status error [422]
I/flutter ( 5580): #0 DioMixin._dispatchRequest (package:dio/src/dio.dart:966:7)
I/flutter ( 5580): <asynchronous suspension>
I/flutter ( 5580): #1 DioMixin._request._interceptorWrapper.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:dio/src/dio.dart:849:37)
I/flutter ( 5580): #2 DioMixin.checkIfNeedEnqueue (package:dio/src/dio.dart:1121:22)
I/flutter ( 5580): #3 DioMixin._request._interceptorWrapper.<anonymous closure>.<anonymous closure> (package:dio/src/dio.dart:846:22)
I/flutter ( 5580): #4 new Future.<anonymous closure> (dart:async/future.dart:175:37)
I/flutter ( 5580): #5 _rootRun (dart:async/zone.dart:1182:47)
I/flutter ( 5580): #6 _CustomZone.run (dart:async/zone.dart:1093:19)
I/flutter ( 5580): #7 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
I/flutter ( 5580): #8 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
I/flutter ( 5580): #9 _rootRun (dart:async/zone.dart:1190:13)
I/flutter ( 5580): #10 _CustomZone.run (dart:async/zone.dart:1093:19)
I/flutter ( 5580): #11 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1021:23)
I/flutter ( 5580): #12
Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15
If you consider codes that indicate an error valid information and want to access the information anyway, you can decide yourself, what you consider an error:
Response response = await _dio.post(apiEndpoint + "fines",
options: Options(
headers: {"Authorization": apiToken},
validateStatus: (status) => true),
data: {"uin": uin, "type": type});
In the options, you can pass a validator that decides what status codes are valid. In this case I just made it use any code. any code at all. You may want to restrict that further to your usecase, maybe even per call. For example, you could restrict it to "OK" and "Unprocessable Entity", where for example a 401 would still throw an exception:
validateStatus: (status) => { return status == 200 || status == 422; }
Related
I'm trying to upload an image using Multipart from Flutter Retrofit using this code
#POST("apiUrl/upload/files")
#MultiPart()
Future<TSSuccessResponse<UploadFileRemoteResponse>> uploadFile(
#Part() File file);
However it keeps getting error 415 that says application/form-octet is not supported MediaType.
E/flutter ( 8367): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioError [bad response]: The request returned an invalid status code of 415.
E/flutter ( 8367): #0 DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:530:7)
E/flutter ( 8367): #1 _RootZone.runBinary (dart:async/zone.dart:1665:54)
E/flutter ( 8367): #2 _FutureListener.handleError (dart:async/future_impl.dart:162:22)
E/flutter ( 8367): #3 Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
E/flutter ( 8367): #4 Future._propagateToListeners (dart:async/future_impl.dart:800:13)
E/flutter ( 8367): #5 Future._completeError (dart:async/future_impl.dart:575:5)
E/flutter ( 8367): #6 _SyncCompleter._completeError (dart:async/future_impl.dart:51:12)
E/flutter ( 8367): #7 _Completer.completeError (dart:async/future_impl.dart:23:5)
E/flutter ( 8367): #8 Future.any.onError (dart:async/future.dart:617:45)
E/flutter ( 8367): #9 _RootZone.runBinary (dart:async/zone.dart:1665:54)
E/flutter ( 8367): #10 _FutureListener.handleError (dart:async/future_impl.dart:162:22)
E/flutter ( 8367): #11 Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
E/flutter ( 8367): #12 Future._propagateToListeners (dart:async/future_impl.dart:800:13)
E/flutter ( 8367): #13 Future._completeError (dart:async/future_impl.dart:575:5)
E/flutter ( 8367): #14 Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:666:7)
E/flutter ( 8367): #15 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 8367): #16 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
I/flutter ( 8367): ╔ DioErrorType.badResponse
I/flutter ( 8367): ║ {
I/flutter ( 8367): ║ statusCode: 415,
I/flutter ( 8367): ║ "File type application/octet-stream is not matching: image, pdf, powerpoint, prese
I/flutter ( 8367): ║ ntation, video, video/quicktime"
I/flutter ( 8367): ║ error: "Unsupported Media Type"
I/flutter ( 8367): ║ }
I/flutter ( 8367): ╚══════════════════════════════════════════════════════════════════════════════════════════╝
Then I tried to change the request to include content-type in the #Part() tag as someone mentioned, so that it satisfies the generated file from Retrofit.
#POST("apiUrl/upload/files")
#MultiPart()
Future<TSSuccessResponse<UploadFileRemoteResponse>> uploadFile(
#Part(contentType: "image/png") File file);
But it throw another error, that is
E/flutter ( 8367): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioError [bad response]: The request returned an invalid status code of 415.
E/flutter ( 8367): #0 DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:530:7)
E/flutter ( 8367): #1 _RootZone.runBinary (dart:async/zone.dart:1665:54)
E/flutter ( 8367): #2 _FutureListener.handleError (dart:async/future_impl.dart:162:22)
E/flutter ( 8367): #3 Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
E/flutter ( 8367): #4 Future._propagateToListeners (dart:async/future_impl.dart:800:13)
E/flutter ( 8367): #5 Future._completeError (dart:async/future_impl.dart:575:5)
E/flutter ( 8367): #6 _SyncCompleter._completeError (dart:async/future_impl.dart:51:12)
E/flutter ( 8367): #7 _Completer.completeError (dart:async/future_impl.dart:23:5)
E/flutter ( 8367): #8 Future.any.onError (dart:async/future.dart:617:45)
E/flutter ( 8367): #9 _RootZone.runBinary (dart:async/zone.dart:1665:54)
E/flutter ( 8367): #10 _FutureListener.handleError (dart:async/future_impl.dart:162:22)
E/flutter ( 8367): #11 Future._propagateToListeners.handleError (dart:async/future_impl.dart:779:47)
E/flutter ( 8367): #12 Future._propagateToListeners (dart:async/future_impl.dart:800:13)
E/flutter ( 8367): #13 Future._completeError (dart:async/future_impl.dart:575:5)
E/flutter ( 8367): #14 Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:666:7)
E/flutter ( 8367): #15 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 8367): #16 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
I/flutter ( 8367): ╔ DioErrorType.badResponse
I/flutter ( 8367): ║ {
I/flutter ( 8367): ║ statusCode: 415,
I/flutter ( 8367): ║ message: "File type is not matching",
I/flutter ( 8367): ║ error: "Unsupported Media Type"
I/flutter ( 8367): ║ }
I/flutter ( 8367):
I also tried chaging the contentType to "image/*" but it throws error on the MediaType.parser (from the generated file) saying that it's an invalid type.
Is there anything I'm missing in this scenario? Have anyone solved this problem before? I tried solutions mentioned by [1],[2] and many others but still stuck in this problem. Thx in advance.
One thing to note: This request works normally in Postman with the same file.
I expext response.data to be when i got an error 422, like
{
"message": "You can NOT add a penalty!"
}
but i have an error The getter 'data' was called on null.
Future transferCoinsToUser(
String apiToken, String recipientBill, int coin) async {
Response response;
try {
response = await _dio.post(apiEndpoint + "bills/transfer",
options: Options(headers: {"Authorization": apiToken}),
data: {"recipient_bill": recipientBill, "coin": coin});
if(response.statusCode == 200){
print('status cod ' + response.statusCode.toString());
print('response bady ' + response.data.toString());//{message: completed successfully.}
}
} on DioError catch (error) {
print(error);
print(response.data);// The getter 'data' was called on null.
return null;
}
}
my stack trace
NoSuchMethodError: The getter 'data' was called on null.
I/flutter ( 7462): Receiver: null
I/flutter ( 7462): Tried calling: data
I/flutter ( 7462): NoSuchMethodError: The getter 'data' was called on null.
I/flutter ( 7462): Receiver: null
I/flutter ( 7462): Tried calling: data
I/flutter ( 7462): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter ( 7462): #1 ApiProvider.transCoinToUser (package:no_fine/data/api_provider.dart:104:22)
I/flutter ( 7462): <asynchronous suspension>
I/flutter ( 7462): #2 TransferRepositoryImpl.transCoinToUser (package:no_fine/data/repository/transfer_repo.dart:37:20)
I/flutter ( 7462): <asynchronous suspension>
I/flutter ( 7462): #3 TransferBloc._mapTransferCoinsToUserToState (package:no_fine/bloc/auth/translations_bloc/translations_bloc.dart:42:33)
I/flutter ( 7462): <asynchronous suspension>
I/flutter ( 7462): #4 TransferBloc.mapEventToState (package:no_fine/bloc/auth/translations_bloc/translations_bloc.dart:26:14)
I/flutter ( 7462): <asynchronous suspension>
I/flutter ( 7462): #5 Bloc._bindEventsToStates.<anonymous closure> (package:bloc/src/bloc.dart:232:20)
I/flutter ( 7462): #6 Stream.asyncExpand.<anonymous closure>.<anonymous closure> (dart:async/stream.dart:644:30)
I/flutter ( 7462): #7 _rootRunUnary (dart:async/zone.dart:1198:47)
I/flutter ( 7462): #8 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
I/flutter ( 7462): #9 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
I/flutter ( 7462): #10 _BufferingStreamSubscription._sendData (dart:a
response might be null. You are calling .data on null hence the error. Try
print(response?.data)
or check
if(response != null) print(response.data);
You can't access the Response object, when you have an error. Instead, Please use below code:
on DioError catch (error) {
print(error);
print(error.response.data);// Here you will find the error response in error object
return null;
}
You can check your request host. In Android device you can not use the request host like "localhost" or "127.0.0.1" directly because this is the Android device's host and this is not your API host.You should use your API host's IP which like "http://192.168.50.123/request?foo=bar".
I'm getting data from my api as a following JSON object to create chart with the data. I want to covert this DIO response to a Map<String, int> object in my flutter app.
My API response:
{
"November 20": 1,
"October 20": 3,
"September 20": 1
}
My try of creating a map object:
Future<bool> fetchChartData() async {
var response = await CasesApiService().getChartData();
Map<String, dynamic> data = jsonDecode(response.data);
}
But it shows the following error:
E/flutter ( 4733): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
E/flutter ( 4733): #0 CasesProvider.fetchChartData
package:bdopsApp/providers/casesProvider.dart:86
E/flutter ( 4733): <asynchronous suspension>
E/flutter ( 4733): #1 _CasesChartViewState.build.<anonymous closure>
package:bdopsApp/…/casesApp/casesChart.dart:31
E/flutter ( 4733): #2 _InkResponseState._handleTap
package:flutter/…/material/ink_well.dart:985
E/flutter ( 4733): #3 _InkResponseState.build.<anonymous closure>
package:flutter/…/material/ink_well.dart:1101
E/flutter ( 4733): #4 GestureRecognizer.invokeCallback
package:flutter/…/gestures/recognizer.dart:183
E/flutter ( 4733): #5 TapGestureRecognizer.handleTapUp
package:flutter/…/gestures/tap.dart:598
E/flutter ( 4733): #6 BaseTapGestureRecognizer._checkUp
package:flutter/…/gestures/tap.dart:287
E/flutter ( 4733): #7 BaseTapGestureRecognizer.handlePrimaryPointer
package:flutter/…/gestures/tap.dart:222
E/flutter ( 4733): #8 PrimaryPointerGestureRecognizer.handleEvent
package:flutter/…/gestures/recognizer.dart:476
E/flutter ( 4733): #9 PointerRouter._dispatch
package:flutter/…/gestures/pointer_router.dart:77
E/flutter ( 4733): #10 PointerRouter._dispatchEventToRoutes.<anonymous closure>
package:flutter/…/gestures/pointer_router.dart:122
E/flutter ( 4733): #11 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
E/flutter ( 4733): #12 PointerRouter._dispatchEventToRoutes
package:flutter/…/gestures/pointer_router.dart:120
E/flutter ( 4733): #13 PointerRouter.route
package:flutter/…/gestures/pointer_router.dart:106
E/flutter ( 4733): #14 GestureBinding.handleEvent
package:flutter/…/gestures/binding.dart:368
E/flutter ( 4733): #15 GestureBinding.dispatchEvent
package:flutter/…/gestures/binding.dart:348
E/flutter ( 4733): #16 RendererBinding.dispatchEvent
package:flutter/…/rendering/binding.dart:268
E/flutter ( 4733): #17 GestureBinding._handlePointerEventImmediately
package:flutter/…/gestures/binding.dart:303
E/flutter ( 4733): #18 GestureBinding.handlePointerEvent
package:flutter/…/gestures/binding.dart:267
E/flutter ( 4733): #19 GestureBinding._flushPointerEventQueue
package:flutter/…/gestures/binding.dart:225
E/flutter ( 4733): #20 GestureBinding._handlePointerDataPacket
package:flutter/…/gestures/binding.dart:208
E/flutter ( 4733): #21 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 4733): #22 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4733): #23 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 4733): #24 _invoke1 (dart:ui/hooks.dart:265:10)
E/flutter ( 4733): #25 _dispatchPointerDataPacket (dart:ui/hooks.dart:174:5)
N.B: I'm doing my final year project. Therefore, the process I'm following might not be what is used in real world project.
If you run the following example in the dartPad you will get the result that you are looking for:
import 'dart:convert';
void main() {
var jsonString= "{\"November 20\": \"1\",\"October 20\": \"2\",\"September 20\": \"3\"}";
Map<String, dynamic> data = jsonDecode(jsonString);
print(data);
}
I think you need to check the data that you are getting it from the response.data
I have a sqflite database with a table set up with all columns aside form the unique key set to BLOB data type. The intent is to store as binary data. I'm very new to dart and flutter, so I'm keeping things as simple as possible. I have int, double, String, List<String>, Map<String:String>, and DateTime data going into these columns. I am using the .insert() function, not the .rawInsert() function.
In my TEST application there is no problem whatsoever with either string or int going into the table as BLOB data type. I'm using exactly the same code to insert, just different objects with different columns. In the application I'm building for production, which has much larger, longer strings (like images in base 64), and much larger integers, I'm getting the error.
The strange thing is, I have type checking code that is converting all of the integer data I'm getting from my server in to actual integer data...there's no possible way that the integers could be anything but integers. Every value goes through a function that can only throw, or return an integer.
How then would the database be getting a string that it is trying to convert into an integer?
I'm not asking for a solution, so much as additional troubleshooting steps I should take that I might be missing due to brain fatigue or inexperience. I've hit a roadblock of sorts.
Here is the stack trace for the exception being raised:
I/flutter ( 6502): #0 wrapDatabaseException (package:sqflite/src/exception_impl.dart:11:7)
I/flutter ( 6502): <asynchronous suspension>
I/flutter ( 6502): #1 SqfliteDatabaseFactoryImpl.wrapDatabaseException (package:sqflite/src/factory_impl.dart:29:7)
I/flutter ( 6502): #2 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin.safeInvokeMethod (package:sqflite/src/database_mixin.dart:183:15)
I/flutter ( 6502): #3 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin.txnRawInsert.<anonymous closure> (package:sqflite/src/database_mixin.dart:340:14)
I/flutter ( 6502): #4 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin.txnSynchronized.<anonymous closure> (package:sqflite/src/database_mixin.dart:290:22)
I/flutter ( 6502): #5 BasicLock.synchronized (package:synchronized/src/basic_lock.dart:31:26)
I/flutter ( 6502): <asynchronous suspension>
I/flutter ( 6502): #6 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin.txnSynchronized (package:sqflite/src/database_mixin.dart:286:43)
I/flutter ( 6502): <asynchronous suspension>
I/flutter ( 6502): #7 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin.txnWriteSynchronized (package:sqflite/src/database_mixin.dart:307:7)
I/flutter ( 6502): #8 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin.txnRawInsert (package:sqflite/src/database_mixin.dart:339:12)
I/flutter ( 6502): #9 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin&SqfliteDatabaseExecutorMixin.rawInsert (package:sqflite/src/database_mixin.dart:44:15)
I/flutter ( 6502): #10 _SqfliteDatabaseBase&Object&SqfliteDatabaseMixin&SqfliteDatabaseExecutorMixin.insert (package:sqflite/src/database_mixin.dart:54:12)
I/flutter ( 6502): #11 AppPersistenceManager.insertIntoDatabase (package:gogreen_utility_belt/app/AppPersistenceManager.dart:120:37)
I/flutter ( 6502): <asynchronous suspension>
I/flutter ( 6502): #12 AppNetwork._triggerProductFetchAndCacheWith.<anonymous closure> (package:gogreen_utility_belt/app/AppNetwork.dart:167:38)
I/flutter ( 6502): #13 _rootRunUnary (dart:async/zone.dart:1132:38)
I/flutter ( 6502): #14 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
I/flutter ( 6502): #15 _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
I/flutter ( 6502): #16 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
I/flutter ( 6502): #17 Future._propagateToListeners (dart:async/future_impl.dart:668:32)
I/flutter ( 6502): #18 Future._chainCoreFuture (dart:async/future_impl.dart:454:7)
I/flutter ( 6502): #19 Future._complete (dart:async/future_impl.dart:466:9)
I/flutter ( 6502): #20 _SyncCompleter.complete (dart:async/future_impl.dart:51:12)
I/flutter ( 6502): #21 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:28:18)
I/flutter ( 6502): #22 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:294:13)
I/flutter ( 6502): #23 compute (package:flutter/src/foundation/_isolates_io.dart)
I/flutter ( 6502): <asynchronous suspension>
I/flutter ( 6502): #24 AppNetwork._triggerProductFetchAndCacheWith (package:gogreen_utility_belt/app/AppNetwork.dart:153:55)
I/flutter ( 6502): <asynchronous suspension>
I/flutter ( 6502): #25 AppNetwork.fetchAndCacheAllProducts (package:gogreen_utility_belt/app/AppNetwork.dart:195:9)
I/flutter ( 6502): #26 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:77:64)
I/flutter ( 6502): #27 _rootRunUnary (dart:async/zone.dart:1132:38)
I/flutter ( 6502): #28 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
I/flutter ( 6502): #29 _FutureListener.handleValue (dart:async/future_impl.dart:126:18)
I/flutter ( 6502): #30 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:639:45)
I/flutter ( 6502): #31 Future._propagateToListeners (dart:async/future_impl.dart:668:32)
I/flutter ( 6502): #32 Future._complete (dart:async/future_impl.dart:473:7)
I/flutter ( 6502): #33 _cancelAndValue (dart:async/stream_pipe.dart:63:12)
I/flutter ( 6502): #34 Stream.first.<anonymous closure> (dart:async/stream.dart:1190:11)
I/flutter ( 6502): #35 _rootRunUnary (dart:async/zone.dart:1132:38)
I/flutter ( 6502): #36 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
I/flutter ( 6502): #37 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
I/flutter ( 6502): #38 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
I/flutter ( 6502): #39 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:263:7)
I/flutter ( 6502): #40 _SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:375:20)
I/flutter ( 6502): #41 _BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:250:5)
I/flutter ( 6502): #42 _AsBroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:474:11)
I/flutter ( 6502): #43 _rootRunUnary (dart:async/zone.dart:1136:13)
I/flutter ( 6502): #44 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
I/flutter ( 6502): #45 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
I/flutter ( 6502): #46 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
I/flutter ( 6502): #47 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:263:7)
I/flutter ( 6502): #48 _SyncStreamController._sendData (dart:async/stream_controller.dart:764:19)
I/flutter ( 6502): #49 _StreamController._add (dart:async/stream_controller.dart:640:7)
I/flutter ( 6502): #50 _StreamController.add (dart:async/stream_controller.dart:586:5)
I/flutter ( 6502): #51 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
Here is what some of the functions involved look like:
initDatabase() async {
print(new Trace.from(StackTrace.current).terse.frames[0]);
Directory documentsDirectory;
print(
'documentsDirectory set to null, about to assign with an await method');
documentsDirectory = await getApplicationDocumentsDirectory();
print('passed doc dir');
String path = join(documentsDirectory.path, "TestDB.db");
print('passed join');
print(Trace.from(StackTrace.current).terse);
return await openDatabase(path, version: 1, onOpen: (db) {
print('in onOpen');
}, onCreate: (Database database, int version) async {
print('in onCreate async');
for (DatabaseTable databaseTable in DatabaseTable.values) {
print(
'reached inside of "for (DatabaseTable databaseTable in DatabaseTable.values)"');
String executionString =
"CREATE TABLE IF NOT EXISTS ${RawValue.databaseTable(databaseTable)}("
"$uniqueRowKey INTEGER PRIMARY KEY,";
JSONSerializable objectExample;
switch (databaseTable) {
case DatabaseTable.Product:
objectExample = Product.example;
}
print('getting parameters');
List<String> parameters = [];
for (String key
in getDatabaseKeyedMapFrom(serialObject: objectExample).keys) {
parameters.add(key);
}
print('getting unique keys');
List<String> uniqueKeys = [];
var rawUniqueProperties = objectExample.uniqueProperties();
for (String property in rawUniqueProperties) {
uniqueKeys.add(getDatabaseKeyFrom(jsonKey: property));
}
print('iterating through parameters');
for (String parameter in parameters) {
if (parameter != parameters.first) {
executionString += ',';
}
if (uniqueKeys.contains(parameter)) {
uniqueKeys.remove(parameter);
executionString += "$parameter BLOB UNIQUE";
continue;
}
executionString += "$parameter BLOB";
}
executionString += ')';
print('executing string on database');
await database.execute(executionString);
}
});
}
/// Attempts to insert the object into its corresponding table.
Future<DatabaseLocation> insertIntoDatabase(JSONSerializable object) async {
print(new Trace.from(StackTrace.current).terse.frames[0]);
final localDatabase = await database;
String tableName = RawValue.databaseTable(getTableFor(object));
try {
Map<String, dynamic> dbKeyedMap =
getDatabaseKeyedMapFrom(serialObject: object);
int row = await localDatabase.insert(tableName, dbKeyedMap,
conflictAlgorithm: ConflictAlgorithm.replace);
return DatabaseLocation(table: tableName, row: row);
} catch (error, trace) {
printWrapped(error.toString());
printWrapped(trace.toString());
rethrow;
}
}
///converts the String keys of any map representing an object into snake_case
Map<String, dynamic> getDatabaseKeyedMapFrom(
{JSONSerializable serialObject}) {
print(new Trace.from(StackTrace.current).terse.frames[0]);
Map<String, dynamic> jsonKeyedMap = serialObject.toJson();
List<String> jsonPropertyNames = serialObject.propertyNames();
Map<String, dynamic> databaseKeyedMap = {};
for (String jsonPropertyName in jsonPropertyNames) {
ReCase reCase = ReCase(jsonPropertyName);
String databasePropertyName = reCase.snakeCase;
databaseKeyedMap[databasePropertyName] = jsonKeyedMap[jsonPropertyName];
}
return databaseKeyedMap;
}
///converts the String keys of any map representing an object into camelCase
Map<String, dynamic> getJSONKeyedMapFrom(
{Map<String, dynamic> databaseKeyedMap}) {
////print(new Trace.from(StackTrace.current).terse.frames[0]);
List<String> databasePropertyNames = databaseKeyedMap.keys;
Map<String, dynamic> jsonKeyedMap = {};
for (String databasePropertyName in databasePropertyNames) {
ReCase reCase = ReCase(databasePropertyName);
String jsonPropertyName = reCase.camelCase;
jsonKeyedMap[jsonPropertyName] = databaseKeyedMap[databasePropertyName];
}
return jsonKeyedMap;
}
Here is the Product model used in the DB.
Update:
I added all of the data types represented in the production code model to my test app model, and was able to duplicate the error. See the test application link at the top. I removed the new data types one by one until the error went away, and was able to find out that it's the List data type that generates this error. I double checked the Map, that one doesn't cause any trouble.
So, refined question: how do I store a list of strings using sqflite? I don't want to just store it as the original JSON string...that would suck...
You have to flatten your model. See the supported types help section.
Basically int, double, String and Uint8List(blob) are the only types supported.
Unfortunately you have to convert your inner List<String> and Map<String, Object?>, json being one solution.
After some research, I think my understanding of BLOB was incorrect - I assumed it meant it would store the objects as binary data, and I also assumed that in SQLite, if a table was BLOB it would force all data to be converted to binary when inserted, or at least throw if it isn't. Turns out that SQLite is not strict, and BLOB just means 'any data type you want'. I also discovered that SQLite will try to automatically convert the data type of objects. So complex data types such as List need to be converted into something that SQLite can cast into its own types before being stored. There is no Array or Object type in SQLite, so a List just won't work.
I solved this problem by converting the complex data type to a JSON string before inserting into the DB, and converting it back into a List when fetching/instantiating the object from the database. That way I don't have to deal with converting the object property out of JSON every time I need to use/change that property or something in it. Not exactly elegant, but it works and I understand it.
I'm trying to use a simple GET requests in REST to flutter, but have an error
Code:
Future<Map> timeStamp() async {
const request =
"https://armariosinteligentes.com/api/v3/timestamp";
http.Response response = await http.get(request);
print(json.decode(response.body));
}
json: {"timestamp":1566397501}
Error:
E/flutter ( 7041): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: HandshakeException: Handshake error in client (OS Error:
E/flutter ( 7041): BLOCK_TYPE_IS_NOT_01(padding.c:108)
E/flutter ( 7041): PADDING_CHECK_FAILED(rsa_impl.c:641)
E/flutter ( 7041): public key routines(a_verify.c:105)
E/flutter ( 7041): CERTIFICATE_VERIFY_FAILED: certificate signature failure(handshake.cc:352)) E/flutter ( 7041):
#0 IOClient.send (package:http/src/io_client.dart:33:23) E/flutter ( 7041): <asynchronous suspension> E/flutter ( 7041):
#1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:169:38) E/flutter ( 7041): <asynchronous suspension> E/flutter ( 7041):
#2 BaseClient.get (package:http/src/base_client.dart:32:7) E/flutter ( 7041):
#3 get.<anonymous closure> (package:http/http.dart:46:36) E/flutter ( 7041):
#4 _withClient (package:http/http.dart:166:20) E/flutter ( 7041): <asynchronous suspension> E/flutter ( 7041):
#5 get (package:http/http.dart:46:5) E/flutter ( 7041):
#6 timeStamp (package:armarios_inteligentes/screens/locker_screen.dart:196:34) E/flutter ( 7041): <asynchronous suspension> E/flutter ( 7041):
#7 LockerScreenState.build.<anonymous closure> (package:armarios_inteligentes/screens/locker_screen.dart:114:15) E/flutter ( 7041):
#8 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:635:14) E/flutter ( 7041):
#9 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:711:32) E/flutter ( 7041):
#10 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) E/flutter ( 7041): #11 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:365:11) E/flutter ( 7041):
#12 TapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:312:7) E/flutter ( 7041):
#13 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27) E/flutter ( 7041):
#14 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:222:20) E/flutter ( 7041):
#15 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) E/flutter ( 7041):
#16 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) E/flutter ( 7041):
#17 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) E/flutter ( 7041):
#18 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) E/flutter ( 7041):
#19 _rootRunUnary (dart:async/zone.dart:1136:13) E/flutter ( 7041):
#20 _CustomZone.runUnary (dart:async/zone.dart:1029:19) E/flutter ( 7041):
#21 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7) E/flutter ( 7041):
#22 _invoke1 (dart:ui/hooks.dart:250:10) E/flutter ( 7041):
#23 _dispatchPointerDataPacket (dart:ui/hooks.dart:159:5) E/flutter ( 7041):
timeStamp() async {
final response =
await http.get('http://armariosinteligentes.com/api/v3/timestamp');
if (response.statusCode == 200) {
// If server returns an OK response, parse the JSON.
var jsonResponse = json.decode(response.body);
tempoStamp tempo = new tempoStamp.fromJson(jsonResponse);
var time = ('${tempo.timestamp}');
return time;
} else {
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
}
Result: 1566411603
Try to remove the https and put http instead. And verify your connection, you need to know if you can call websites like this in your local...