Flutter : Unable to fetch json file data from an api - json

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().

Related

Flutter exception: Invalid image data using Image.memory()

I am trying to get image from MySQL and display using 'Image.memory' in flutter, but there is exception saying invalid image data:
E/FlutterJNI(12873): Failed to decode image
E/FlutterJNI(12873): android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.
E/FlutterJNI(12873): at android.graphics.ImageDecoder.nCreate(Native Method)
E/FlutterJNI(12873): at android.graphics.ImageDecoder.access$200(ImageDecoder.java:173)
E/FlutterJNI(12873): at android.graphics.ImageDecoder$ByteBufferSource.createImageDecoder(ImageDecoder.java:250)
E/FlutterJNI(12873): at android.graphics.ImageDecoder.decodeBitmapImpl(ImageDecoder.java:1862)
E/FlutterJNI(12873): at android.graphics.ImageDecoder.decodeBitmap(ImageDecoder.java:1855)
E/FlutterJNI(12873): at io.flutter.embedding.engine.FlutterJNI.decodeImage(FlutterJNI.java:431)
Reloaded 1 of 675 libraries in 750ms.
======== Exception caught by image resource service ================================================
The following _Exception was thrown resolving an image codec:
Exception: Invalid image data
Below is my main.dart, when I run the code, the screen shows invalid image data:
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'mysql.dart';
import 'dart:convert';
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(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter and Mysql Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
String title ='';
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
var db = new Mysql();
var ques = '';
void _getCustomer() {
db.getConnection().then((conn) {
String sql = 'select question from quiz where quizID =1;';
conn.query(sql).then((results) {
for(var row in results){
setState(() {
ques = row[0]; //<=Here
});
}
});
conn.close();
});
}
#override
Widget build(BuildContext context) {
Uint8List code=base64Decode(ques);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child:Image.memory(base64.decode('ques')),
),
/*Text(
'$ques',
),*/
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _getCustomer,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
This is the output:(https://i.stack.imgur.com/ca32r.png)
When I change the ques = row[0] to ques=row['question'].toString(), the output different and another exception comes out:
Invalid character (at character 1)
Has anyone run into the same problem? I would appreciate if you could help

_TypeError was thrown building FutureBuilder<dynamic>(dirty, state: _FutureBuilderState<dynamic> type 'Null' is not a subtype of type 'List<dynamic>'

#
I've been dealing with this problem for a long time.
I am trying to parse JSON and convert it into list view.
I am getting the response body and it is been converted to list also but its sending null to the future builder, I am getting this error:
#
Exception caught by widgets library =======================================================
The following _TypeError was thrown building FutureBuilder(dirty, state: _FutureBuilderState#a289a):
type 'Null' is not a subtype of type 'List'
The relevant error-causing widget was:
FutureBuilder<dynamic> file:///Users/metehanmacbook/StudioProjects/flutter_mysql/lib/main.dart:37:13
When the exception was thrown, this was the stack:
#0 _MyHomePageState.build.<anonymous closure> (package:flutter_mysql/main.dart:40:14)
#1 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:775:55)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4746:11)
...
**# Codes: #**
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
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 MySql',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.lime,
),
home: MyHomePage(title: 'Flutter MYSQL'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: Getmethod(),
builder: (BuildContext context, AsyncSnapshot snapshot){
List snap = snapshot.data;
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
if(snapshot.hasError){
return Center(
child: Text('error fatch'),
);
}
return ListView.builder(
itemCount: snap.length,
itemBuilder: (context, index){
return ListTile(
title: Text("Product Name: ${snap[index]['pro_name']}"),
subtitle: Text("Product Desc: ${snap[index]['pro_desc']}"),
);
}
);
},
),
);
}
Getmethod()async{
String theurl = ('http://10.0.2.2/flutter-demo/getdata.php');
var res = await http.get(Uri.parse(Uri.encodeFull(theurl)),headers: {"Accept":"application/json"});
var responseBody = json.decode(res.body);
print(responseBody);
return responseBody;
}
}
how can i solve this problem?
Seems like error is List snap = snapshot.data; snapshot.data is null, and you want to cast it to list.
Solutions:
You can make your snap variable as nullable: List? snap = snapshot.data;
You can return default value (empty list for example) if snap returns null: List snap = snapshot.data ?? [];
Investigate why your Getmethod returns null;

The method '[]' was called on null. Receiver: null T while accessing key:value pair in json

I am working on a mobile app related to vehicles. I have to create a form that should have several fields to be filled about a vehicle's info (like regNum, brand, model,type...).
In order to fetch the data for the dropdown button field I have to make http request(for type,brand,model).
I want whenever I change the vehicle brand in its corresponding dropdown, the vehicle model dropdown field to be updated only with models corresponding to the selected brand.
Here is my code:
#VehicleForm
class VehicleForm extends StatefulWidget {
final Future<VehicleTypes> types;
final Future<VehicleBrands> brands;
final Future<VehicleModels> models;
VehicleForm(this.types, this.brands, this.models);
#override
VehicleFormState createState() => VehicleFormState(types,brands,models);
}
class VehicleFormState extends State<VehicleForm>{
final Future<VehicleTypes> types;
final Future<VehicleBrands> brands;
final Future<VehicleModels> models;
String brandName;
VehicleFormState(this.types, this.brands, this.models);
void handleBrandChanged(String brand){
setState(() {
print(brand);
brandName=brand;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Vehicle')
),
body: Container(
child: Column(
children: [
Container(
margin: EdgeInsets.only(
top:20,
),
alignment: Alignment.center,
child:Text('General Info',
style: TextStyle(
fontSize: 22,
color:Colors.blue,
),
),
),
Container(
child: Column(
children: [
Container(
child: TextFormField(
decoration: const InputDecoration(
hintText: 'Registration number'
),
),
margin: EdgeInsets.all(10),
),
Container(
child: TextFormField(
decoration: const InputDecoration(
hintText: 'Vehicle km'
),
),
margin: EdgeInsets.all(10),
),
Container(
width:200,
child: VehicleTypeMenu(types),
),
Container(
width:200,
child: VehicleBrandMenu(brands,brandName,handleBrandChanged),
),
Container(
width:250,
child: brandName==null ? TextFormField(
decoration: const InputDecoration(
hintText: 'Vehicle Model'
),
): VehicleModelMenu(models,brandName),
),
VehicleYearDropdown(),
VehicleMonthDropdown(),
],
),
)
],
)
)
);
}
//VehicleBrand
class VehicleBrandMenu extends StatelessWidget{
final Future<VehicleBrands> brands;
final String brandName;
final ValueChanged<String> onChanged;
VehicleBrandMenu(this.brands,this.brandName,this.onChanged);
void handleBrandChanged(String brandName){
onChanged(brandName);
}
#override
Widget build(BuildContext context) {
return FutureBuilder<VehicleBrands>(
future: brands,
builder: (context,snapshot){
if(snapshot.hasData){
List<String> vehicleBrands = List<String>();
for(int i=snapshot.data.brands.length-1;i>=0;i--){
vehicleBrands.add(snapshot.data.brands[i]['name'].toString());
}
return DropdownButton<String>(
hint: Text("Select Vehicle Brand"),
value:brandName,
onChanged: handleBrandChanged,
items: vehicleBrands.map((String vehicleBrand){
return DropdownMenuItem(
value:vehicleBrand,
child: Row(
children: [
Text('$vehicleBrand')
],
),
);
}).toList(),
);
} else if(snapshot.hasError){
return Text('${snapshot.error}');
} else{
return TextFormField(
decoration: const InputDecoration(
hintText: 'Vehicle Model'
),
);
}
}
);
}
}
//VehicleModel(the problem occurs here)!
class VehicleModelMenu extends StatefulWidget{
final Future<VehicleModels> models;
final String brandName;
VehicleModelMenu(this.models,this.brandName);
#override
VehicleModelMenuState createState() => VehicleModelMenuState(models,brandName);
}
class VehicleModelMenuState extends State<VehicleModelMenu>{
final Future<VehicleModels> models;
final String brandName;
var firstItem;
VehicleModelMenuState(this.models,this.brandName);
#override
Widget build(BuildContext context) {
return FutureBuilder<VehicleModels>(
future: models,
builder: (context,snapshot){
if(snapshot.hasData){
print(brandName);
List<String> vehicleModels = List<String>();
for(int i=snapshot.data.models.length-1;i>=0;i--){ //The problem occurs in this loop
if(snapshot.data.models[i]['vehicleBrand']['name']==brandName){ //I check for equal brand
vehicleModels.add(snapshot.data.models[i]['name']); //I add only the needed models
}
}
return DropdownButton<String>(
hint: Text("Select Vehicle Model"),
value: firstItem,
onChanged: (String model) {
setState(() {
firstItem = model;
});
},
items: vehicleModels.map((String vehicleModel) {
return DropdownMenuItem(
value: vehicleModel,
child: Row(
children: [
Text('$vehicleModel')
],
),
);
}).toList(),
);
} else if(snapshot.hasError){
return Text('${snapshot.error}');
} else {
return CircularProgressIndicator();
}
}
);
}
}
Here is the data I want to fetch: I compare the ['vehicleBrand']['name']->brand property and add ['name']->model
enter image description here
Here is the actual error:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building FutureBuilder<VehicleModels>(dirty, state: _FutureBuilderState<VehicleModels>#5813d):
The method '[]' was called on null.
Receiver: null
Tried calling: []("name")
The relevant error-causing widget was:
FutureBuilder<VehicleModels> file:///D:/Android%20Apps/login_form/lib/vehicleFormElements/vehicleModel.dart:23:12
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 VehicleModelMenuState.build.<anonymous closure> (package:test_flutter_app/vehicleFormElements/vehicleModel.dart:30:59)
#2 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:751:55)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4744:28)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
Here is the deserialisation to object
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
class VehicleModels {
final List<dynamic> models;
VehicleModels({this.models});
factory VehicleModels.fromJson(Map<String,dynamic> json){
return VehicleModels(
models: json['data']['results'],
);
}
}
Future<VehicleModels> getVehicleModels(String cookie)async{
final http.Response response = await http.get(
'https://gara6.bg/auto-api/vehicleModels?pageSize=2147483647',
headers: <String, String>{
'Content-Type': 'application/json',
'cookie':cookie,
},
);
if(response.statusCode==200){
return VehicleModels.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
}
else{
throw Exception('Failed to retrieve vehicle models');
}
}
If any entry in your JSON is missing vehicleBrand you will get that null error.
Since you're accessing nested JSON data (i.e. Map class) directly, you have to check each nested level actually has data or else you can get a null error trying to access a value when the object is null.
So this:
if (snapshot.data.models[i]['vehicleBrand']['name']==brandName) {
// do something
}
should be something like this:
if (snapshot.data.models[i] != null && snapshot.data.models[i]['vehicleBrand'] != null && snapshot.data.models[i]['vehicleBrand']['name'] == brandName) {
// do something
}
In general, directly accessing JSON data like this is unsafe, repetitive and verbose. It would probably be better to convert your JSON data into objects (i.e. deserialize) where you can get the benefits of Type-safety (properties are the type you're expecting) & can create methods/getters that produce safe/sane values so you don't get null errors when data isn't perfect.
Check out the Flutter article on serialization for more info.

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]]

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

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/