Format Exception, FutureBuilder dirty? 'Unexpected end of input (at character 1)'? - json

First time posting, I'm very new to coding, and I am trying to learn about loading local json into flutter.
I followed this tutorial https://www.youtube.com/watch?v=bTwTKwK3hGc to the letter and triple checked and cannot find any differences, and no errors show in the editor, but when I try to run the code I get a "FormatException" error.
The code:
import 'package:flutter/material.dart';
import 'dart:convert';
void main() => runApp(new MaterialApp(
theme: new ThemeData(
primarySwatch: Colors.teal,
),
home: new HomePage(),
));
class HomePage extends StatefulWidget {
#override
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
List data;
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Load Json Practice"),
),
body: new Container(
child: new Center(
child: new FutureBuilder(
future: DefaultAssetBundle
.of(context)
.loadString('load_json/stuff.json'),
builder: (context, snapshot) {
//decode json:
var mydata = jsonDecode(snapshot.data.toString());
return new ListView.builder(
itemBuilder: (BuildContext context, int index) {
return new Card(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Text("Name: " + mydata[index]['name']),
],
),
);
},
itemCount: mydata == null ? 0 : mydata.length,
);
},
),
),
),
);
}
}
My Json file:
[{
"id":1,
"name":"example"
}
]
My error:
════════ Exception caught by widgets library ═══════════════════════════════════
The following FormatException was thrown building FutureBuilder<String>(dirty, state: _FutureBuilderState<String>#07cf5):
Unexpected end of input (at character 1)
^
User-created ancestor of the error-causing widget was
Center
lib/main.dart:25
When the exception was thrown, this was the stack
#0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1392:5)
#1 _ChunkedJsonParser.close (dart:convert-patch/convert_patch.dart:510:7)
#2 _parseJson (dart:convert-patch/convert_patch.dart:30:10)
#3 JsonDecoder.convert (dart:convert/json.dart:493:36)
#4 JsonCodec.decode (dart:convert/json.dart:151:41)
...
I am still very bad at understanding errors I get, I have googled everything I can think of to try and solve this on my own and have no idea how to troubleshoot this problem further. Any help or suggestions would be appreciated. Thank you for your time.

I have test your code and your code is correct
Step 1 : please check json file directory, you can see picture 1
Step 2 : check pubspec.yaml setting (picture 2)
In pubspec.yaml, space and indent are important
Step 3 : check you json data, does it contains abnormal character (picture 3)
assets:
- load_json/

Related

NoSuchMethodError: The method '[]' was called on null - Flutter

I want to read data from this JSON in this way (PLEASE READ CODE COMMENTS):
class Profile extends StatefulWidget {
final id;
Profile({Key? key, #required this.id}) : super(key: key);
#override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
var data;
#override
void initState() {
super.initState();
void getData() async {
Response response = await get(
Uri.parse('https://en.gravatar.com/' + widget.id + '.json'));
this.data = json.decode(utf8.decode(response.bodyBytes));
// READ PLEASE >>> Data successfully is loaded from server & if you
// print this.data it will show full data in console <<< READ PLEASE
}
getData();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Profile | MWX Gravatar Viewer',
home: Scaffold(
appBar: AppBar(
title: Text('Profile | MGV'),
),
body: Center(
child: Column(
children: [
Text(this.data['entry'][0]['name']['familyName']), // Where raises error
],
),
),
),
);
}
}
And i get this error while rendering page:
The following NoSuchMethodError was thrown building Profile(dirty, state: _ProfileState#35267):
The method '[]' was called on null.
Receiver: null
Tried calling: []("entry")
NOTE: After a hot reload error is gone & I CAN SEE THE DATA I NEEDED ON SCREEN but every time when I want to load the page this error will be shown although I can see what I expected, after a hot reload
Your body might be running and not waiting for your getData() on initState. Try to check if it's null before using it:
body: Center(
child: Column(
children: [
Text(this.data != null ? this.data['entry'][0]['name']['familyName'] : 'no data'), // Where raises error
],
),
),
Or use a FutureBuilder.
This is because you are calling network request and at same time you are using data which is null by default so you can use either FutureBuilder() or handle error by null check

Flutter : Unable to fetch json file data from an api

Hello Everyone I am new to flutter during practicing While trying to fetch JSON data from an api I am unable to complete the operation and receiving the below mentioned error. I have attached my entire program and error notification for your suggestions.
What this program is about?
I am trying to fetch the cryptocurrency price details from an api and trying to display the few details of that website in my app. while doing that the data type which i mentioned in the code creating some error and i tried to change the data type and other things but still it is not solved.
main.dart
import 'package:flutter/material.dart';
import 'package:fluttercrypto/home_page.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
void main() async {
List currencies = await getCurrency();
print(currencies);
runApp(MyApp(currencies));
}
class MyApp extends StatelessWidget {
final List _currencies;
MyApp(this._currencies); // This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.red,
),
home: HomePage(_currencies),
);
}
}
Future<List> getCurrency() async {
String cryptoUrl =
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids";
http.Response response = await http.get(Uri.parse(cryptoUrl));
return jsonDecode(response.body);
}
'''
**homepage.dart**
'''import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
final List currencies;
HomePage(this.currencies);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List currencies;
final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Crypto Tracker"),
),
body: cryptoWidget(),
);
}
Widget cryptoWidget() {
return Container(
child: Column(
children: [
Flexible(
child: ListView.builder(
itemCount: widget.currencies.length,
itemBuilder: (BuildContext context, int index) {
final Map currency = widget.currencies[index];
final MaterialColor color = _colors[index % _colors.length];
return _getListItemUi(currency, color);
},
),
),
],
),
);
}
ListTile _getListItemUi(Map currency, MaterialColor color) {
return ListTile(
leading: CircleAvatar(
backgroundColor: color,
child: Text(currency['name'][0]),
),
title: Text(
currency['name'],
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: _getSubtitleText(
currency['current_price'], currency['price_change_24h']),
isThreeLine: true,
);
}
Widget _getSubtitleText(int priceUSD, String percentageChange) {
TextSpan priceTextWidget = new TextSpan(
text: "\$$priceUSD\n", style: TextStyle(color: Colors.black));
String percentageChangeText = "24 hour : $percentageChange%";
TextSpan percentageChangeTextWidget;
if (double.parse(percentageChange) > 0) {
percentageChangeTextWidget = TextSpan(
text: percentageChangeText,
style: TextStyle(color: Colors.green),
);
} else {
percentageChangeTextWidget = TextSpan(
text: percentageChangeText,
style: TextStyle(color: Colors.red),
);
}
return RichText(
text: TextSpan(children: [priceTextWidget, percentageChangeTextWidget]),
);
}
}'''
**ERROR**
'''
======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building:
type 'double' is not a subtype of type 'String'
When the exception was thrown, this was the stack:
#0 _HomePageState._getListItemUi (package:fluttercrypto/home_page.dart:54:46)
#1 _HomePageState.cryptoWidget.<anonymous closure> (package:fluttercrypto/home_page.dart:34:24)
#2 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:455:22)
#3 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1201:28)
#4 SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1214:55)
...
====================================================================================================
======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building:
type 'double' is not a subtype of type 'String'
When the exception was thrown, this was the stack:
#0 _HomePageState._getListItemUi (package:fluttercrypto/home_page.dart:54:46)
#1 _HomePageState.cryptoWidget.<anonymous closure> (package:fluttercrypto/home_page.dart:34:24)
#2 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:455:22)
#3 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1201:28)
#4 SliverMultiBoxAdaptorElement.performRebuild.processElement `enter code here`(package:flutter/src/widgets/sliver.dart:1145:67)
====================================================================================================
'''
It's probably because currency['price_change_24h'] isn't a string. When you pass it into _getSubtitleText do currency['price_change_24h'].toString().

convert data from a csv to a dynamic List (Flutter)

I create an app that loads the CSV file and displays it as a list view, I have used the following example. https://gist.github.com/Rahiche/9b4b2d3b5c24dddbbe662b58c5a2dcd2
The problem is that my List, don't generate rows
I/flutter ( 2158): [[M01, Plastics, 50, NA
I/flutter ( 2158): M02, Plastics, 85, NA
I/flutter ( 2158): M03, Wood, 50, NA
I/flutter ( 2158): M04, Wood, 15, 3
I/flutter ( 2158): M05, Plastics, 50, NA]]
Here is my code
class TableLayout extends StatefulWidget {
#override
_TableLayoutState createState() => _TableLayoutState();
}
class _TableLayoutState extends State<TableLayout> {
List<List<dynamic>> data = [];
loadAsset() async {
final myData = await rootBundle.loadString("assets/ford.csv");
List<List<dynamic>> csvTable = CsvToListConverter().convert(myData);
print(csvTable);
data = csvTable;
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
onPressed: () async {
await loadAsset();
//print(data);
}),
appBar: AppBar(
title: Text("Table Layout and CSV"),
),
body: SingleChildScrollView(
child: Table(
columnWidths: {
0: FixedColumnWidth(100.0),
1: FixedColumnWidth(200.0),
},
border: TableBorder.all(width: 1.0),
children: data.map((item) {
return TableRow(
children: item.map((row) {
return Container(
color:
row.toString().contains("NA") ? Colors.red : Colors.green,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
row.toString(),
style: TextStyle(fontSize: 20.0),
),
),
);
}).toList());
}).toList(),
),
),
);
}
}
and my ford.csv
M01,Plastics,50,NA
M02,Plastics,85,NA
M03,Wood,50,NA
M04,Wood,15,3
M05,Plastics,50,NA
---
i tried the hints from https://pub.dev/packages/csv#-readme-tab- and from
Not viewing Table Layout from a csv in flutter and I have read several csv files
but every time i have the same issues.
what am I doing wrong??
Please help a new flutter developer. ;)
You can copy paste run full code below
I add setState in function loadAsset()
I did not encounter column width issue, if you still have this issue, please try to add column 2 , 3 or shrink width of FixedColumnWidth
columnWidths: {
0: FixedColumnWidth(100.0),
1: FixedColumnWidth(100.0),
2: FixedColumnWidth(50.0),
},
code snippet
loadAsset() async {
final myData = await rootBundle.loadString("assets/ford.csv");
List<List<dynamic>> csvTable = CsvToListConverter().convert(myData);
print(csvTable);
data = csvTable;
setState(() {
});
}
working demo
animated gif did not show correct green color,
so I paste final result in second picture
full code
import 'package:flutter/material.dart';
import 'package:csv/csv.dart';
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: TableLayout(),
);
}
}
class TableLayout extends StatefulWidget {
#override
_TableLayoutState createState() => _TableLayoutState();
}
class _TableLayoutState extends State<TableLayout> {
List<List<dynamic>> data = [];
loadAsset() async {
final myData = await rootBundle.loadString("assets/ford.csv");
List<List<dynamic>> csvTable = CsvToListConverter().convert(myData);
print(csvTable);
data = csvTable;
setState(() {
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
onPressed: () async {
await loadAsset();
//print(data);
}),
appBar: AppBar(
title: Text("Table Layout and CSV"),
),
body: SingleChildScrollView(
child: Table(
columnWidths: {
0: FixedColumnWidth(100.0),
1: FixedColumnWidth(200.0),
},
border: TableBorder.all(width: 1.0),
children: data.map((item) {
return TableRow(
children: item.map((row) {
return Container(
color:
row.toString().contains("NA") ? Colors.red : Colors.green,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
row.toString(),
style: TextStyle(fontSize: 20.0),
),
),
);
}).toList());
}).toList(),
),
),
);
}
}
It's because of different EOL (END OF LINE) characters that are used to terminate a line in file. i.e Some program use '\r\n' while other '\n'.
So to solve the issue you have to consider that. i.e I am using csv package on window os and while reading from a csv file, you should specify eol argument to convert method of the CsvToListConverter().
return CsvToListConverter().convert(csv.data, eol: '\n');
The fast_csv parser is for parsing CSV data.
It is 2.9-4.7 times faster than the csv parser.
If you need to parse large amounts of data, then it will be more efficient.
Line endings are \n, \r\n or \r (no need to configure).
import 'package:fast_csv/fast_csv.dart' as _fast_csv;
void main(List<String> args) {
final res = _fast_csv.parse(_csv);
print(res);
}
final _csv = '''
M01,Plastics,50,NA
M02,Plastics,85,NA
M03,Wood,50,NA
M04,Wood,15,3
M05,Plastics,50,NA
''';
Output:
[[M01, Plastics, 50, NA], [M02, Plastics, 85, NA], [M03, Wood, 50, NA], [M04, Wood, 15, 3], [M05, Plastics, 50, NA]]

local JSON results are not shwoing - Flutter

I have a local JSON file that contains a list of words and I want to display the words in a list using flutter/Dart, for some reason the results are not displayed. All I get is a blank page along with this exception:
The following NoSuchMethodError was thrown building FutureBuilder(dirty, state:
I/flutter (25570): _FutureBuilderState#b10bc):
This is the code I am working with:
class _ListContentState extends State<ListContent> {
List<WordsDictionary> _words = List<WordsDictionary>();
Future<List<WordsDictionary>> _getWords() async{
var dictionaryData = await
DefaultAssetBundle.of(context).loadString('assets/json/dictionary.json');
var words = List<WordsDictionary>();
if(dictionaryData != null){
var jsonData = json.decode(dictionaryData);
for(var word in jsonData){
words.add(WordsDictionary.fromJson(word));
}
}else {
print('fail');
}
return words;
}
#override
void initState(){
_getWords().then((value) {
setState(() {
_words.addAll(value);
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return ListView.builder(
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(top: 6.0, bottom: 6.0, left: 8.0, right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(_words[index].wordEnglish,),
Spacer(),
Text(_words[index].wordGerman,),
],
),
),
);
},
itemCount: _words.length,
);
}
}
WordDictionary.dart :
class WordsDictionary {
int wordId;
String wordEnglish;
String wordGerman;
WordsDictionary(
this.wordId,
this.wordEnglish,
this.wordGerman
);
WordsDictionary.fromJson(Map<String, dynamic> json){
wordId = json['wordId'];
wordEnglish = json['englishWord'];
wordGerman = json['germanWord'];
}
}
Please wrap your list view with future builder
I slightly change your WordsDictionary class
example json
[
{
"wordId" : "1",
"wordEnglish" : "abc",
"wordGerman" : "def"
},
{
"wordId" : "2",
"wordEnglish" : "123",
"wordGerman" : "456"
}
]
the following is full working code
import 'package:flutter/material.dart';
import 'dart:convert';
void main() => runApp(MyApp());
// To parse this JSON data, do
//
// final wordsDictionary = wordsDictionaryFromJson(jsonString);
List<WordsDictionary> wordsDictionaryFromJson(String str) =>
List<WordsDictionary>.from(
json.decode(str).map((x) => WordsDictionary.fromJson(x)));
String wordsDictionaryToJson(List<WordsDictionary> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class WordsDictionary {
String wordId;
String wordEnglish;
String wordGerman;
WordsDictionary({
this.wordId,
this.wordEnglish,
this.wordGerman,
});
factory WordsDictionary.fromJson(Map<String, dynamic> json) =>
WordsDictionary(
wordId: json["wordId"],
wordEnglish: json["wordEnglish"],
wordGerman: json["wordGerman"],
);
Map<String, dynamic> toJson() => {
"wordId": wordId,
"wordEnglish": wordEnglish,
"wordGerman": wordGerman,
};
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: ListContent(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class ListContent extends StatefulWidget {
#override
_ListContentState createState() => _ListContentState();
}
class _ListContentState extends State<ListContent> {
List<WordsDictionary> _words = List<WordsDictionary>();
Future<List<WordsDictionary>> _getWords() async {
var dictionaryData = await DefaultAssetBundle.of(context)
.loadString('assets/json/dictionary.json');
var words = List<WordsDictionary>();
if (dictionaryData != null) {
words = wordsDictionaryFromJson(dictionaryData);
print("words lenght ${words.length}");
} else {
print('fail');
}
return words;
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
builder: (context, AsyncSnapshot<List<WordsDictionary>> wordSnap) {
switch (wordSnap.connectionState) {
case ConnectionState.none:
return new Text('none');
case ConnectionState.waiting:
return new Center(child: new CircularProgressIndicator());
case ConnectionState.active:
return new Text('');
case ConnectionState.done:
if (wordSnap.hasError) {
return new Text(
'${wordSnap.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: wordSnap.data.length,
itemBuilder: (context, index) {
WordsDictionary wordsDictionary = wordSnap.data[index];
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0, bottom: 6.0, left: 8.0, right: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
wordsDictionary.wordEnglish,
),
Spacer(),
Text(
wordsDictionary.wordGerman,
),
],
),
));
});
}
}
},
future: _getWords(),
);
}
}

Flutter JSON String/Int commands

I'm trying to make an app that retrieves data from this JSON list and parse this data to a listview.
With my code below, the first record I expect to see is ID, NAME and PRICE, but it appears that I can't retrieve the PRICE, because it's an int and I'm calling for a string from the JSON list.
Also, 'PRICE' is an int just like 'ID', as sam mentioned below, but 'ID' is fetched just fine whereas 'PRICE' just says 'NULL' in the list view
I don't know how to fix this, and hope I can get the answer I'm looking for on this platform.
FirstPage.dart :
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
home: StarWarsData(),
));
}
class StarWarsData extends StatefulWidget {
#override
StarWarsState createState() => StarWarsState();
}
class StarWarsState extends State<StarWarsData> {
final String url = "https://api.coinmarketcap.com/v2/ticker/";
List data;
Future<String> getSWData() async {
var res = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
setState(() {
var resBody = json.decode(res.body);
data = resBody["data"];
});
return "Success!";
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Cryp-Tick Crypto Exchange"),
centerTitle: true,
backgroundColor: Colors.black,
),
body: ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Card(
child: Container(
padding: EdgeInsets.all(15.0),
child: Row(
children: <Widget>[
Text("Id: "),
Text('${data[index]["id"]}',
style: TextStyle(
fontSize: 18.0, color: Colors.black87)),
],
)),
),
Card(
child: Container(
padding: EdgeInsets.all(15.0),
child: Row(
children: <Widget>[
Text("Name: "),
Text('${data[index]["name"]}',
style: TextStyle(
fontSize: 18.0, color: Colors.red)),
],
)),
),
Card(
child: Container(
padding: EdgeInsets.all(15.0),
child: Row(
children: <Widget>[
Text("Price: "),
Text('${data[index]["price"]}',
style: TextStyle(
fontSize: 18.0, color: Colors.black87)),
],
)),
),
],
),
),
);
},
),
);
}
#override
void initState() {
super.initState();
this.getSWData();
}
}
The error I receive in the Debug Console:
E/flutter (25480): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (25480): type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List' where
E/flutter (25480): _InternalLinkedHashMap is from dart:collection
E/flutter (25480): String is from dart:core
E/flutter (25480): List is from dart:core
I don't think the problem is what you think. You have your data typed as a List:
List data;
And you're populating it like this:
data = resBody["data"];
The error says:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List'
This suggests that resBody["data"]` is a map and not a list, and if you look at the JSON in the URL you're pulling, it starts like this:
{
"data": {
"1": {
That data object is not a list/array, it's a an object/map. You should change the type of your data variable to Map<String, dynamic> of convert the data to a List before storing it in the variable.
Edit after some comments
I was able to make this work by adding .values.toList() and stripping the JSON down to just the first two records:
However with all of the JSON from that url it seems to error. So, maybe something in the JSON is triggering a bug. Even more strangely, it seems to work fine in DartPad!