Class '_LinkedHashMap<String, ObjectPool>' has no instance getter 'iterator' - dart

so I got a chunk of code below:
...
static final Map<String, ObjectPool> _objectPools = new Map<String, ObjectPool>();
static IPoolable get(Type objectType)
{
for (String name in _objectPools) // <-- This one throws an error
{
if (_objectPools[name].runtimeType == objectType)
{
return _objectPools[name].alloc();
}
}
}
...
and it throws an error "Breaking on exception: Class '_LinkedHashMap' has no instance getter 'iterator'."
Last time I checked it's the for loop that throws me the error (as commented in the code) but I don't have a clue what causes it or any workaround for it. I also have tested that the _objectPools is filled at least one element so it should make a loop, but it doesn't.
any idea? Thanks!

You have to use for (String name in _objectPools.keys).

Related

Adding a void callback with a generic parameter to a function in Dart

What I'm trying to do
Given the following Node:
class Node<T> {
Node(this.value);
T value;
Node? child;
// TODO: add `visit` method
#override
String toString() => value.toString();
}
I'd like to add a visit method that will perform some action on the value of each node and its child recursively. Then I could do something like this:
void main() {
final root = Node(1);
root.child = Node(2);
root.child!.child = Node(3);
// one of these
root.visit(print);
root.visit((value) => print(value));
// 1
// 2
// 3
}
Naive solution
If I do the following, it works:
void visit(Function action) {
action(value);
child?.visit(action);
}
Problems with the naive solution
However, the value in this statement is inferred to be dynamic:
root.visit((value) => print(value));
I'd like to infer it to be the same type as the Node's generic T type.
Additionally, the compiler allows the following, which causes a runtime crash:
root.visit(() => 42);
I'd like that to be a compile-time error.
Attempted solution 1
If I change visit to the following:
void visit(Function(T value) action) {
action(value);
child?.visit(action(value));
}
Everything looks good at compiletime:
root.visit(print); // OK
root.visit((value) => print(value)); // OK
root.visit(() => 42); // error
But if I comment out that last one and run the code on either of the first two then I'll get the following runtime error:
Unhandled exception:
type 'Null' is not a subtype of type '(dynamic) => dynamic'
I'm not exactly sure what that means.
Attempted solution 2
Added void:
void visit(void Function(T value) action) {
action(value);
child?.visit(action(value)); // error
}
This expression has a type of 'void' so its value can't be used.
Try checking to see if you're using the correct API; there might be a function or call that returns void you didn't expect. Also check type parameters and variables which might also be void. (dartuse_of_void_result)
Attempted solution 3
This one was just a stab in the dark:
void visit(void Function<T>(T value) action) {
action(value);
child?.visit(action);
}
The visit method seems to compile but calling it as before gives compile time errors:
root.visit(print); // error
root.visit((value) => print(value)); // error
The errors read:
The argument type 'void Function(Object?)' can't be assigned to the parameter type 'void Function(T)'. (dartargument_type_not_assignable)
Related questions
These questions seem related but I couldn't figure out how to extract a solution from them:
How to create a generic method in Dart?
Callback with generic type parameter in Dart
Dart: Type error when overrding generic function in abstract class
How to check and cast generic parameters in Dart?
Dart passing generic Function<T>(T t) seems to require cast, all other ways signatures don't match
How can I solve the problem?
Thank you to #jamesdlin in the comments for solving the problem.
You need to set the generic type for the child as Node<T>. Then you can specify the method signature as void visit(Function(T value) action) and pass action itself on to the child.
Here is the full example:
void main() {
final root = Node(1);
root.child = Node(2);
root.child!.child = Node(3);
// one of these
root.visit(print);
root.visit((value) => print(value)); // value inferred as int
// root.visit(() => 42); // compile-time error
// 1
// 2
// 3
}
class Node<T> {
Node(this.value);
T value;
Node<T>? child;
void visit(Function(T value) action) {
action(value);
child?.visit(action);
}
#override
String toString() => value.toString();
}

Dart: Using Interface gives the error: "isn't a valid override of"

I've created a small interface:
import ...
abstract class IController {
void navigateTo(BuildContext context, String routeName);
Future<LocationData> get location;
// registration process
void registerGender(Gender gender);
void registerBirthday(DateTime birthday);
Future<bool> register(String email, String password);
}
And then I tried to implement this:
import ...
class Controller implements IController {
static final Controller _instance = Controller._internal();
final ServiceAuthenticate _serviceAuth = ServiceAuthenticate();
final ServiceDatabase _serviceDb = ServiceDatabase();
final ServiceGPS _serviceGPS = ServiceGPS();
User _user;
String _routeName;
UserData _userData;
Controller._internal() {
this._routeName = ROUTE_WELCOME;
}
factory Controller() => _instance;
void navigateTo(BuildContext context, String routeName) {
this._routeName = routeName;
Navigator.pushReplacementNamed(context, routeName);
}
Future<LocationData> get location async{
this._userData.location = await this._serviceGPS.location;
print(this._userData.location);
return this._userData.location;
}
void registerGender(Gender gender){
this._userData = UserData();
this._userData.gender = gender;
}
void registerBirthday(DateTime birthday) {
this._userData.birthday = birthday;
}
Future<bool> register(String email, String password) async {
User user = await this._serviceAuth.registerWithEmailAndPassword(email, password);
if(user == null){
return false;
}
this._user = user;
return true;
}
}
But that code produces the following error:
error: 'Controller.navigateTo' ('void Function(BuildContext, String)') isn't a valid override of 'IController.navigateTo' ('void Function(dynamic, String)'). (invalid_override at [prototype] lib\controller\controller.dart:30)
It looks like Dart thinks, that the BuildContext in the IController is dynamic, but this is obviously not the case.
How can I fix this? I'm new to Dart and don't know what to do.
Thanks for help :)
I'm stupid.
My import statement was wrong.
The line
import 'package:prototype/Controller/IController.dart';
produced this error, because the folder controller starts with a lowercase Letter.
The correct import statement is
import 'package:prototype/controller/IController.dart';
But regardless of my stupid mistake is the error message quite interesting.
A had a similar error and in my case the problem was that the return type of the buggy function was such that there were two different classes in the codebase with the same name. And the interface was using one and the implementation the other.
The one line answer is :
Your import statement is wrong.
But now , you need to take care in which file the import statement is going wrong.
There can be many scenarios, but I would like to give an example where I was stuck.
I had two different files in different package, but both files were importing some method where the method names were same.
So while importing the file which contain this method, I had imported the same name method from one file, and at other place, the same name method from second file.
So that's where everything went wrong!
So if import file is correct in the file which is giving some error, check the other dependent file, where same method import statement is written, that may be wrong.

Calling .filter() on a stream looses generic type

I have the following code. "Protectable" is an interface. My compiler gives the following error: "Incompatible types: Object cannot be converted to Collection"
When I remove the .filter line, everything works. Why does the compiler loose my type here?
Thanks,
Hannes
Collection<Protectable> requiredItems prefs.getConnectedProtectables(fuzDoc)
.stream()
.filter(protectable -> !protectable.itemVisibleForCurrentUser(fuzDoc))
.collect(Collectors.toList());
The variable prefs implements HasConnectedRights which is implemented as follows:
public interface HasConnectedRights {
public Collection<Protectable> getConnectedProtectables(FuzDocument doc);
}
The interface Protectable declares the method itemVisibleForCurrentUser like this:
default public boolean itemVisibleForCurrentUser(Docker<FuzDocument> doc) {
User user = UserCtrl.getCurrentUser(doc.getDoc());
return user == null || itemVisibleFor(user);
}

Dart, null reference exception on static member

I have the following class:
class Label{
static PopOver contextMenu; // can I put = new PopOver(); here?
Label(){
if(Label.contextMenu == null){ //null reference exception here why????
Label.contextMenu = new PopOver();
}
}
}
but I am getting a null reference exception on the Label.contextMenu should I be getting a null reference exception when I'm checking for null? and also can you initialise static members inline where you declare them?
You should not get a null reference exception with this code. I have tested it and I do not get any error.
You definitely can initialize static members inline. Whether you should do so depends on the situation. If the contextMenu will never change, consider making it final as well:
static final PopOver contextMenu = new PopOver();

Type cast from Java.Lang.Object to native CLR type in MonoDroid

How to cast Java.Lang.Object to some native type?
Example:
ListView adapter contains instances of native type Message. When i am trying to get SelectedItem from ListView it returns instance of Message type casted to Java.Lang.Object, but I can't find solution to cast Java.Lang.Object back to Message.
var message = (Message)list.SelectedItem;
// throws Error 5 Cannot convert type 'Java.Lang.Object' to 'Message'
Please Help.
After long time debuging, have found the solution:
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
Usage example:
var message = list.GetItemAtPosition(e.Position).Cast<Message>();
bundle.PutInt("Message", message.ID);
After careful sdk study have found MonoDroid integrated extension for this purpose:
public static TResult JavaCast<TResult>(this Android.Runtime.IJavaObject instance)
where TResult : class, Android.Runtime.IJavaObject
Member of Android.Runtime.Extensions
The least magical way of getting a native type from the Spinner is to call
message = ((ArrayAdapter<Message>)list.Adapter).GetItem(list.SelectedItemPosition);
I used this code from above answer and it works fine to me
public static class ObjectTypeHelper
{
public static T Cast<T>(this Java.Lang.Object obj) where T : class
{
var propertyInfo = obj.GetType().GetProperty("Instance");
return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
}
}
and this is how I used
var selectedLocation = locationSpinner.SelectedItem.Cast<Location>();
I am able to get my location object fine from spinner
For generic collections, the right answer would be to use JavaList, which is a Java.Lang.Object and also implements IList. But it involves more work that's for sure. This is actually just an adapter for Java's ArrayList implementation.
You could always try the JavaCast<> method (most of the views implement this)(not tested):
var message = list.SelectedItem.JavaCast< Message >();
If for some reason GetChildAtPosition is not possible, serialise the object to json string and then deserialise the string back to native class.
All of the above answers are correct but I found the simplest way for my case was to make the object a subclass of Java.Lang.Object.
For example I'm writing a Android app in Monotouch, mimicking the concept of a UITableView in iOS using the ExpandableListAdapter, which requires the equivalent of UITableViewCells, so I subclassed cell objects from Java.Lang.Object allowing me to implement a subclass of ExpandableListAdapter such as
public override Java.Lang.Object GetChild(int position, int childPosition)
Etc.
it's work for me:
public class HolderHelper<T> : Java.Lang.Object {
public readonly T Value;
public HolderHelper (T value)
{
this.Value = value;
}
}
test:
chkFileName.Tag = new HolderHelper<LinkInfo> (item);
LinkInfo link= (chkFileName.Tag as HolderHelper<LinkInfo>).Value;

Resources