How to fix 'NoSuchMethodError: The getter 'length' was called on null' - flutter

How i can fix this problem
i use function to get data from api, but i see error 'NoSuchMethodError: The getter 'length' was called on null'
My code:
Future getData() async{
http.Response response = await http.get('https://myappres.000webhostapp.com/pubg/api.php?action=getskin');
debugPrint(response.body);
_data = json.decode(response.body);
_list = _data['categorys'];
return _list;
}
and
Center(
child: _list.length != null? ListView.builder(
itemCount: _list.length,
padding: const EdgeInsets.all(15.9),
itemBuilder: (BuildContext context, int position){
final index = position;
return ListTile(
title: Text('${_list[index]['name']}'),
subtitle: Image.network('${_list[index]['image']}',width: 200,)
);
}
):Container()
)
this is result Error:

Try using FutureBuilder to wait for the Future:
FutureBuilder(
future: getData(),
builder: (BuildContext context,AsyncSnapshot<List> snapshot){
if(snapshot.hasData){
return Center(child: snapshot.length)
} else return Container();
},
//you can use too:
getData().then((listData){
Center(child: listData)...
});

Related

How to convert type 'Future<dynamic>' is not a subtype of type 'Stream<Object?>?'

I want to get the data from Firebase in streambuilder. How to convert the Future into Stream.
Below is my code.
getData() async {
var db = FirebaseFirestore.instance;
await db.collection('categories').doc(value).get().then((DocumentSnapshot doc) {
var listSubCol = doc["categoryCollection"];
listSubCol.forEach((id) {
db.collection('categories').doc(value).collection(id).get().then((snapshot) {
snapshot.docs.forEach((element) {
items.add(element.data());
});
});
return items;
});
});
return items;
}
StreamBuilder(
stream: getData(),
builder: (BuildContext context,snapshot){
print('snap: ${items.length}');
if(!snapshot.hasData){
return Center(
child: CircularProgressIndicator(),
);
}else{
return Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, int index){
return Text(items[index]['categoryName']);
},
),
);
}
}
),
can anyone please help me on this issue.

The property can't be unconditionally accessed because the receiver can be 'null'...?

Hey guys i have an error and the code is bellow:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
class ChatScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats/RMxQeDVKeYPOW940bWCH/messages/')
.snapshots(),
builder:(ctx, snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
final docs = snapshot.data.docs;
return ListView.builder(
itemCount: docs.length,
itemBuilder: (ctx, index) => Container(
padding: EdgeInsets.all(8),
child: Text(docs[index]['text']),
),
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: (){
FirebaseFirestore.instance
.collection('chats/RMxQeDVKeYPOW940bWCH/messages/')
.snapshots()
.listen((event) {
event.docs.forEach((element) {
print(element['text']);
});
});
},
),
);
}
}
Now the problem is in:
final docs = snapshot.data.docs;
And it says that:
The property 'docs' can't be unconditionally accessed because the receiver can be
'null'.
it is just having an error in docs after the snapshot data so can anybody please help me in that?
Thanks.
You need to make change is on this line
builder: (context, snapshot) to builder: (context, AsyncSnapshot snapshot)
then use
snapshot.data as snapshot.data!.
you are doing everything perfectly, except for the fact to add the Type for the StreamBuilder. Null safety alone won't solve your problem. Here is a piece of code that I altered a bit only in the body of Scaffold Widget.
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('chats/RMxQeDVKeYPOW940bWCH/messages/')
.snapshots(),
builder:(ctx, snapshot){
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if(snapshot.hasData) {
final docs = snapshot.data!.docs;
return ListView.builder(
itemCount: docs.length,
itemBuilder: (ctx, index) => Container(
padding: EdgeInsets.all(8),
child: Text(docs[index]['text']),
),
);
}
else {
return Text("Something Went wrong");
}
},
)
As the error message says, The property docs can't be unconditionally accessed because the receiver can be
null.
var docs = snapshot?.data?.docs;
return ListView.builder(
itemCount: docs?.length ?? 0,
itemBuilder: (ctx, index) => Container(
padding: EdgeInsets.all(8),
child: Text(docs?[index]['text'] ?? ''),
),
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: (){
if(event.docs =! null)
FirebaseFirestore.instance
.collection('chats/RMxQeDVKeYPOW940bWCH/messages/')
.snapshots()
.listen((event) {
event.docs.forEach((element) {
print(element['text']);
});
});

Flutter : Class 'Future<List<String>>' has no instance getter 'length'

I have a List of String saved on SharedPreference in Flutter app, I want to call it inside Provider and using it in a widget.
Provider :
get myTeam => getMyTeam();
Future<List<String>> getMyTeam() async {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final SharedPreferences prefs = await _prefs;
return prefs.getStringList('team');
}
I used it in future builder :
Widget build(BuildContext context) {
return Consumer<GeneralProvider>(
builder: (context, generalProvider, child) {
var items = generalProvider.myTeam;
return FutureBuilder(
future: items,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${items[index].club}'),
);
});
} else {
return Text('bad');
}
});
});
}
I get error : Class 'Future<List<String>>' has no instance getter 'length'
I tied with many solutions in questions here like :
Class 'Future<dynamic>' has no instance getter 'length'
but it wasn't solved
Change itemCount: items.length into itemCount: snapshot.length,
And Future builder to FutureBuilder<List<String>(...etc).
Will look like this in the end:
Widget build(BuildContext context) {
return Consumer<GeneralProvider>(
builder: (context, generalProvider, child) {
var items = generalProvider.myTeam;
return FutureBuilder<List<String>>(
future: items,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.length,
itemBuilder: (context, index) {
return ListTile(
// title: Text('${items[index].club}'),//This will likely throw an error also, because items is a List<String>, there is no method called "club" for Lists.
//Replace it with this to validate:
title: Text(snapshot[index]),//This
);
});
} else {
return Text('bad');
}
});
});
}

How to display list of data in application?

I have encountered an error where the data is printed out in terminal but do not display in the application.
Future<DocumentSnapshot> getTeacher() async {
var firebaseUser = await FirebaseAuth.instance.currentUser;
var docRef = FirebaseFirestore.instance.collection("User");
var query = docRef.where("type", isEqualTo: "teacher").limit(10);
query.get().then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
print(doc["name"]);
print(doc["email"]);
});
});
}
body: new FutureBuilder(
future: getTeacher(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return Row(
children: <Widget>[
Expanded(child: Text(snapshot.data["name"])),
Expanded(child: Text(snapshot.data["email"])),
Expanded(
child: IconButton(
icon: Icon(Icons.chat), onPressed: () {}))
],
);
});
}
return Container();
}),
this is the output in the terminal
Your getTeacher()-Function does not return your Future. Because of this
the Nullpointer-Exception ist thrown. You should return query.get() instead of listen to it.
You should also not call getTeacher() in the build-Function because it will be called at every build.
EDIT:
Your method:
Future<DocumentSnapshot> getTeacher() async {
var firebaseUser = await FirebaseAuth.instance.currentUser;
var docRef = FirebaseFirestore.instance.collection("User");
var query = docRef.where("type", isEqualTo: "teacher").limit(1);
return (await query.get()).docs[0];
}
Variable of your widget:
final Future<DocumentSnapshot> teacher = getTeacher();
Your FutureBuilder:
new FutureBuilder(
future: teacher,
builder: ...
)
You are not returning anything from future function. Please check below code
Future<List<DocumentSnapshot>> getTeacher() async {
var firebaseUser = await FirebaseAuth.instance.currentUser;
var docRef = FirebaseFirestore.instance.collection("users");
QuerySnapshot query =
await docRef.where("user_device_language", isEqualTo: "en").limit(10).get();
return query.docs;
}
And handle null value in list view like this
body: new FutureBuilder(
future: getTeacher(),
builder: (BuildContext context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data != null) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Row(
children: <Widget>[
Expanded(child: Text(snapshot.data[index]["name"])),
Expanded(child: Text(snapshot.data[index]["email"])),
Expanded(child: IconButton(icon: Icon(Icons.chat), onPressed: () {}))
],
);
});
} else {
return Text('No Data');
}
}
return Container();
},
),

Flutter Error: A value of type 'Future<bool>' can't be assigned to a variable of type 'bool' when get value form function Future<bool>

I met problem when get value form function Future
I have a function below
Future<bool> checkstr(String str) async {
bool result = await check(str);
if (result == null) {
return false;
} else {
return true;
}
}
when i get and check value met error
Expanded(
child: model.isBusy
? CircularProgressIndicator()
: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ListTile(
model.checkstr(str) //<------ error this line
? title: Text('true')
: title: Text('false'),
}),
),
error
Flutter Error: A value of type 'Future<bool>' can't be assigned to a variable of type 'bool'
please help me.
You'll have to use the FutureBuilder since checkstr() is a future
Expanded(
child: model.isBusy
? CircularProgressIndicator()
: ListView.builder(itemBuilder: (BuildContext context, int index) {
return FutureBuilder(
future: checkstr(str),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return CircularProgressIndicator();
return ListTile(
title: Text(snapshot.data ? 'true' : 'false'));
},
);
}));