flutter - Dart Map in Map called on null - dart

I have this
var _subscription = Map<String, Map<String, StreamSubscription<DocumentSnapshot>>>();
When I tried to call this
_subscription[id][userId] = Firestore.instance.collection('user').document(userId).snapshots().listen((snapshot)
console says this.
The method '[]=' was called on null
Does anyone know what am I missing?

Related

Why toList() creates a List<dynamic> in Dart?

I have this method, which compiles with no problems in Dart 2. However at run-time I get the following error
type 'List<dynamic>' is not a subtype of type 'List<ExchangeRate>'
As you see in the code I create and return new ExchangeRate objects within .map() and then after that I return a rateEntries.toList() which I expect to be of type List<ExchangeRate>, however it seems to be inferred as type List<dynamic>!!!
#override
Future<List<ExchangeRate>> getExchangeRatesAt(DateTime time, Currency baseCurrency) async {
final http.Client client = http.Client();
final String uri = "some uri ...";
return await client
.get(uri)
.then((response) {
var jsonEntries = json.decode(response.body) as Map<String, dynamic>;
var rateJsonEntries = jsonEntries["rates"].entries.toList();
var rateEntries = rateJsonEntries.map((x) {
return new ExchangeRate(x.value.toDouble());
});
return rateEntries.toList(); // WHY IS IT RETURNING A List<dynamic> here?
})
.catchError((e) => print(e))
.whenComplete(() => client.close());
}
However if I cast it specifically to ExchangeRate it would be fine.
return rateEntries.toList().cast<ExchangeRate>();
This casting at the end seems redundant to me, why should I need it?
Well, it seems that the cast is necessary to fully define the type.
But, you can avoid the cast if you add any of the following snippets:
Give the correct type to the rateJsonEntries variable
List<dynamic> rateJsonEntries = jsonEntries["rates"].entries.toList();
For whatever reason this works in my case.
Add the parameter type to the map() method
var rateEntries = rateJsonEntries.map<ExchangeRate>((x) {
return new ExchangeRate(x.value.toDouble());
});

Dart programming calling the method from another class

I need some help here i am trying to this getdetails.getuserid method in the another class but i am getting error like this type 'Future<dynamic>' is not a subtype of type 'String'
class getdetails {
Future<Null> getuserid() async {
SharedPreferences pref = await SharedPreferences.getInstance();
String userid = pref.getString('userid');
return userid;
}
}
I am getting this error Closure: () => dynamic from Function 'getuserid': static.() in dart if i try to call like below
String getuserid() async {
SharedPreferences pref = await SharedPreferences.getInstance();
String userid = pref.getString('userid');
return userid;
}
You need to define the return type of your function to Future<String>
Future<String> getuserid() async {
....
}
remove null and place String after Future...
Future
You have got quiet a few errors there .
1. In the first code sample you were returning a null future while your code you were returning a string . that dosen't make any sense.
2. In your second code sample you are returning just a string while your function is an async function so its another error that might even be shown to u on whichever IDE you are working with .
something like -> you need to return a future . So it should be Future
as mentioned in the previous answer.
Future<String>
Create a String var just say
String userId = "";
inside your class getdetails.
then inside your function getuserid() do this supposing that you already have some value in userid key that you are using for shared preferences.
getuserid() async{
SharedPreferences pref = await SharedPreferences.getInstance();
String u = pref.getString('userid');
userId = u ;
}
now create another function in same class just to make things simple and clear .
String userdetails(){
return userId;
}
now in the class/widget(stateful/stateless) where you want to get the userId do this :-
create an object of that class like this
getdetails g ;
now call the functions created like this ..
g.getuserid().then((){
String ID = g.userdetails();
});
What i am doing here is first create a function that gets your value and stores it into a local variable then call another function to get the value of that local variable when the value have been retrieved from the shared prefs class and stored into that local variable using the same object i.e why i used .then((){}) function
I hope it helps .

Flutter MethodChannel nested values: 'List<dynamic>' is not a subtype of type 'FutureOr<List<Map<String, double>>>'

I'm writing a Flutter Plugin that sends a List of Maps (List<Map<String, double>>) from the Platform specific side. On the Platform specific side, I'm sending these Objects using the Default Message Codec.
// (example: Android side)
List<Map<String, Double>> out = new ArrayList<>();
... fill the map ...
result.success(out);
I'm receiving these values as follows on the Dart side:
static Future<List<Map<String, double>>> getListOfMaps() async {
var traces = await _channel.invokeMethod('getListOfMaps');
print(traces); // works
return traces;
}
Printing the values gives the correct values. However, on the Function Return, I'm getting the following Error type 'List<dynamic>' is not a subtype of type 'FutureOr<List<Map<String, double>>>' on run-time, indicating that the cast from the dynamic value to the specific Map<String, double> didn't work.
How do I cast nested values coming from MethodChannels correctly in Dart?
As pointed out in the comments, I have to cast every value with unknown runtime type individually to the expected type.
static Future<List<Map<String, double>>> getListOfMaps() async {
List<dynamic> traces = await _channel.invokeMethod(...);
return traces
.cast<Map<dynamic, dynamic>>()
.map((trace) => trace.cast<String, double>())
.toList();
}
You can now use invokeListMethod:
Since invokeMethod can only return dynamic maps, we instead create a new typed list using List.cast.
var channel = MethodChannel('foo_channel');
var list = await channel.invokeListMethod<Map<String, double>>('methodInJava');

IronResponse calls an JsObjectImpl object, but I cant find class docs on it

I was trying to parse the return of an IronAjax success handler and set the response to an instance of Map. It seems to not like that.
My HTML Markup is:
<iron-ajax id="myAjaxId" auto
url="http://localhost:12345/test_server/v1/daily"
handle-as="json"
on-response="handleResponse" on-error="handleError"></iron-ajax>
My Dart Code is:
void handleResponse(CustomEventWrapper cew, IronRequest ir){
print("inside handleResponse");
var data = ir.response; // <-- is type JsObjectImpl
print("data");
print(data);
if (data == null) return;
print ("About to set rows");
List<Map> rows = data.containsKey("data") ? data["data"] : [];
print("Variables are Set locally");
$['myDatagrid'].render();
}
#reflectable
String camelToFormal (String input){
String out;
RegExp regex = new RegExp("([A-Z])");
out = input[0].toUpperCase() + input.substring(1).replaceAllMapped(regex, (Match m) => " ${m[1]}");
return out;
}
#reflectable
void handleError(CustomEventWrapper cew, IronRequest ir){
print("____Error:____");
print(ir.response);
}
The Error I get is:
type 'JsObjectImpl' is not a subtype of type 'Map' of 'other'.
I wasnt sure if I need to run convert over it, even though the return type set by IronAjax was json
So, since ir.response will either be set or null, i check if it is null first. the var data line in responseHandler currently sets is, but i have also attempted to do something like: Map data = new Map.from(ir.response); which fails as well.
Even though this is said to be handled as JSON, and is returning a jslint confirmed objected, it seems to have issues to convert it to a proper map instance.
According to Polymer IronRequest at: https://elements.polymer-project.org/elements/iron-ajax?active=iron-request
it says that responseis *, the parsed response body. Am I mistaken as to how this is properly set up, or am I missing something?
You could try Object instead of map on the property and then use convertToDart. Not sure this results in a Map but worth a try I guess. See also Polymer 1.0 - iron-list - selection

Breeze throws Null reference exception when calling EntityAspect.validateProperty() method

I have the following entity property defined as the following metadata shows:
{"name":"website","dataType":"String",
"validators":[
{"name":"string"},
{"messageTemplate":"'%displayName%' is not valid",
"pattern":"^$|(^http|^https)://[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}(/S*)?",
"name":"regExValidator"}]}
When I attempt to call entityAspect.validateProperty("website"), and the value of the website property is null, the call to the validateProperty() method throws the following exception:
"Unable to get property 'complexAspect' of undefined or null
reference"
I wouldn't expect this behavior since it's possible that the website entity property could be null. It looks like there may be a null reference handling bug in the validateProperty method:
In Breeze.debug.js:
proto.validateProperty = function (property, context) {
var value = this.getPropertyValue(property); // performs validations
if (value.complexAspect) { // THROWS EXCEPTION IF 'value' IS NULL
return validateTarget(value);
}
context = context || {};
context.entity = this.entity;
if (typeof(property) === 'string') {
context.property = this.entity.entityType.getProperty(property, true);
context.propertyName = property;
} else {
context.property = property;
context.propertyName = property.name;
}
return this._validateProperty(value, context);
};
Just curious if I'm doing something wrong, or if this is just a bug?
Thanks,
Richard
Edit: This was fixed in Breeze v1.3.0, available now.
This is a bug, and will be fixed in the next release, out later this week. ... and thx for finding and reporting it :)

Resources