OpenAPI Dart generator - dart

I'm using OpenAPI generator to generate Dart client to my spec.
One of my endpoints returns binary data which reflects in schema like this:
"responses" : {
"200" : {
"description" : "",
"content" : {
"application/octet-stream" : {
"schema" : {
"type" : "string",
"format" : "binary"
}
}
}
}
}
Client is generated without errors, with the response type Future. However when I invoke that method, I get error like this:
Unhandled exception:
FormatException: Unexpected character (at character 1)
#0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5)
#1 _ChunkedJsonParser.parseNumber (dart:convert-patch/convert_patch.dart:1271:9)
#2 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:936:22)
#3 _parseJson (dart:convert-patch/convert_patch.dart:40:10)
#4 JsonDecoder.convert (dart:convert/json.dart:506:36)
#5 JsonCodec.decode (dart:convert/json.dart:157:41)
#6 jsonDecode (dart:convert/json.dart:96:10)
#7 ApiClient.deserialize (package:openapi/api_client.dart:192:20)
#8 DefaultApi.testIntPost (package:openapi/api/default_api.dart:143:24)
<asynchronous suspension>
#9 main.<anonymous closure> (package:X/run.dart)
<asynchronous suspension>
What am I doing wrong?

I tried the dart-dio generator and it worked OK with binary return type. Still I will not mark this answer as the right one since the question regarding dart generator is not solved

Related

Decoding JSON in dart

I have this simple dart file which I'm running:
import 'dart:convert';
// ...
dynamic test() {
final strJson = '{"ACB":["{\"date\":\"2020-02-28\",\"open\":1.36,\"close\":1.34,\"high\":1.4,\"low\":1.32,\"volume\":26469238}","{\"date\":\"2020-03-12\",\"open\":47.99,\"close\":45.54,\"high\":50.09,\"low\":45.37,\"volume\":50661745}"]}';
final parsedJson = json.decode(strJson);
print('${parsedJson.runtimeType} : $parsedJson');
}
main() {
test();
}
But getting this weird exception:
Unhandled exception:
FormatException: Unexpected character (at character 12)
{"ACB":["{"date":"2020-02-28","open":1.36,"close":1.34,"high":1.4,"low":1.3...
^
#0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1394:5)
#1 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:924:48)
#2 _parseJson (dart:convert-patch/convert_patch.dart:31:10)
#3 JsonDecoder.convert (dart:convert/json.dart:495:36)
#4 JsonCodec.decode (dart:convert/json.dart:153:41)
#5 test (file:///home/val/src/labs/maingain/test.dart:60:27)
#6 main (file:///home/val/src/labs/maingain/test.dart:65:3)
#7 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:307:19)
#8 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
I'll just say, that running similar code from the Flutter seems to work fine. Only when running this from command line give me the above.
Also validated JSON.
Put an r in front of the string literal.
The '{"ACB":["{\"date\":....' is a plain single-quoted Dart string literal. That means that backslash is a string escape, so \" only adds " to the string value.
It's not a necessary escape because the string uses single quotes, but it's still treated like an escape.
That means that you pass the string content {"ACB":["{"date":... to the JSON decoder, which promptly gives up because the code is not valid JSON.
If you put an r in front of the string: r'{"ACB":["{\"date\":...' then the string literal becomes a raw string. That means that backslashes do not work as escapes, but are treated like literal characters. That makes the resulting string valid JSON.
Another alternative is to change every backslash to two: '{"ACB":["{\\"date\\":...'.

"Bad state: Future already completed" in Aqueduct

I'm attempting to, in the prepare method of the main channel, load up an AutoRefreshingAuthClient and subsequently a FirestoreAPI object, but I am getting the following stack trace:
Unhandled exception:
Bad state: Future already completed
#0 _Completer.completeError (dart:async/future_impl.dart:21:31)
#1 ApplicationIsolateSupervisor._handleIsolateException (package:aqueduct/src/application/isolate_supervisor.dart:129:24)
#2 ApplicationIsolateSupervisor.listener (package:aqueduct/src/application/isolate_supervisor.dart:102:7)
#3 _RootZone.runUnaryGuarded (dart:async/zone.dart:1314:10)
#4 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
#5 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:263:7)
#6 _SyncStreamController._sendData (dart:async/stream_controller.dart:764:19)
#7 _StreamController._add (dart:async/stream_controller.dart:640:7)#8 _StreamController.add (dart:async/stream_controller.dart:586:5)
#9 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
Though this stack trace does not point to anything in my code, I isolated the issue to an awaited clientViaServiceAccount call (code below) in the prepare method.
I'm unsure as to what I'm doing wrong as the documentation for this API (googleapis) is largely unhelpful in this context, and the example method shown in the documentation doesn't seem to work here.
How do I properly set up the AutoRefreshingAuthClient and FirestoreAPI objects without getting this exception?
This is an Aqueduct project that has no issues running if I simply run the example code shipped with the project at creation.
I've tried shifting the calls and initialization to different scopes, but aside from that I don't know what to try.
channel.dart
import 'dart:io';
import 'package:googleapis/firestore/v1.dart';
import 'package:googleapis_auth/auth.dart';
import 'package:googleapis_auth/auth_io.dart';
import 'package:mm_block/mm_block.dart';
import 'package:mm_block/controller/member.dart';
final _credentials = ServiceAccountCredentials.fromJson(
File('credentials').readAsString()
);
final _scopes = [
FirestoreApi.CloudPlatformScope
];
class MMBlockChannel extends ApplicationChannel {
FirestoreApi firestore;
#override
Future prepare() async {
// The issue is here.
await clientViaServiceAccount(_credentials, _scopes)
.then((client) => firestore = FirestoreApi(client));
}
...
}
This should all run correctly and I should end up with an AutoRefreshingAuthClient being passed to the FirestoreAPI call.

How to parse json data if it has escape characters in response with dart or flutter?

my json response is {"quoteText":"You\'re not obligated to win. You\'re obligated to keep trying to do the best you can every day.", "quoteAuthor":"Marian Edelman"} and I am trying to decode by Map<String, dynamic> quoteData = jsonDecode(response.body); but getting this exception
[ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter ( 5814): FormatException: Unrecognized string escape (at character 20)
E/flutter ( 5814): {"quoteText":"You\'re not obligated to win. You\'re obligated to keep tryin...
E/flutter ( 5814): ^
E/flutter ( 5814):
E/flutter ( 5814): #0 _ChunkedJsonParser.fail (dart:convert/runtime/libconvert_patch.dart:1358:5)
Tried by json.decode() and by doing flutter-remove-escape-sequence-in-dart but no luck. Any workaround?
That isn't valid json. Single quotes should not be escaped. Either you should get the source to fix it, or you can try to fix the string yourself by wholesale replacing any occurrence of \' with '.
String fixed = badString.replaceAll(r"\'", "'");
json.decode(fixed);

Navigate to other page

I use a Datepicker Cupertiono in my Flutter application:
https://github.com/wuzhendev/flutter-cupertino-date-picker
There is a method named "onConfirm()" where I'm trying to redirect user to other page, but with no luck.
I tried
return Navigator.pushReplacementNamed(ctx, '/otherPage');
but what actually happens when this return statment is hit, is cupertino widget closes and nothing happen. There is no error
When I try to use :
return Navigator.pushNamed<bool>(
ctx,
'/route/' + object.id.toString());
Some errors apear:
Performing hot restart...
Restarted application in 1 685ms.
I/flutter (20542): 112
E/flutter (20542): [ERROR:flutter/shell/common/shell.cc(188)] Dart Error: Unhandled exception:
E/flutter (20542): Looking up a deactivated widget's ancestor is unsafe.
E/flutter (20542): At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling
inheritFromWidgetOfExactType() in the widget's didChangeDependencies() method.
E/flutter (20542):
E/flutter (20542): #0 Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> (package:flutter/src/widgets/framework.dart:3232:9)
E/flutter (20542): #1 Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:3241:6)
E/flutter (20542): #2 Element.ancestorStateOfType (package:flutter/src/widgets/framework.dart:3289:12)
E/flutter (20542): #3 Scaffold.of (package:flutter/src/material/scaffold.dart:935:42)
You should use Navigator.push.
Import your page, example: import './otherPage.dart';
Than change your line
return Navigator.pushReplacementNamed(ctx, '/otherPage');
To
return Navigator.push(context, 'otherClassName');

How do you listen for custom events in Polymer Dart 1.0?

I've been trying to do something like the following inside a Polymer Dart 1.0 element
#PolymerRegister('some-element')
class SomeElement extends PolymerElement {
...
void fireEvent() {
fire('someevent');
}
...
}
I then listen for it in this manner
<some-element on-someevent="handleSomeEvent"></some-element>
with the method defined inside the Polymer Element that I'm using in defined thus
#reflectable
void handleSomeEvent([_, __]) {
...
}
The problem is I get an
Unhandled exception
which wasn't helpful, and it took me a while to figure out that the above was causing it. If I remove the
#reflectable
annotation from the event handler method, I get the following
method `registered` not defined
I was wondering if there is a special way to handle custom events in Polymer Dart 1.0?
I can handle it this way
on['someevent'].listen(handleSomeEvent);
which does work, it's just I don't see why I shouldn't be able to handle it both ways. I'm thinking I'll be submitting a bug report on this, but I thought I'd put it here and check to see if I've done this correctly, since what I did, apart from using
#reflectable
which is Polymer Dart 1.0 specific, is what they say you should do in Polymer JS whose documentation can be found here
UPDATE
I should clarify, this exception happened at load time, when the element was being registered. I'll put the full exception in later, when I have a bit more time.
The exception I'm getting is the following
Exception: Uncaught Error: Unhandled exception:
Reflecting on un-marked type 'JsObjectImpl'
#0 _InstanceMirrorImpl._InstanceMirrorImpl (package:reflectable/src/reflectable_transformer_based.dart:150:9)
#1 ReflectableImpl.reflect (package:reflectable/src/reflectable_transformer_based.dart:1216:16)
#2 _setupReflectableMethods.<anonymous closure>.<anonymous closure> (package:polymer/src/common/polymer_descriptor.dart:151:49)
#3 JsObject._callMethod (dart:js:678)
#4 JsObject.callMethod (dart:js:618)
#5 PolymerRegister.initialize (package:polymer/src/common/polymer_register.dart:19:13)
#6 loadInitializers.<anonymous closure>.<anonymous closure> (package:initialize/src/static_loader.dart:46:32)
#7 _runInitQueue (package:initialize/initialize.dart:35:24)
#8 _runInitQueue.<anonymous closure> (package:initialize/initialize.dart:38:26)
#9 _RootZone.runUnary (dart:async/zone.dart:1165)
#10 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:502)
#11 _Future._propagateToListeners (dart:async/future_impl.dart:585)
#12 _Future._completeWithValue (dart:async/future_impl.dart:376)
#13 _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:430)
#14 _microtaskLoop (dart:async/schedule_microtask.dart:43)
#15 _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
#16 _ScheduleImmediateHelper._handleMutation (dart:html:42565)
Stack Trace:
#0 JsObject._callMethod (dart:js:678)
#1 JsObject.callMethod (dart:js:618)
#2 PolymerRegister.initialize (package:polymer/src/common/polymer_register.dart:19:13)
#3 loadInitializers.<anonymous closure>.<anonymous closure> (package:initialize/src/static_loader.dart:46:32)
#4 _runInitQueue (package:initialize/initialize.dart:35:24)
#5 _runInitQueue.<anonymous closure> (package:initialize/initialize.dart:38:26)
#6 _RootZone.runUnary (dart:async/zone.dart:1165)
#7 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:502)
#8 _Future._propagateToListeners (dart:async/future_impl.dart:585)
#9 _Future._completeWithValue (dart:async/future_impl.dart:376)
#10 _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:430)
#11 _microtaskLoop (dart:async/schedule_microtask.dart:43)
#12 _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
#13 _ScheduleImmediateHelper._handleMutation (dart:html:42565)
Further Info
Next time I ask for help, I'll just use the exact code I'm using. The method I'm annotating with
#reflectable
is called registered.
#reflectable
void registered([_, __]) {
....
}
If I change the name of this method to something else like
#reflectable
void someOtherName([_, __]) {
...
}
The exception doesn't occur. Sorry about that, it didn't occur to me the name of the method might have something to do with it. Again sorry, but I still would like some explanation as to why the name of the annotated method matters in this case.
This is just fine.
#reflectable
void handleSomeEvent([_, __]) {
...
}
Can you provide the project in a GitHub repo that allows to reproduce the problem?
An additional method would be
#Listen('someevent')
void handleSomeEvent([_, __]) {
...
}
(You don't need to add anything to HTML for this method).

Resources