Flutter: _TypeError - flutter

I'm trying to get datas from api and add them a list. But at this moment, I see datas i got but I can't get it out of the function. What should i do?
function
List<dynamic> xxx = [];
#override
void initState() {
super.initState();
Future<List<dynamic>> fetchCompanies(List<dynamic> datas) async {
var response = await Dio().get(CompaniesPath().url);
if (response.statusCode == HttpStatus.ok) {
Map<String, dynamic> company = jsonDecode(response.data);
for (int i = 0; i < company['Data'].length; i++) {
datas.add(company['Data'][i]);
}
//print(datas); //=> I see datas here
} else {
throw Exception();
}
return datas;
}
print(fetchCompanies(xxx));
}
When I run print(fetchCompanies(xxx)); I got "Instance of 'Future<List<dynamic>>'". How can i get data inside fetchCompanies to my xxx list?

You're trying to print future instance of List that's why you got
Instance of Future<List>
You have to wait until function finish executing.
Catch here is you can't call wait in initState() so you have to use .then method
try this:
fetchCompanies(xxx)
.then((result) {
print("result: $result");
});

It should already work fine like it is. But you probably want to call a setState to refresh the page. Try this:
#override
void initState() {
super.initState();
Future<List<dynamic>> fetchCompanies(List<dynamic> datas) async {
var response = await Dio().get(CompaniesPath().url);
if (response.statusCode == HttpStatus.ok) {
Map<String, dynamic> company = jsonDecode(response.data);
for (int i = 0; i < company['Data'].length; i++) {
datas.add(company['Data'][i]);
}
//print(datas); //=> I see datas here
setState(() {}); // added this
} else {
throw Exception();
}
return datas;
}
print(fetchCompanies(xxx));
}

Related

sqflite is taking too long time to fetch data from database

This is the code which i used to fetch data from database
Future<List<ShadeColorDatabase>?> getShadeColorData() async {
Database? db = await instance.database;
try {
var data = await db!.query(table4);
List<ShadeColorDatabase>? shadeColorDataList = data.isNotEmpty
? data.map((e) => ShadeColorDatabase.fromMap(e)).toList()
: [];
return shadeColorDataList;
} catch (e) {
rethrow;
}
}
and i called this function in my screen like this
filterDatabaseData() async {
final databaseData = await DatabaseHelper.instance.getShadeColorData();
for (int i = 0; i < databaseData!.length; i++) {
print("${databaseData[i].colorName}");
setState(() {
allColorCodeList.add(databaseData[i].colorName);
});
}
}
#override
void initState() {
// TODO: implement initState
super.initState();
filterDatabaseData();
}
but i get this warning saying:- warning-database-has-been-locked-for-00010-000000-make-sure-you-always-use-th. this says when i run my app for the first time. Meaning if someone is running the app for the first time this warning is showing and related data is not showing is there any way i can fix this problem need some help. Thanks

Empty map on flutter when initiating

Map user = {};
Future<void> getUser(String idProfile) async {
final response = await ac.getItem("/v2/users/:0", [idProfile]);
if (response.statusCode >= 200 && response.statusCode < 300) {
setState(() {
user = json.decode(response.body);
print(user);
});
}
}
#override
void initState() {
super.initState();
getUser(getCurrentUser());
print(user);
}
With the first print, it returns me the user. However, at the second doesn't. I need to get the user information. How could I do it?
getUser is a future method, you need to wait until it fetches data from API. While you are using StatefulWidget , you can show landing indication while it fetch data from API.
If it is inside Column widget,
if (user.isEmpty) Text("fetching data")
else LoadDataWidget(),
Also you can use ternary operator.
Map user = {};
//Return a user from the function
Future<Map<String, dynamic>> getUser(String idProfile) async {
final response = await ac.getItem("/v2/users/:0", [idProfile]);
if (response.statusCode >= 200 && response.statusCode < 300) {
user = json.decode(response.body) as Map<String, dynamic>;
return user
}
else {
throw Exception();
}
}
// Set the user value in initstate
#override
void initState() {
super.initState();
user = getUser(getCurrentUser());
print(user);
}

How to update a list in initState() flutter after the api call?

So I have a Stateful Widget which has a List variable I want to update from the API call. My issue is that the List is empty even after I do the fetchItems() in the initState().
How can I then update the itemsList with the content of the fetchItems function?
Isnt the function suppose to update itemsList if I use setState().
class _ItemsWidgetState extends State<ItemsWidget> {
List<ItemsModel> itemsList = [];
void initState(){
fetchItems();
}
fetchItems() async {
final response = await http.get(url);
if (response.statusCode == 200) {
final fetchedItems = json.decode(response.body);
for (var item in fetchedItems) {
ItemsModel item = ItemsModel.fromJson(item);
setState(() {
itemsList.add(item);
});
}
} else {
throw Exception('Failed to load items');
}
}
Avoid calling setState inside loops, call it after your task has done.
Always call super.initState and mark initState as overrided
class _ItemsWidgetState extends State<ItemsWidget> {
List<ItemsModel> itemsList = [];
#override
void initState(){
super.initState();
fetchItems();
}
fetchItems() async {
final response = await http.get(url);
if (response.statusCode == 200) {
final fetchedItems = json.decode(response.body);
for (var item in fetchedItems) {
ItemsModel item = ItemsModel.fromJson(item);
/// Remove from setState
itemsList.add(item);
}
/// Tells to Flutter that now something has changed
setState(() {});
} else {
throw Exception('Failed to load items');
}
}
First check fetchedItems is a list type.
class _ItemsWidgetState extends State<ItemsWidget> {
List<ItemsModel> itemsList = [];
void initState(){
fetchItems();
}
fetchItems() async {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final fetchedItems = jsonDecode(response.body);
for (var item in fetchedItems) {
ItemsModel item = ItemsModel.fromJson(item);
setState(() {
itemsList.add(item);
});
}
} else {
throw Exception('Failed to load items');
}
}

Flutter initState wait for async function to complete

in my main.dart i have among others those two functions:
Future<void> _fetchMasterData() async {
print("Start fetch");
var jwt = await API.attemptLogIn();
if (jwt != null) {
Map<String, dynamic> answer = jsonDecode(jwt);
if (answer['message'] == 'Auth ok') {
jwtToken = 'Bearer ' + answer['token'];
}
}
await _getArticles();
await _getMainCategories();
await _getIngredients();
await _getArticleIngredients();
print("EndMasterData fetch");
}
And
#override
void initState() {
super.initState();
_fetchMasterData();
}
What i would like to have is to wait in initState till _fethcMasterData is done bevore Widgert build is called.
Is that possible? Many thanks for any help!
Here how I use an async func in initstate;
builder() async {
favoriteDatabase =
await $FloorFavoriteDatabase.databaseBuilder('favorite_database.db')
.build();
setState(() {
favoriteDao = favoriteDatabase.favoriteDao;
});
}
#override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
WidgetsBinding.instance.addPostFrameCallback((_) =>
getNamePreferences().then(updateName));
});
builder();
favoriteDao.findAllMoviesAsStreamW();
favoriteDao.findAllMoviesAsStream();
}
Also you can check this mini article too.
It is not possible to await in initState, so when you finish all loading process then you can call SetState method which populate your widget with actual data.
Second solution could be use of futurebuilder or streambuilder where you want to show data but it is only possible if any methods data is not dependent on each other.
Future<void> _fetchMasterData() async {
print("Start fetch");
var jwt = await API.attemptLogIn();
if (jwt != null) {
Map<String, dynamic> answer = jsonDecode(jwt);
if (answer['message'] == 'Auth ok') {
jwtToken = 'Bearer ' + answer['token'];
}
}
await _getArticles();
await _getMainCategories();
await _getIngredients();
await _getArticleIngredients();
print("EndMasterData fetch");
SetState((){}); // added line
}

Flutter flutter_in_app_purchases subscription FlutterInAppPurchses.instance.getSubscriptions() is not retrieving any items for IAPItem

I'm trying to implement a renewable subscription in flutter using the flutter_in_app_purchases plugin. When I click on the screen that this is declared in, it goes through the initState() function and then gets to the initPlatformState() and goes through that successfully, but when it gets to the getProducts() function, it's returning an empty item list for the List items = FlutterInappPurchase.instance.getSubscriptions([productID]); call. I've added the monthly subscription in both the App Store Connect and Google Play Store and completed the tax forms. Any help would be appreciated.
List<IAPItem> _items = [];
static const String productID = 'monthly_subscription';
#override
void initState() {
super.initState();
print("IN INIT STATE");
initPlatformState();
}
Future<void> initPlatformState() async {
print("In init platform state");
// prepare
final bool available = await InAppPurchaseConnection.instance.isAvailable();
print(available);
var close = await FlutterInappPurchase.instance.endConnection;
var result = await FlutterInappPurchase.instance.initConnection;
print('result: $result');
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) {
print('In not mounded');
return;
}
// refresh items for android
/*try {
String msg = await FlutterInappPurchase.instance.consumeAllItems;
print('consumeAllItems: $msg');
} catch(e){
print(e.toString());
}*/
await _getProduct();
}
Future<Null> _getProduct() async {
print("In get products");
try {
List<IAPItem> items = await FlutterInappPurchase.instance.getSubscriptions([productID]);
print("Items is: $items");
for (var item in items) {
print('${item.toString()}');
this._items.add(item);
}
setState(() {
this._items = items;
});
} catch(e) {
print(e.toString());
}
}
Here you have a working example from app in production. Disclaimer: I'm not using it anymore but the last time I did it worked fine:
class _InAppState extends State<InApp> {
StreamSubscription _purchaseUpdatedSubscription;
StreamSubscription _purchaseErrorSubscription;
StreamSubscription _conectionSubscription;
final List<String> _productLists = Platform.isAndroid
? [
'subs_premium', 'subs_user'
]
: ['subs_premium', 'subs_boss', 'subscripcion_user'];
String _platformVersion = 'Unknown';
List<IAPItem> _items = [];
List<IAPItem> _subscripions = [];
List<PurchasedItem> _purchases = [];
#override
void initState() {
super.initState();
initPlatformState();
}
#override
void dispose() {
super.dispose();
if (_conectionSubscription != null) {
_conectionSubscription.cancel();
_conectionSubscription = null;
}
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
platformVersion = await FlutterInappPurchase.instance.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// prepare
var result = await FlutterInappPurchase.instance.initConnection;
print('result: $result');
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
// refresh items for android
try {
String msg = await FlutterInappPurchase.instance.consumeAllItems;
print('consumeAllItems: $msg');
} catch (err) {
print('consumeAllItems error: $err');
}
_conectionSubscription = FlutterInappPurchase.connectionUpdated.listen((connected) {
print('connected: $connected');
});
_purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) {
print('purchase-updated: $productItem');
});
_purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) {
print('purchase-error: $purchaseError');
});
final List<String> _SKUS = widget.premium ? ['subs_boss']
: ['subs_user'] ;
_getSubscriptions(_SKUS);
}
void _requestPurchase(IAPItem item) {
FlutterInappPurchase.instance.requestPurchase(item.productId);
}
Future _getProduct() async {
print('TEST 1 HERE ${_productLists.length}, ${_productLists.first.toString()}');
List<IAPItem> items = await FlutterInappPurchase.instance.getProducts(_productLists);
print('TEST 2 HERE ${items.length}');
for (var item in items) {
print('${item.toString()}');
this._items.add(item);
}
setState(() {
this._items = items;
this._purchases = [];
});
}
Future _getPurchases() async {
List<PurchasedItem> items =
await FlutterInappPurchase.instance.getAvailablePurchases();
for (var item in items) {
print('${item.toString()}');
this._purchases.add(item);
}
setState(() {
this._items = [];
this._purchases = items;
});
}
Future _getSubscriptions(_SKUS) async {
List<IAPItem> items =
await FlutterInappPurchase.instance.getSubscriptions(_SKUS);
for (var item in items) {
print('${item.toString()}');
this._subscripions.add(item);
}
setState(() {
this._items = [];
this._subscripions = items;
});
}
Future _getPurchaseHistory() async {
List<PurchasedItem> items = await FlutterInappPurchase.instance.getPurchaseHistory();
for (var item in items) {
print('${item.toString()}');
this._purchases.add(item);
}
setState(() {
this._items = [];
this._purchases = items;
});
}