To take a String from a Flux<String> throws type mismatch: Cannot convert from Disposable to String - project-reactor

Related to this question to take a string from a Mono I think I have finally got how to take a String out of a Flux<String> like this:
Flux<String> rates = controller.getRate(json);
String myRate = rates.next().subscribe(System.out::print);
However, this is causing a type mismatch cannot convert from Disposable to String
What am I getting wrong?
To clarify, it's for testing - I need an internal String value. So if I have a Flux<String> of strings: one, two, three then I want to set another String to value one
String s = ...
If I try
String s = rates.doOnNext(System.out::print);
Then I get a type mismatch: cannot convert from Flux<String> to String
If I try
String s = next().flatMap(System.out::print);
Then I get a type mismatch: cannot convert from Mono<Object> to String

What am I getting wrong?
It's not clear what you're trying to achieve, but potentially a few things here:
A Flux<String> returns a stream of 0..n strings, do you definitely only ever want the first one it returns (which is what next() does?)
You've realistically got two options in getting a value from a publisher - you can do it asynchronously by using the reactive chain, or you can block the thread until it completes, then get it directly. (Note that if you block though, you're losing all the advantages the reactive framework gives you, so it's rare that this is actually what you want to do.) In this example it looks like you're subscribing, but also trying to block, which doesn't make any sense - you need to pick one or the other.
If you don't want to block and you're using a reactive framework like webflux, then subscribing is generally the framework's job anyway - you would just pass your reactive calls up the chain until you eventually returned a Mono or a Flux on (for example) your controller method. (Subscribing is only really valid if you're not using a framework, and managing the entirety of the reactive chain + event loop yourself.)
If you don't want to block but want to make sure the value is printed out as soon as it's emitted (known as a side-effect) then you can use the doOnNext(System.out::print) as part of the reactive chain to achieve this.

Related

What does it mean <> in method?

I have this method
#override
Response<BodyType> convertResponse<BodyType, SingleItemType>(
Response response) {
final Response dynamicResponse = super.convertResponse(response);
final BodyType customBody =
_convertToCustomObject<SingleItemType>(dynamicResponse.body);
return dynamicResponse.replace<BodyType>(body: customBody);
}
What does it mean <BodyType> and <BodyType, SingleItemType> in this method?
These are called generics in Dart (in fact, they are called the same in other similar programming languages).
The main idea behind generics is that you could reuse the same code without relying on a specific data/return type. Imagine List in Dart. You could have a list of integers (List<int>), a list of strings (List<String>), a list of your custom objects (List<CustomType>) - the type is not hardcoded and it could be adjusted based on your needs.
Also, you could say that it would be easier just to use dynamic or Object types that would cover most of these cases. However, generics brings you type safety, and the method type itself becomes a parameter.
Here is the official documentation about generics.

The argument type 'ListOf5' can't be assigned to the parameter type 'ListOf5'

I need to implement an abstract class function, which own a an specific data type. But I need inside my logic layer to make the attribute which is going to be passed as a dynamic data type. But when i Pass it to the function, i am sure that its data type will be as needed. So, i type (product.value.pickedImages) as ListOf5) . But it does an Exception.
The Abstract Class Code Is:
Future<Either<FireStoreServerFailures, List<String>>> uploadProductImages(
{required ListOf5<File> images});
The Implementation Code Is:
Future<Option<List<String>>> _uploadImagesToFirestorage() async {
return await productRepo
.uploadProductImages(
images: (product.value.pickedImages) as ListOf5<File>) // Exception
}
The Exception Is:
The argument type 'ListOf5 < dynamic>' can't be assigned to the
parameter type 'ListOf5 < File>'.
You are trying to cast the List from List<dynamic> to List<String>.
Instead, you should cast each item, using something like this:
void main() {
List<dynamic> a = ['qwerty'];
print(List<String>.from(a));
}
Not sure about the implementation of this ListOf5 though...
The cast (product.value.pickedImages) as ListOf5<File> fails.
It fails because product.value.pickedImages is-not-a ListOf5<File>, but instead of ListOf5<dynamic> (which may or may not currently contain only File objects, but that's not what's being checked).
Unlike a language like Java, Dart retains the type arguments at run-time(it doesn't do "erasure"), so a ListOf5<dynamic> which contains only File objects is really different from a ListOf5<File> at run-time.
You need to convert the ListOf5<dynamic> to a ListOf5<File>.
How to do that depends on the type ListOf5, which I don't know.
For a normal List, the two most common options are:
(product.value.pickedImages).cast<File>(). Wraps the existing list and checks on each read that you really do read a File. It throws if you ever read a non-File from the original list. Perfectly fine if you'll only read the list once.
List<File>.of(product.value.pickedImages). Creates a new List<File> containing the values of product.value.pickedImages, and throws if any of the values are not File objects. Requires more memory (because it copies the list), but fails early in case there is a problem, and for small lists, the overhead is unlikely to be significant. If you read the resulting list many times, it'll probably be more efficient overall.
If the ListOf5 class provides similar options, you can use those. If not, you might have to build a new ListOf5 manually, casting each element of the existing ListOf5<dynamic> yourself.
(If the ListOf5 class is your own, you can choose to add such functionality to the class).

Better way to assign a value with nullable field in dart

Is there a better way to do this?
Assignment(
dueAt: json['due_at'] == null ?
null :
DateTime.parse(json['due_at']).toLocal()
)
The attribute "dueAt" in Assignment class can be null and i need to parse the string of json['due_at'] to a DateTime, but json['due_at'] can be null too.
Is not really a problem right now but seems noisy and repetitive.
First and foremost, it looks like you're writing JSON serialization code by hand. Your life will be much easier and less bug-prone if you let a library do this instead. json_serializable is very simple and powerful and 100% worth looking into.
However, this pattern is still common outside of json code.
You could also consider writing an extension method for Object? that behaves like the Kotlin standard library's let function (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html)
You can then use Dart's ?. syntax to handle the rest of the logic:
// extension on T rather than Object? to maintain type information
extension Example<T> on T {
R let<R>(R Function(T) function) => function(this);
}
This just applies a given function to this, which isn't incredibly useful on it's own, but allows the use of ?.:
final DateTime? dueAt = json['due_at']?.let(DateTime.parse);
If json['due_at'] evaluates to null, the ?. operator short-circuits, and dueAt is set to null. Otherwise, it evaluates to DateTime.parse(json['due_at']).
Or, you could just use package:kt_dart which ports much of the Kotlin standard library to Dart
In this particular case you may want to use tryParse instead of parse. If dueAt is of type DateTime? you can simply call:
Assignment( dueAt: DateTime.tryParse(json['due_at'])?.toLocal() );
Be aware though that tryParse will return null for any invalid date string (be it null or an improperly formatted string). This may or may not be desired behavior depending on your intended use.

How to return a struct from an imported DLL-function in MQL4?

Is there a way to return a struct from an imported function in MQL4, without having to pass it as a parameter and making a memcpy?
Be cautious with any kind of DLL-interfacing, MQL4 Documentation states:
Passing ParametersAll parameters of simple types are passed by values unless it is explicitly indicated that they are passed by reference. When a string is passed, the address of the buffer of the copied string is passed; if a string is passed by reference, the address of the buffer of this string without copying it is passed to the function imported from DLL.Structures that contain dynamic arrays[], strings, classes, other complex structures, as well as static or dynamic arrays[] of the enumerated objects, can't be passed as a parameter to an imported function.When passing an array to DLL, the address of the beginning of the data buffer is always passed (irrespective of the AS_SERIES flag). A function inside a DLL knows nothing about the AS_SERIES flag, the passed array is a static array of an undefined length; an additional parameter should be used for specifying the array size.
More glitches apply... Then how to make it work?
Maybe a straight, heterogeneous multi-party distributed processing, which communicates rather results than function calls, independent of all nightmares of maintaining just DLL-imported functions API changes, is a way safer way to go. Using this approach for the last few years and since than have no problems with New-MQL4.56789 string-s that seized to remain string-s and silently started to become struct-s etc.
Worth to know about.
Anyway, welcome and enjoy the Wild Worlds of MQL4 -- may enjoy to click and read other posts on issues in MQL4/DLL integration and/or signalling/messaging in MQL4 domains. Feel free to ask more

How to define content transformers in Siesta?

I'm just integrating Siesta and I love it, it solves a lot of issues we have when using frameworks like RestKit.
What I can't get my head around is how to use the content transformers? I've looked at the docs and examples and I can't quite understand how it works, I'm also fairly new to Swift.
Looking at this example taken from another SO reply:
private let SwiftyJSONTransformer = ResponseContentTransformer(skipWhenEntityMatchesOutputType: false) {
JSON($0.content as AnyObject)
}
I can't quite understand what's going on here, there is no return value so I don't understand how content is being transformed. This might be my due to a lack of deep Swift knowledge.
I've understand how NSValueTransformer objects work in Obj-C but I can't work out how to map a response abit JSON or just a simple response body like a single string, number of boolean value to a object or type using Siesta.
We have some API responses that return just a single BOOL value in the response body while most of the other API responses are complex JSON object graphs.
How would I go about mapping these responses to more primitive types and or more complex objects.
Thanks.
Some of your confusion is basic Swift stuff. Where a closure uses $0 and contains only a single statement, the input types are inferred and the return is implicit. Thus the code in your question is equivalent to:
ResponseContentTransformer(skipWhenEntityMatchesOutputType: false) {
(content: AnyObject, entity: Entity) in
return JSON(content)
}
(Using $0.content instead of just $0 is a workaround for a maybe-bug-maybe-feature in Swift where $0 becomes a tuple of all arguments instead of just the first one. Don’t worry too much about it; $0.content is just a magic incantation you can use in your Siesta transformers.)
The other half of your confusion is Siesta itself. The general approach is as follows:
Configure a generic transformer that turns the raw NSData into a decoded but unstructured type such as String or Dictionary.
You’ll usually configure this based on content type.
Siesta includes parsing for strings, JSON, and images unless you turn it off with useDefaultTransformers: false.
Optionally configure a second transformer that turns the unstructured type into a model.
You’ll usually configure this based on API path.
Siesta doesn’t include any of this by default; it’s all per app.
For responses that are just a bare boolean, you’d probably do only #1 — depending on exactly what kind of response the server is sending, and depending on how you know it's just a boolean.
I recommend looking at the example project included with Siesta, which gives a good example of how all this plays out. You’ll see examples of both transformers that conditionally operate on the content based on its type (#1) and model-specific tranformers (#2) in that code.

Resources