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

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.

Related

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 property values of a Map all treated as strings

I have a list like this a = [{'one': 'one', 'two': null, 'three': [{'four': 'four'}]}]
I send it to a function to use it in a post request which in the body should receive a Map, so what I did was this to a[0], the problem is that I get this error The getter 'length' was called on null
I start to review and it treats all the property values as if they were Strings, even the nested list 'three': [{'four': 'four'}], I have tried to send the post in this way http.post (url, body: (recurrence [0] as Map)) but it has not worked, it always gives me the same error, even if in the body I put the properties by hand in the body: {'new property': a [0] [' tres']}, how should one act to solve this problem? Thank you very much for your help
Code:
void _ordersGet() async {
await http.get(url).then((value) {
setState(() {
orders = jsonDecode(value.body);
}
}
orders is sent to a new widget: orderList(orders)
orderList is a listView
ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: orders.length,
itemBuilder: (orders, index) {
return return Card(
elevation: 5,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(orders[index]['facts']),
SizedBox(
width: 4,
),
Text('Cantidad : '),
Text(orders[index]['ITEMS'][0]['jeans']),
SizedBox(
width: 4,
),
IconButton(
onPressed: () => _reorderData(context, orders[index]),
icon: Icon(
Icons.replay_outlined,
color: Theme.of(context).accentColor,
)),
],
),
);
},
);
_reorderData is a function that make a get request, the info in shipped to ReorderModal
ReorderModal it only shows the information and has a button
void _reorderData(BuildContext ctx, order) async {
var data;
var url = 'serverAddress/${order['facts']}';
await http.get(url).then((value) {
data = jsonDecode(value.body);
data[0]['CORPORATION'] = order['corporation'];
showModalBottomSheet(
context: ctx,
builder: (_) {
return ReorderModal(data);
});
}).catchError((onError) {});
}
class ReorderModal extends StatelessWidget {
final List data;
ReorderModal(this.data);
void orderSend(orderInfo) async {
var url = 'serverAddress';
await http.post(url, body: orderInfo[0]).then((value) {
print(jsonDecode(value.body));
}).catchError((onError) {
print(onError);
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: Column(children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Column(
children: [
ElevatedButton(
onPressed: () {
orderSend(data);
//print(data);
},
child: Text('ONE Click'))
]),
);
}
}
when i press the ONE Click button execute the function orderSend, orderSend make a post request and the problem described above
This is the simplified code, I know it must be something very simple, but it is giving me a lot of work to solve

Is there a way to test a Dart program as unchecked (production) mode?

Some of my classes uses assert() to make development easier.
The problem is that those asserts are ignored in production mode, so I need a way to write tests for times when those assertions fail (when they throw assertionErrors).
main() {
// test if the assertion is being throw correctly
test('null emailStr assertion', () {
expect(() => Email(emailStr: null), throwsAssertionError);
});
// here I want to test how it would behave in prod mode
// when the asserts are ignored.
// This way it'll just throw an assertion error
test('null emailStr emailStr value', () {
final Email email = Email(emailStr: null);
expect(email.isValid, false);
});
}
I wonder if there's something like this to run tests as if we were in production mode:
setUp(isCheckedMode = false)
I found in google that the only way to message someone in stack is to write a comment in his question.
However, my code of another class (MessageBubble) is:
class MessageBubble extends StatelessWidget {
final String messsage;
final userID;
final bool isMe;
final Key key;
MessageBubble(this.messsage,this.userID, this.isMe,this.key);
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: isMe? MainAxisAlignment.start: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: isMe? Colors.grey[300]: nave,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: !isMe ? Radius.circular(12) : Radius.circular(0),
bottomRight: isMe ? Radius.circular(12) : Radius.circular(0),
),
),
width: 140,
padding: EdgeInsets.symmetric(vertical: 10,horizontal: 16),
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: Column(
children: [
Column(
children: [
FutureBuilder(
future: FirebaseFirestore.instance.collection('users').doc(userID).get(),
builder: (context, snapshot) {
if(snapshot.connectionState== ConnectionState.waiting){
return Text('جاري التحميل...');}
return Text(snapshot.data['username'], style: TextStyle(fontWeight: FontWeight.bold),);
}
),
],
),
Text(messsage, style: TextStyle(color: isMe? white : Colors.black,),),
],
) ,
),
],
);
}
}
my code in main:
home:
StreamBuilder(stream: FirebaseAuth.instance.authStateChanges(), builder: (ctx, userSnapshot) {
if (userSnapshot.hasData) {
return ChatPage();
}
return FirstPage();
}),

From Future<List<String>> to List<String> for API calls to use in regular functions/scaffold

I'm using the TMDb API to get image urls to display. I am able to get the image urls and display them on the console. But then when I try to create a method and loop through for each of the items in the list it keeps returning empty (i checked with print).
Edit: Both methods are inside the same class and literally right below each other.
Any help will be appreciated!
List<String> popularMovie = List<String>();
#override
void initState() {
super.initState();
this.getJsonData();
}
//GET POPULAR MOVIE INFO WITH API
Future<List> getJsonData() async {
http.Response response = await http.get(
Uri.encodeFull(popularURL),
headers: {
'Accept': 'application/json'
}
);
var popularMovieData = json.decode(response.body);
var placeholder = popularMovieData['results'];
//get a list of images only
for(var item in placeholder) {
popularMovie.add(item['poster_path']);
}
print(popularMovie.length); //20
print(popularMovie); //prints [imgURL, imageURL, ...]
return popularMovie;
} //end of popular movie api function
Below is the method that is suppose to loop through list items
//method to iterate through each item and get the image url to display image
List<Widget> popularMovies() {
List<Widget> popularMovieList = new List();
for(var item in popularMovie) { //this is empty
var popularMovieItem = Padding(
padding: EdgeInsets.all(10),
child: Container(
width: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.4),
spreadRadius: 4,
blurRadius: 4,
),
]
),
child: Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height/2 - 20,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15),),
image: DecorationImage(
image: NetworkImage('https://image.tmdb.org/t/p/w500${item}'),
fit: BoxFit.fill,
)
),
),
],
),
],
),
),
);
popularMovieList.add(popularMovieItem);
}
return popularMovieList;
}
And finally, I'd like to display all the movies on my page as
children:popularMovies(),
Since getJsonData is an async function, you need to use a FutureBuider or else instead of returning popularMovie you need to call setState
FutureBuilder<String>(
future: getJsonData,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Press button to start.');
case ConnectionState.active:
case ConnectionState.waiting:
return Text('Awaiting result...');
case ConnectionState.done:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
return Text('Result: ${snapshot.data}');
}
return null; // unreachable
},
)
I finally figured it out! It is super easy with setState so if anyone needs a solution to convert a
Future<List<String>> to List<String> and then use it as a normal List inside the scaffold here's what I did:
First, declare your list variable:
List<String> popularMovie = List<String>(); //declare a list inside the class
Then do your http call and assign the 'list of items you want' to your previously declared list variable 'inside setState'
#override
void initState() {
super.initState();
this.getJsonData();
}
//GET POPULAR MOVIE INFO WITH API
Future<List<String>> getJsonData() async {
http.Response response = await http.get(
Uri.encodeFull(popularURL),
headers: {
'Accept': 'application/json'
}
);
setState(() { //only get the first 10 movie images
var popularMovieData = json.decode(response.body);
for (int i = 0; i < 10; i++) {
popularMovie.add(popularMovieData['results'][i]['poster_path']);
}
print(popularMovie);
});
} //end of popular movie api function
Then I created a method to create a widget to display each image which is the same as the method I created in my original post that starts like this:
List<Widget> popularMovies() {
And finally, I wanted to display it this way(which you can do however you want to):
Padding(
padding: EdgeInsets.only(left: 10, top: 10, bottom: 10),
child: Container(
height: MediaQuery.of(context).size.height/2,
child: ListView(
scrollDirection: Axis.horizontal,
children: popularMovies(), //display all images in a horizontal row
),
),
),
And you're done!! :)

Flutter return Firestore array values to a List

I am using Flutter table calendar plugin to make a calendar. In order to put events into the calendar, I have to add data to _events map. I want to get the data from Firestore document, and put the data into _events map. However, I don't know how to do it. I search everywhere but I can't get an answer.
This is my code
class _MemberEventsState extends State<MemberEvents>
with TickerProviderStateMixin {
Map<DateTime, List> _events;
List _selectedEvents;
AnimationController _animationController;
CalendarController _calendarController;
List<String> list = List();
#override
void initState() {
super.initState();
final _selectedDay = DateTime.now();
Firestore.instance
.collection('events')
.document('2019-07-30')
.get()
.then((DocumentSnapshot ds) {
list = List.from(ds['title']);
});
_events = {DateTime.parse("2019-08-01"): list};
_selectedEvents = _events[_selectedDay] ?? [];
_calendarController = CalendarController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
_animationController.forward();
}
#override
void dispose() {
_animationController.dispose();
_calendarController.dispose();
super.dispose();
}
void _onDaySelected(DateTime day, List events) {
print('CALLBACK: _onDaySelected');
setState(() {
_selectedEvents = events;
});
}
void _onVisibleDaysChanged(
DateTime first, DateTime last, CalendarFormat format) {
print('CALLBACK: _onVisibleDaysChanged');
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
_buildTableCalendar(),
const SizedBox(height: 8.0),
const SizedBox(height: 8.0),
Expanded(child: _buildEventList()),
],
),
);
}
Widget _buildTableCalendar() {
return TableCalendar(
calendarController: _calendarController,
events: _events,
startingDayOfWeek: StartingDayOfWeek.sunday,
calendarStyle: CalendarStyle(
selectedColor: Colors.deepOrange[400],
todayColor: Colors.blueAccent[200],
markersColor: Colors.brown[700],
outsideDaysVisible: false,
),
headerStyle: HeaderStyle(
formatButtonTextStyle:
TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
formatButtonDecoration: BoxDecoration(
color: Colors.deepOrange[400],
borderRadius: BorderRadius.circular(16.0),
),
),
onDaySelected: _onDaySelected,
onVisibleDaysChanged: _onVisibleDaysChanged,
);
}
Widget _buildEventList() {
return ListView(
children: _selectedEvents
.map((event) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.8),
borderRadius: BorderRadius.circular(12.0),
),
margin:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: ListTile(
title: Text(event.toString()),
),
))
.toList(),
);
}
}
So in the first step to achieve my goal, I made a document named 2019-07-30, then I made an array in it named title. Then I tried to get the values in the array to a List named list. However, list returned null.
I don't know where I went wrong.
I am new to Flutter, so the question might seem stupid.
Also, I am new to stackoverflow, so if I did any steps wrong on describing the question, please tell me so I can fix it.