Did flutter methodchannel support return a List<Map<String, String>> value? - flutter-animation

as title said, I wrote an plugin that return a List> value, but I can't get the result from my plugin, and there was no error.
Is any thing wrong?
How to implement the customized type returned by MethodChannel?

DO NOT:
List<Map<String, dynamic>> resp = await _channel.invokeMethod('returnAMapList');
DO:
List<Map> = await _channel.invokeMethod('returnAMapList');

Related

Dart Future async not working as expected

I'm getting an
'await' can only be used in 'async' or 'async*' methods.
In popup error:
The await expression can only be used in an async function. Try
marking the function body with either 'async' or
'async*'.dart(await_in_wrong_context)
firestore.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:workout/main.dart';
class FirestoreViewModel {
Future<List<int>> getDocuments(
String type, int numValues, bool isDescending) async {
List<int> _list;
QuerySnapshot documents = await FirebaseFirestore.instance
.collection('workouts')
.where('id', isEqualTo: googleSignIn.currentUser.id)
.orderBy('date', descending: isDescending)
.limit(numValues)
.get();
_list = documents.docs.map((snapshot) => snapshot['water'] as int).toList();
return _list;
}
}
file.dart
import 'package:workout/services/firestore_view_model.dart';
List<int> _waters = await FirestoreViewModel().getDocuments("water", 7, true);
I just can't seem to get a list with all the Futures, awaits, and asyncs going around. I've looked at other solutions on here but they are set up a bit differently. Either way, I don't know how to create a method that returns a list, when the firestore is full of futures. Any ideas would be appreciated.

Convert dart http.get request to match the constructor

I have the following code in dart:
final uri = Uri.https('api.server', '/json/pages', queryParams);
final response =
await http.get(uri, headers: {"Accept": "application/json"});
However the app is throwing an exception citing:
type '_InternalLinkedHashMap<String, Object>' is not a subtype of type 'Map<String, String>'
How do I convert the response to a valid type expected by http.get's constructor or is there another workaround?
Thanks
You may need to fix the queryParams
Map<String, String> stringParams = {};
// or
var stringParams = <String, String>{};
Look at here

flutter dart error when installing google api calendar

I will display a list of events from Google Calendar.
I followed the example already in the following link : How to use Google API in flutter?
and my script is as follows :
import 'package:http/http.dart' as http;
assumed I was logged in.
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: <String>[
'email',
'https://www.googleapis.com/auth/contacts.readonly',
'https://www.googleapis.com/auth/calendar'
],
);'
class GoogleHttpClient extends http.BaseClient {
Map<String, String> _headers;
GoogleHttpClient(this._headers) : super();
#override
Future<http.StreamedResponse> send(http.BaseRequest request) =>
super.send(request..headers.addAll(_headers)); //have error 'the method 'send' is always abstract in the supertype'
#override
Future<http.Response> head(Object url, {Map<String, String> headers}) =>
super.head(url, headers: headers..addAll(_headers));
}
void getCalendarEvents() async {
final authHeaders = _googleSignIn.currentUser.authHeaders;
final httpClient = new GoogleHttpClient(authHeaders); //have error "The argument type 'Future<Map<String, String>>' can't be assigned to the parameter type 'Map<String, String>'"
var calendar = new Calendar.CalendarApi(new http.Client());
var calEvents = calendar.events.list("primary");
calEvents.then((Calendar.Events events) {
events.items.forEach((Calendar.Event event) {print(event.summary);});
});
}
the above script cannot run because of an error.
the method 'send' is always abstract in the supertype
can someone help me?
If your code is based on How to use Google API in flutter? you'll see that I have a #override Future<StreamedResponse> send(...) in my code.
GoogleHttpClient extends abstract class IOClient that is missing an implementation of send, so the concrete subclass needs to implement it.
That's what the error message is about.
Replace StreamedResponse with IOStreamedResponse
add IOClient library
replace class GoogleHttpClient extends IOClient with class GoogleHttpClient extends http.BaseClient
1 This is error
//have error "The argument type 'Future<Map<String, String>>' can't be assigned to the parameter type 'Map<String, String>'"
fixed: add await ahead
Like below:
final authHeaders = await _googleSignIn.currentUser.authHeaders;
2: Change like below
var calendar = new Calendar.CalendarApi(new http.Client());
to
var calendar = new Calendar.CalendarApi(httpClient);
======> Final:
void getCalendarEvents() async {
final authHeaders = await _googleSignIn.currentUser.authHeaders;
final httpClient = new GoogleHttpClient(authHeaders);
var calendar = new Calendar.CalendarApi(httpClient);
var calEvents = calendar.events.list("primary");
calEvents.then((Calendar.Events events) {
events.items.forEach((Calendar.Event event) {print(event.summary);});
});
}
It worked for me.

Flutter: shared preferences

I have this function:
Future<String> load(SharedPreferences prefs, String fileName) async {
prefs = await SharedPreferences.getInstance();
String jsonString = prefs.getString(fileName) ?? "";
if (jsonString.isNotEmpty) {
return jsonString;
}else{
return ...
}
}
What should I return in the else case? I tried with "" but it doesn't work.
Shared Preferences
In Flutter, Shared Preferences are used to store primitive data (int, double, bool, string, and stringList). This data is associated with the app, so when the user uninstalls your app, the data will also be deleted.
Get the plugin
The shared_preferences plugin from pub is a wrapper around Android SharedPreferences and iOS NSUserDefaults. You can get this plugin by adding the shared_preferences line to your pubspec.yaml file in the dependencies section.
dependencies:
shared_preferences: '>=0.5.12+2 <2.0.0'
You can change the version number to whatever the current one is, but anything less than 2.0 should be compatible.
Import the package
In whichever file you need the Shared Preferences, add the following import:
import 'package:shared_preferences/shared_preferences.dart';
Reading and writing data
To get the shared preferences object you can do the following:
final prefs = await SharedPreferences.getInstance();
This will be used for all of the following examples.
int
read: final myInt = prefs.getInt('my_int_key') ?? 0;
write: prefs.setInt('my_int_key', 42);
double
read: final myDouble = prefs.getDouble('my_double_key') ?? 0.0;
write: prefs.setDouble('my_double_key', 3.14);
bool
read: final myBool = prefs.getBool('my_bool_key') ?? false;
write: prefs.setBool('my_bool_key', true);
string
read: final myString = prefs.getString('my_string_key') ?? '';
write: prefs.setString('my_string_key', 'hello');
stringList
read: final myStringList = prefs.getStringList('my_string_list_key') ?? [];
write: prefs.setStringList('my_string_list_key', ['horse', 'cow', 'sheep']);
Removing data
You can remove any saved data by supplying the key name:
prefs.remove('my_int_key');
I rarely find a need to do that, though. I just overwrite the old data or ignore it. You shouldn't store any sensitive data in Shared Preferences.
See also
Shared Preferences Service in Flutter for Code Maintainability
Documentation: Storing key-value data on disk
What are the ?? double question marks in Dart?
How to create an empty list in Dart
The answer is "it depends". Namely, it depends on what exactly you are doing with the result of this function, and what a good empty default value means in that context.
Assuming you're decoding the returned JSON string into a Map<String, dynamic>, then a good default value might be the empty map. In that case, you could reformulate your function as follows:
Future<String> loadJSON(final String fileName) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String jsonString = prefs.getString(fileName);
if (jsonString != null && jsonString.isNotEmpty) {
return jsonString;
}
return "{}"; // default value
}
final String jsonString = await loadJSON("test.json");
final Map<String, dynamic> jsonData = json.decode(jsonString);
However, it probably makes more sense to reformulate this procedure as a slightly higher-level function returning actual map values:
Future<Map<String, dynamic>> loadData(final String fileName) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String jsonString = prefs.getString(fileName);
if (jsonString != null && jsonString.isNotEmpty) {
return json.decode(jsonString);
}
return Map(); // default value
}
final Map<String, dynamic> jsonData = await loadData("test.json");

Make a http request in dart whith dart:io

Hey I'm a beginner and I want to interact with an API with dart:io for fetch JSON files I can fetch the data with this code :
final HttpClient client = HttpClient();
client.getUrl(Uri.parse("https://api.themoviedb.org/3/movie/76341?api_key=fbe54362add6e62e0e959f0e7662d64e&language=fr"))
.then((HttpClientRequest request) {
return request.close();
})
.then((HttpClientResponse response) {
Map a;
print(a);
But I want to have a Map whith the JSON but I can't do it. If I could get a String that contains the JSON I could do it with
json.decode();
also know that the answer is stored in an int list that represents the utf8 values of the characters so with utf8.decode(responce.toList()) I can get the utf8 value but responce.toList() return a Future but even if it may be easy I don't know how to get the list.
import 'dart:convert';
import 'dart:io';
void main() async {
final client = HttpClient();
final request = await client.getUrl(Uri.parse(
'https://api.themoviedb.org/3/movie/76341?api_key=fbe54362add6e62e0e959f0e7662d64e&language=fr'));
final response = await request.close();
final contentAsString = await utf8.decodeStream(response);
final map = json.decode(contentAsString);
print(map);
}

Resources