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

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

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;

trying to make json request from worldtime api flutter

I am trying to make a JSON request from world time API by using future builder when I tried to get the data from my asset folder which contains JSON data it works properly but when I try to get the data from the internet it crashes
here as you can see
this the main class
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
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: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
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> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green,
body: FutureBuilder(
future:
get('http://api.worldweatheronline.com/premium/v1/weather.ashx?key=65dbd1979bd445e58aa171529203010&q=Europe/London&format=json&num_of_days=1'),
builder: (context, snapshot) {
var myData = json.decode(snapshot.data.toString());
String jsonsDataString = myData.body.toString(); // toString of Response's body is assigned to jsonDataString
jsonsDataString = jsonDecode(jsonsDataString);
if (myData == null){
return Center(
child: Text(
'Loading',
style: TextStyle(fontSize: 30, color: Colors.red),
),
);
}else{
return Center(
child: Text(
myData,
style: TextStyle(fontSize: 30, color: Colors.red),
),
);
}
}));
}
}
this the error when I try to run the app
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following FormatException was thrown building FutureBuilder<Response>(dirty, state: _FutureBuilderState<Response>#2a0b7):
Unexpected character (at character 1)
Instance of 'Response'
^
The relevant error-causing widget was:
FutureBuilder<Response> file:///F:/FlutterProjects/learn_json/lib/main.dart:54:15
When the exception was thrown, this was the stack:
#0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1394:5)
#1 _ChunkedJsonParser.parseNumber (dart:convert-patch/convert_patch.dart:1261:9)
#2 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:926:22)
#3 _parseJson (dart:convert-patch/convert_patch.dart:31:10)
#4 JsonDecoder.convert (dart:convert/json.dart:495:36)
...
your key is not working , check it using Postman , and you have to await for the response

Fetch Api Data Automatically with Interval in Flutter

On my flutter application I am trying to show updating data. I am successful in getting data from weather api manually. But I need to constantly grab data every 5 seconds. So it should be updated automatically. Here is my code in Flutter :
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sakarya Hava',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Sakarya Hava'),
),
body: Center(
child: FutureBuilder<SakaryaAir>(
future: getSakaryaAir(), //sets the getSakaryaAir method as the expected Future
builder: (context, snapshot) {
if (snapshot.hasData) { //checks if the response returns valid data
return Center(
child: Column(
children: <Widget>[
Text("${snapshot.data.temp}"), //displays the temperature
SizedBox(
height: 10.0,
),
Text(" - ${snapshot.data.humidity}"), //displays the humidity
],
),
);
} else if (snapshot.hasError) { //checks if the response throws an error
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
),
);
}
Future<SakaryaAir> getSakaryaAir() async {
String url = 'http://api.openweathermap.org/data/2.5/weather?id=740352&APPID=6ccf09034c9f8b587c47133a646f0e8a';
final response =
await http.get(url, headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
return SakaryaAir.fromJson(json.decode(response.body));
} else {
throw Exception('Failed to load post');
}
}
}
I found such a snippet to benefit from :
// runs every 5 second
Timer.periodic(new Duration(seconds: 5), (timer) {
debugPrint(timer.tick);
});
Probably I need to wrap and call FutureBuilder with this snippet but I was not able to understand how to do it.
Futures can have 2 states: completed or uncompleted. Futures cannot "progress", but Streams can, so for your use case Streams make more sense.
You can use them like this:
Stream.periodic(Duration(seconds: 5)).asyncMap((i) => getSakaryaAir())
periodic emits empty events every 5 seconds and we use asyncMap to map that event into another stream, which get us the data.
Here is working example:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class ExamplePage extends StatelessWidget {
Future<String> getSakaryaAir() async {
String url =
'https://www.random.org/integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new';
final response =
await http.get(url, headers: {"Accept": "application/json"});
return response.body;
}
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Stream.periodic(Duration(seconds: 5))
.asyncMap((i) => getSakaryaAir()), // i is null here (check periodic docs)
builder: (context, snapshot) => Text(snapshot.data.toString()), // builder should also handle the case when data is not fetched yet
);
}
}
You can refactor your FutureBuilder to use a Future variable instead of calling the method in the FutureBuilder. This would require you to use a StatefulWidget and you can set up the future in your initState and update it by calling setState.
So you have a future variable field like:
Future< SakaryaAir> _future;
So your initState would look like this :
#override
void initState() {
super.initState();
setUpTimedFetch();
}
where setUpTimedFetch is defined as
setUpTimedFetch() {
Timer.periodic(Duration(milliseconds: 5000), (timer) {
setState(() {
_future = getSakaryaAir();
});
});
}
Finally, your FutureBuilder will be changed to:
FutureBuilder<SakaryaAir>(
future: _future,
builder: (context, snapshot) {
//Rest of your code
}),
Here is a DartPad demo: https://dartpad.dev/2f937d27a9fffd8f59ccf08221b82be3

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/