flutter future do not set data - flutter

I'm trying to set langauge from a Future call. I can see that future returns an object with data(value has languageCode property and it's data) but I cannot set that data to a String variable
class Api {
String language() {
String langaugeCode;
getLocale().then((value) => langaugeCode = value.languageCode);
return langaugeCode;
}
Future<List<Product>> getProduct() async {
var response = await http.get(BASE_URL + 'language?begins-with=' + language() , headers: headers());
}
}

Future<String> language() async {
var local = await getLocale()
return local.languageCode;
}
Future<List<Product>> getProduct() async {
var lang = await language()
var response = await http.get(BASE_URL + 'language?begins-with=' + lang , headers: headers());
}

In order to set the value getLocale() returns to languageCode so it can be returned by language() you need to make language() async and await the result of language():
Future<String> language() async {
String langaugeCode;
final locale = await getLocale();
langaugeCode = locale.languageCode;
return langaugeCode;
}
The issue with the code in the question is that you get the value but only within the scope of the function passed into then(). Additionally language() is synchronous so it doesn't wait for getLocale() or its then() callback to execute before returning. This means the languageCode isn't available by the time the function returns a value.
Using this approach you'll also need to make sure that you only use language() in async functions and await it's result to get the value: await language().

Related

Exception in json.decode : Closure: () => String from Function 'toString'

I am getting some data from API in flutter. I am trying to decode the data using json.decode() but this decode function gives me the following error:
Closure: () => String from Function 'toString'
Here's my code:
Future<Product> createOrder() async {
var client = new http.Client();
var productModel = null;
try {
var response = await client
.get(Uri.https('butterbasket.onrender.com', Strings.createOrderUrl));
if (response.statusCode == 200) {
var body = response.body;
print("Body: $body");
var jsonMap = json.decode(body);
var productModel = Product.fromJson(jsonMap);
}
} catch (e) {
print("Exception: ${e.toString}");
}
return productModel;
}
Here is the Error Debug Console:
You are running into issues because the data you are loading in is an array, but the model is an object. You'll need to do something like the following:
final List jsonProducts = json.decode(body)
final List<Product> products =
jsonProducts.map((jsonProduct) => Product.fromJson(jsonProduct)).toList();
and then if you only need the first item you can do:
final Product product = products[0]
But don't forget to check if the array is big enough.
Your Future function must return an optional Product?, otherwise your future will never find a result as you are declaring it inside the function.
Instead of:
Future<Product> createOrder() async {}
Use:
Future<Product?> createOrder() async {}
Finally your async snapshot and FutureBuilder type should be of type <Product?>.

Instance of '_Future<dynamic>' instead of input value in Translator package from Flutter

this scope gives me Instance of _Future but I want to get that translated text.
Future<dynamic> translate(String input) async {
final translator = GoogleTranslator();
var result;
var translation = await translator
.translate(input, to: 'tr')
.then((value) => {result = value});
return result;
}
Does this work? I guess the .translate function returns an Translate instance. You need the text attribute to get a String
Below code is wrong!
Future<String> translate(String input) async {
final translator = GoogleTranslator();
var result;
var translation = await translator
.translate(input, to: 'tr')
.then((value) => {result = value});
return result.text;
}
Also you use a then clause and getting the result of translation in to value so you don't need to use await and set the var translation in this case. Or you can use await and remove the then. But you should not use both await and then for the same async method.
So the below code should be used:
Future<String> translate(String input) async {
final translator = GoogleTranslator();
var translation = await translator
.translate(input, to: 'tr');
return translation.text;
}

Flutter : How can use String data outside future method?

I have this future method to get a data from server and using it :
Future<String> get_week() async {
var weekUrl =
'https://xxx/api/controller/matchs/active_week.php';
var weekresponse = await http.get(weekUrl);
var weekdata = await jsonDecode(weekresponse.body);
var weekId = weekdata[0]['w_id'];
return weeId
}
How can i use the value of weekId outside this method?
You can use the await keyword to assign the returned value from the future to variable:
String id = await get_week();

How can I return a Future from a stream listen callback?

I have below code in flutter:
getData() {
final linksStream = getLinksStream().listen((String uri) async {
return uri;
});
}
In getData method, I want to return the value of uri which is from a stream listener. Since this value is generated at a later time, I am thinking to response a Future object in getData method. But I don't know how I can pass the uri as the value of Future.
In javascript, I can simply create a promise and resolve the value uri. How can I achieve it in dart?
In your code 'return uri' is not returning from getData but returning from anonymous function which is parameter of listen.
Correct code is like:
Future<String> getData() {
final Completer<String> c = new Completer<String>();
final linksStream = getLinksStream().listen((String uri) {
c.complete(uri);
});
return c.future;
}
Try this
Future<String> getData() async{
final linksStream = await getLinksStream().toList();
return linksStream[0].toString();
}

how to get data from conn.query in dart

I am doing dart with postgresql , I can't return data the conn.query(rows). but the results are coming ,how to return it, simple code is
main(){
someOtherFunc();
}
Future add() async{
var uri = 'postgres://postgres:root#localhost:5432/testdb';
var conn = await connect(uri);
var sql = 'select * from test';
return conn.query(sql).toList();
}
Future someOtherFunc() async {
print(await add());
}
I got return as "Instance of '_Future'!"
If you use await in the function you call add() from, you get the desired result
Future add() async {
var uri = 'postgres://postgres:root#localhost:5432/testdb';
var conn = await connect(uri);
var sql = 'select * from test';
return conn.query(sql).toList();
}
Future someOtherFunc() async {
print(await add());
}
async is contagious. When you call an async function, you can't return to sync execution. Everything that depends on the async results, needs to use await (or the "old" .then((value) {})) . async + await just create the illusion of sync execution.