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
Related
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?
I have a login screen code like below that has a text button that changes the state of the Login button to Signup or reverse, and want to rewrite it to use GetX library. But I don't know how?
enum AuthMode { Signup, Login }
class AuthenticationScreen extends StatelessWidget {
const AuthenticationScreen({Key? key}) : super(key: key);
AuthMode _authMode = AuthMode.Login;
#override
Widget build(BuildContext context) {
final GlobalKey<FormState> _formKey = GlobalKey();
void _switchAuthMode() {
if (_authMode == AuthMode.Login) {
setState(() {
_authMode = AuthMode.Signup;
= });
_controller!.forward();
} else {
setState(() {
_authMode = AuthMode.Login;
});
_controller!.reverse();
}
}
return Scaffold(
body: Center(
child: Container(
constraints: const BoxConstraints(maxWidth: 400),
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
,
TextButton(
child: Text(
'${_authMode == AuthMode.Login ? 'SIGNUP' : 'LOGIN'} '),
onPressed: _switchAuthMode,
style: TextButton.styleFrom(
padding:
const EdgeInsets.symmetric(horizontal: 30.0, vertical: 4),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
textStyle: TextStyle(color: Theme.of(context).primaryColor),
),
],
),
),
),
);
}
}
I tried some changes like transferring Authmode to the auth_controller file that extends GetxController and add obs after AuthMode _authMode = AuthMode.Login; and try to use obx(()=>) inside the _switchAuthMode() but didn't work.
Try like this:
final authMode= Rx<AuthMode>(AuthMode.Login);
And then on your switchAuthMode method:
authMode.value = AuthMode.Signup; // without setState
And finally, wrap the Text widget with Obx:
Obx(()=> Text('${authMode.value == AuthMode.Login ? 'SIGNUP' : 'LOGIN'} ')
And you can actually make your widget a StatelessWidget.
I am trying to create an app which displays a dynamic FireStore List. I have made the List with a Future Builder, what I am trying to achieve is to add a Icon to every list of which the URL should be fetched from firesotre of the same documents Index. For Eg. Flipkart is a Document in FireStore it has a "images" field with the URL to Flipkart logo. I want the List View "leading" property to display this image by getting the URL from FireStore Database.
ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Card(
margin: EdgeInsets.fromLTRB(10, 2, 10, 2),
elevation: 3,
borderOnForeground: true,
child: ListTile(
title: Text(snapshot.data[index].data['title']),
subtitle: Text(snapshot.data[index].data['description']),
onTap: () => navigateToDetails(snapshot.data[index]),
),
);
});
The Code would go something like
ListTile(
leading: "Code Goes Here"
title: Text(snapshot.data[index].data['title']),
subtitle: Text(snapshot.data[index].data['description']),
Please share your valuable thoughts. I would like this to work, New to programming.
Full Code For FireStore Get Data:
class OfferScroll extends StatefulWidget {
#override
_OfferScrollState createState() => _OfferScrollState();
}
class _OfferScrollState extends State<OfferScroll> {
Future _data;
Future getOffers() async {
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore.collection('Offers').getDocuments();
return qn.documents;
}
navigateToDetails (DocumentSnapshot offers) {
Navigator.push(context, MaterialPageRoute(builder: (context) =>
OfferDetails(offers: offers,)));
}
#override
void initState() {
super.initState();
_data = getOffers();
}
#override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: _data,
builder: (_, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: AwesomeLoader(
loaderType: AwesomeLoader.AwesomeLoader3,
color: Colors.green[900],
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Card(
margin: EdgeInsets.fromLTRB(10, 2, 10, 2),
elevation: 3,
borderOnForeground: true,
child: ListTile(
title: Text(snapshot.data[index].data['title']),
subtitle: Text(snapshot.data[index].data['description']),
onTap: () => navigateToDetails(snapshot.data[index]),
),
);
});
}
}),
);
}
}
When you have the URL as a string in your FireStore you can retrieve the URL with someone like this: snapshot.data[index].data['imageFieldName'] and then you can give the return of this (the URL) to a NetworkImage to display the image.
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!! :)
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.