Exception has occurred. _TypeError (type 'int' is not a subtype of type 'double?') - casting

enter image description here price: snapshot.data!.docs[0]["price"],
it is repeatedly saying that the int type can't be assign to double
then i try by initializing the price num but it is not working still yet.. anybody can help me with this problem
FutureBuilder(
future: FirebaseFirestore.instance
.collection("products")
.doc("IXU9xbH0tAd0ITl8SFqj")
.collection("featureproduct")
.get(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
shirtData = product(
image: snapshot.data?.docs[0]["image"],
price: snapshot.data!.docs[0]["price"],
name: snapshot.data?.docs[0]["name"]);
print(shirtData?.name);

Related

How can I remove the icon when the validation is null in flutter?

I have a function that receives a list in the function parameter and I am displaying that list.
I have a validation in the Text, when it is null it shows me a message that says "no data" or otherwise it shows me the value of the list.
What I want to remove the cancel icon when it is null and only appear when I have a value to display.
Help would be greatly appreciated.
Code and Image ::
Widget SfuluilderSuggestions(List <SDM> historialMenuPrincipal){
return Container(
child:StatefulBuilder(
builder:(context,setState)
{
return Container(
child: ListView.builder(
itemCount: historialMenuPrincipal.length,
itemBuilder: (context,i)
{
contentPadding: EdgeInsets.symmetric(vertical: 12,horizontal: 16);
leading:CircleAvatar(
radius: 32,
backgroundImage: NetworkImage(
"https://2.bp.blogspot.com/-3ZzNt8ZjQk/WR9W4Fn4II/AAAAAAAJw/_inTVynhS6V75IZ-461-pda7WyrTStwCEw/s1600/A.jpg"),
);
return
ListTile(
title: Text(historialMenuPrincipal[i] == null ? "no data":historialMenuPrincipal[i].email ),
trailing: IconButton(
icon: Icon(Icons.cancel,color: Colors.black,),
onPressed: () {
setState(() {
historialMenuPrincipal.remove(historialMenuPrincipal[i]);
});
},
),
);
}
),
);
}
)
);
}
You can check if the text is null -
trailing: Text(historialMenuPrincipal[i] != null ? IconButton(
icon: Icon(Icons.cancel,color: Colors.black,),
onPressed: () {
setState(() {
historialMenuPrincipal.remove(historialMenuPrincipal[i]);
});
},
) : Padding(padding:EdgeInsets.zero),
While historialMenuPrincipal contains data, you can remove only when data is available. You can pass null on trailing.
trailing:
historialMenuPrincipal.contains(historialMenuPrincipal[i])
? IconButton(...)
: null
If you want to skip the generating ListTile, you can check on return level and provide SizedBox or better filter data while generating the list.

Error "The method 'call' was called on null" for generating a list

In my application I use the following code:
#override
Widget build(BuildContext context) {
List<double> listMax = List.from(data_snap()['history']);
final listMaxreversed = List.from(listMax.reversed);
final list_one_week = listMaxreversed.take(
data_snap()['history']['1w']);
final list_one_week_list = List.from(list_one_week);
final list_one_week_list_rev = List.from(list_one_week_list.reversed);
List<FlSpot> spots_one_week =
list_one_week_list_rev
.asMap()
.entries
.map((e) {
return FlSpot(e.key.toDouble(), e.value);
}).toList();
print(spots_one_week);
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.lightGreen),
backgroundColor: Colors.grey[100],
title: const Text('Details', style:
TextStyle(color: Colors.lightGreen)),
),
body: Padding(
//some code here...
Row(
children: [ _loading ? CircularProgressIndicator():
new Container(
child:
LineChart(
LineChartData(
lineTouchData: LineTouchData(enabled: true),
gridData: FlGridData(
show: false,
drawHorizontalLine: false,
drawVerticalLine: false,
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.black,
strokeWidth: 1,
);
},
),
lineBarsData: [
LineChartBarData(
spots: spots_one_week, //inserts the spots here
A brief moment I get the following error on my phone. After this moment the chart is displayed correctly.
The method 'call' was called on null.
Receiver: null
Tried calling: call()
I think I have to include something like an async task. The error occurs directly when I define listMax. How can I solve this?

Flutter 'map' Dynamic call of null. Receiver: Instance of '_Future<dynamic>' Arguments: [Instance of '(dynamic) => Builder']

i am trying to make a banner using this list which can be accessed with function "getBannerList" instead of having to manually write a list in this carousel
if i set items by manually putting a list at items: ['base64string','base64string','base64string'].map it will work fine but when i replace it with the function it causes this error
Error
The following NoSuchMethodError was thrown building MyApp(dirty, dependencies: [MediaQuery], state: _MyAppState#5a46f):
'map'
Dynamic call of null.
Receiver: Instance of '_Future<dynamic>'
Arguments: [Instance of '(dynamic) => Builder']
Code for carousel
Dependencies: carousel_slider: ^4.0.0
CarouselSlider(
options: CarouselOptions(
height: MediaQuery.of(context).size.height * 0.15,
autoPlay: true,
autoPlayInterval: Duration(seconds: 5),
initialPage: 0,
),
items: getBannerList().map((e) { // <---- if i replaced this with ['asdf','asdf,'asdf].map((e) it works fine
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
image: DecorationImage(image: MemoryImage(base64Decode(e.toString()))),
color: Colors.white,
),
);
},
);
}).toList(),
),
GetList Function
getBannerList() async{
dynamic data = await getDashBoardBannerData();
print(data);
return data;
}
returns (example of return cause base64 string is too long):
['base64imgstring','base64imgstring','base64imgstring']
getBannerList method returns Future<dynamic> not List :
1- change method signature to Future<List<String>> getBannerList() async{}
2- define a variable in your StatefullWidget called
late final Future<List> bannerList;
3- initialize you variable in init state
#override
void initState(){
bannerList = getBannerList();
}
4- now we should use FutureBuilder with our basserList
FutureBuilder<List<String>>(
future: bannerList, // your future data
builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
if (snapshot.hasData) {
return CarouselSlider(
options: CarouselOptions(
height: MediaQuery.of(context).size.height * 0.15,
autoPlay: true,
autoPlayInterval: Duration(seconds: 5),
initialPage: 0,
),
items: snapshot.data.map((e) {
return Builder(
builder: (BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
image: DecorationImage(image: MemoryImage(base64Decode(e.toString()))),
color: Colors.white,
),
);
},
);
}).toList(),
);
} else if (snapshot.hasError) {
return Text('Loading Error'); // error state
} else {
return CircularProgressIndicator(); // loading state
},
you should use explicit types for fewer bugs.

List is Empty (Flutter)

I am creating a List in Flutter and displaying it in a Column, When I Run it is just Empty and when I print the list it just prints an Array
I/flutter (24613): []
I am using this code to create the List:-
myFunction() {
return StreamBuilder(
stream:
users.orderBy('timestamp', descending: true).limit(30).snapshots(),
builder: (context, snapshot) {
List<UserList> usersList = [];
snapshot.data.documents.forEach((doc) {
User user = User.fromDocument(doc);
UserList userList = UserList(user);
usersList.add(userList);
});
return Column (children: usersList);
}
),
}
This is My User Class:-
class User {
final String id;
final String username;
final String email;
final String photoUrl;
User({
this.id,
this.username,
this.email,
this.photoUrl,
});
factory User.fromDocument(DocumentSnapshot doc) {
return User(
id: doc.data()['id'],
username: doc.data()['username'],
email: doc.data()['email'],
photoUrl: doc.data()['photoUrl'],
);
}
}
The Code Is Showing No Errors and the Column Is not Displaying, Also When I print The length of the List it Shows it is Zero:-
I/flutter (24613): 0
What Could be The problem ??
I guess we need to tweak some of your code little bit to make the logic working. :)
builder param should be specified with Type otherwise it will be of type dynamic. To be in safer side in this case it will be QuerySnapshot. So,
builder: (context, snapshot) in your code becomes
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot).
Next, there is no need of looping through foreach and instead you can try something like below.
snapshot.data.docs.map((document) { .... }
snapshot.data.documents in your code is not valid way of getting the Firestore Documents. Please refer official doc
And you need to return a widget from builder which you have done correctly. But, by mistake you are passing the List<UserList> to Column which will be expecting List<Widget>
return Column (children: usersList);
Here I can see you are passing usersList which is of type List<UserList>. So you can replace Column with ListView or similar kind of other widget since, Column doesn't support scroll.
So combining all these bits and pieces you will get the below snippet.
return StreamBuilder(
stream: FirebaseFirestore.instance
.collection('users')
.orderBy('timestamp', descending: true)
.limit(30)
.snapshots(), // Just for simplicity.
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
//When there is no data returned from the firebase.
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return ListView(
children: snapshot.data.docs.map((document) {
return Text("Title: " + document['username']);
}).toList(),
);
},
);
For simplicity, I have returned the Text widget. You can implement your own UI there.
NOTE : This is the basic working example and you need to fine tune accordingly like using model classes instead of directly accessing based on your requirements.
Your Code
myFunction() {
return StreamBuilder(
stream:
users.orderBy('timestamp', descending: true).limit(30).snapshots(),
builder: (context, snapshot) {
List<UserList> usersList = [];
snapshot.data.documents.forEach((doc) {
User user = User.fromDocument(doc);
UserList userList = UserList(user);
usersList.add(userList);
});
return Column (children: usersList);
}
),
}
It is because you have to await for the json to actually get parse to the dart model. Second thing is forEach method is synchronous it doesn't wait for the async operation to complete, this is the reason why your list is empty.
This SO question has lot of different ways to make a list work asynchronously in flutter.
Column shows data before fetching data, so it shows empty list. For this use setstate according to your state management type ("notifylisteners" in provider) after getting data, so by this the screen will be updated and column also shows the updated list.
I'm not very sure how you're handling the scope of the variable.
Here's my minimal reproducible code which can give you some idea on how to add the items to the list.
class MyPage extends StatefulWidget {
#override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
final List<Widget> _list = [FlutterLogo()];
#override
void initState() {
super.initState();
Timer.periodic(Duration(seconds: 1), (timer) {
if (timer.tick >= 2) timer.cancel();
setState(() => _list.add(FlutterLogo()));
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: _list),
);
}
}
As 'Ashutosh patole' said, 'forEach' method does not wait iteration's complete.
I think that because of this reason, although you made a 'usersList',
there is no data when build widget in 'usersList'.
To fix this, you'd better change from 'forEach' to 'for'.
void main() async {
List<String> data = [ 'a', 'b', 'c'];
List<String> result = [];
data.forEach((data) async {
await Future.delayed(Duration(seconds: 1));
result.add(data);
});
print(result);
await Future.delayed(Duration(seconds: 3));
print(result);
print('-----------------');
result = [];
for (var item in data) {
await Future.delayed(Duration(seconds: 1));
result.add(item);
}
print(result);
await Future.delayed(Duration(seconds: 3));
print(result);
}
In your code, you can change like below.
List<UserList> usersList = [];
for (var doc in snapshot.data.documents) {
User user = User.fromDocument(doc);
UserList userList = UserList(user);
usersList.add(userList);
}
Before calling the data, check all fields:
Firestore Docs
Add a print() to see where the problem
FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
//This
if (snapshot.hasError) {
return Text("Something went wrong");
}
print(snapshot.data);
//This
if (snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
print(snapshot.data);
//This
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
return Text("Full Name: ${data['full_name']} ${data['last_name']}");
}
return Text("loading");
},
);
This is what i typically use.Try out this! Please balance the brackets in the code
FutureBuilder(
future: users.orderBy('timestamp', descending: true).limit(30),
builder: (BuildContext context, AsyncSnapshot<List<User>> snapshot) {
List<User>ulist=snapshot.data;
return ListView.builder(
shrinkWrap: true,
padding: EdgeInsets.only(top: 25,bottom: 35),
itemCount: evlist==null?0:evlist.length,
itemBuilder: (BuildContext context, int index) {
String evtime=evlist[index].fromdate.substring(11,16);
String ontime=evlist[index].fromdate.substring(0,16);
return Container(
decoration: BoxDecoration(
border: Border.all(width: 1.8,color: Colors.indigo[900]),
borderRadius: BorderRadius.circular(12.0),
color: Colors.grey[200]
),
margin:
const EdgeInsets.symmetric(horizontal: 18.0, vertical: 4.0),
child: ListTile(
leading: Icon(Icons.notifications),
title: Text(ulist[index].username.toString()),
subtitle:Text("next data"),
),
);
},
);

Flutter ListView doesn't update on setState

My flutter ListView doesn't update when my setState runs in my State class.
Yes, My main class is a stateful widget, incase anyone was wondering
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => new _MyAppState();
}
My setState function
setState(() {
if (price == "null") {
items.add("Item ${counter + 1}: error");
print("null");
} else {
items.add("Item ${counter + 1}: $price");
print("$price");
totalPrice += price;
}
counter++;
});
});
Before I placed my ListView within a Container -> Column -> Expanded it was working fine. But after I added it, it stopped updating when my setState ran
body: new Container(
child: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
key: Key(item),
onDismissed: (direction) {
setState(() {
items.removeAt(index);
counter--;
});
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("$item deleted")));
},
background: Container(color: Colors.red),
child: ListTile(title: Text('$item')),
);
},
),
),
Could someone who is more knowledgeable in flutter educate me on what's going on here. I don't think adding the ListView into a container should make that much of a difference to how it works right?
Doing computations in setstate somehow caused this problem. Instead I did the computations in build since and I used setstate to only add to the list. It’ll then trigger the build and the rest of the things happen there. This solved my problem