Another exception was thrown: NoSuchMethodError: The method '[]' was called on null - flutter

var wfa_res = await CallApi().getData('waiting_for_approval/waiting_approval_list/'+widget.username+'/'+'0/requisition');
var wfa_res_body = json.decode(wfa_res.body);
in widget
for(var my_index = 0; my_index < wfa_res_body.length; my_index++)
Container(
padding: EdgeInsetsDirectional.fromSTEB(5,5,5,5),
// child: Text('design'),
child: Text(approvalInfo != null?approvalInfo['page_data'][my_index]['requisition_code']:''),
),
error
Another exception was thrown: NoSuchMethodError: The method '[]' was called on null.

Problem is that your widget is getting build before async method is completed.
Try using future builder e.g.
Your method :
Future yourMethodName() async {
var wfa_res = await CallApi().getData('waiting_for_approval/waiting_approval_list/'+widget.username+'/'+'0/requisition');
var wfa_res_body = json.decode(wfa_res.body);
return wfa_res_body;
}
Future Builder :
FutureBuilder(
future: yourMethodName(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Center(child: CircularProgressIndicator());
}
// after getting data from api
},
);

I fixed the problem. Actually the api response was too slow. right now i set a loader. and working fine. Thanks to all for answer.

Related

FutureBuilder update by timer

I don't quite understand how you can update future in FutureBuilder by timer. I tried to create a timer and give it to the future, but it didn't work out and there was an error: type '_Timer' is not a subtype of the 'Future?'
my handler with a request:
Future<ObjectStateInfoModel> read(int id) async {
TransportResponse response = await transport.request(
'get',
RequestConfig(path: path + '($id)'),
TransportConfig(
headers: {},
));
ObjectStateInfoModel objectState = ObjectStateInfoModel.fromJson(response.data);
return objectState;
}
my FutureBuilder:
return FutureBuilder<ObjectStateInfoModel>(
future: logexpertClient.objectsState.read(object.id),
builder: (context, snapshot) {
if (snapshot.hasData) {
final data = snapshot.data!;
on the advice of one of the commentators i converted FutureBuilder to StreamBuilder and created such a stream and then everything works correctly:
stream = Stream.periodic(const Duration(seconds: 5)).asyncMap((_) async {
return logexpertClient.objectsState.read(object.id);
});
Use refreshable_widget, which is built specifically for this.
https://pub.dev/packages/refreshable_widget
Flexible(
child: RefreshableWidget<num>(
initialValue: challenge.userParticipation!.donePercent,
refreshCall: () async {
final challenge =
await cadoo.getChallengeDetail(
id: widget.challengeId,
);
return challenge.userParticipation!.donePercent;
},
builder: (context, value) {
return DonePercentWidget(
percent: value,
);
},
),
),
Pass a refresh call and how often you want to refresh, widget will build whatever on builder method.

Flutter, "The method 'map' can't be unconditionally invoked because the receiver can be 'null'."

I am getting this error when I am trying to call the .map method on the snapshot.data. I am using an SQLite database.
The code throwing the error is the following:
FutureBuilder(
future: _alarms,
builder: (context, snapshot)
{
if(snapshot.hasData){
return ListView(
children: snapshot.data.map<Widget>((alarms) {
return Container(
And I am creating the _alarms list in the initState method:
#override
void initState() {
_alarmHelper.initializeDatabase().then((value) => print('------------dB initialized'));
_alarms = _alarmHelper.getAlarm();
super.initState();
}
And the .getAlarm(), is defined so:
Future<List<AlarmInfo>> getAlarm() async{
var result;
var db = await this.database;
result = await db?.query(tableName);
result.forEach((element) {
var alarmInfo = AlarmInfo.fromMap(element);
alarms.add(alarmInfo);
}
);
return alarms;
}
I have also tried adding a ?. operator, but then this returns another error which is the .map is not defined for the type object children: snapshot.data?.map<Widget>((alarms) {
Any help is appreciated and if you require any further information feel free to leave a comment.
Thanks :)
I assume it's because you didn't provide a type for the FutureBuilder widget, therefore snapshot.data is from type Object (instead of a list you are expecting there) and the map function does not exist for that.
It should be fixed by writing it like this:
FutureBuilder<List<AlarmInfo>>(
...
),
Additionally since data might be null (but you checked it with snapshot.hasData you have to write:
snapshot.data!.map(...)

LateInitializationError: Field has not been initialized.' .then() command not running after running firebase query in FutureBuilder

I am trying to retrieve a Firestore Snapshot and my code doesn't seem to be working. I made sure fireUser.uid was working, and it printed the right ID but strangely my .then() code isn't running at all I put print('then') in it and isn't appearing on my console
this is where the error is occurring:
FutureBuilder(
future: Future.wait([
DatabaseService.getUserDataFromFirestore(FirebaseAuth.instance.currentUser!),
GeoService.getPosition(),
]),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.done) {
return Frame();
}
else return Container(
color: Colors.black,
child: Center(
child: spinKit,
),
);
}
);
Future with error:
static Future<Userdata> getUserDataFromFirestore (User fireUser) async {
await usersRef.doc(fireUser.uid).get().then((val) {
print('then');
userdata = Userdata.fromDoc(val);
});
return userdata;
}
error message:
LateInitializationError: Field 'userdata' has not been initialized.
I had a different problem then I thought. Firestore must have been updated because the rules of my Firestore database kept me locked out so I updated the rules and now my code works fine. Thanks so much for the help

Creating Stream for StreamBuilder with Firestore

I'm have created a Stream that it working inside StreamBuilder, but I have to pass some parameters to my Stream, this parameters are in a dart file which only has functions. I'm attempting to create the same code that was working, but passing the user uid.
This is what I attempted:
Stream<QuerySnapshot> main_page_stream() async*{
final FirebaseUser user = await _auth.currentUser();
Stream stream = Firestore.instance.collection('user_data').
document(user.uid).collection('Buttons').snapshots();
await for(var event in stream) {
yield event.documents;
}
}
I get the following error:
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: Class 'QuerySnapshot' has no instance getter 'snapshot'.
Receiver: Instance of 'QuerySnapshot'
Tried calling: snapshot)
This isn't working on the home page:
StreamBuilder(
stream: _auth.main_page_stream(),
builder: (context, snapshot) {
if (snapshot.hasError){
return Container(color: Colors.red);
}
if (!snapshot.hasData){
print(snapshot.data);
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasData){
var screenSize = MediaQuery.of(context).size.width;
return Stack(
children: [
this was working:
stream: Firestore.instance.collection('user_data').document('sdsajnd82173812').collection('Buttons').snapshots(),
The QuerySnapshot - event doesn't have a field snapshot. Instead you have to
yield event;
And for this the function return you the Stream<QuerySnapshot>.

Different type error when trying to access BLoC data in StreamBuilder

I'm trying to implementing Bloc on Flutter and i just learn about this feature and i get error:
Error:
Another exception was thrown: type 'Future' is not a subtype of type 'Stream'
my server return this structure and i want to get that with bloc and rxDart, for example:
[
"active"=> 1,
"name"=> "MY NAME",
"avatar"=> "http://www.sample.com/avatar.png",
...
]
my implemented Repository class :
class Repository {
final userInformation = InstagramApiProviders();
Future<UserInfo> userInfo() => userInformation.checkUserLogin();
}
LoginBlock class
class LoginBlock{
final _repository = Repository();
final _login_fetcher = PublishSubject<UserInfo>();
Observable<UserInfo> get login=>_login_fetcher.stream;
fetchLogin() async{
UserInfo userInfo = await _repository.userInfo();
_login_fetcher.sink.add(userInfo);
}
dispose(){
_login_fetcher.close();
}
}
final bloc = LoginBlock();
click on button on view implementation:
onPressed: () {
setState(() {
if (_checkLoginInstagram()) {
StreamBuilder(
stream: bloc.fetchLogin(),
builder: (context,
AsyncSnapshot<UserInfo>
snapshot) {
if (snapshot.hasData) {
parseResponse(snapshot);
}
},
);
}
});
},
parseResponse method:
void parseResponse(AsyncSnapshot<UserInfo> snapshot) {
debugPrint(snapshot.data.avatar);
}
You are providing a Future object instead a stream to stream property of your StreamBuilder.
//...
StreamBuilder(
stream: bloc.fetchLogin(), // THIS LINE IS WRONG
As your fetchLogin is an async function by default async methods returns always a Future object in your case Future<void>. You should replace the wrong line by:
//...
StreamBuilder(
stream: bloc.login,
And make fetchLogin() call in onPress callback and you don't need setState calls. I cant get it why you have a setState call there...