import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
class HomePage extends StatefulWidget {
#override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
List items;
Future<String> getData() async {
var response = await http.get(
'https://api.torn.com/torn/?selections=items&key=7PnSA9HkVB5B6eAK');
this.setState(() {
Map items = json.decode(response.body);
print(items);
});
}
#override
void initState() {
this.getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: items == null ? 0 : items.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Text(items[index]['name']),
);
},
),
);
}
}
As far as i know we can get Json in two forms, first is List and second is a Map.
In my case i received a Map with all data i need but unfortunately i dont know how properly display that.
From print i received data but nothing happen on screen.
You must not re-define items. You need to set it. It will look like this:
setState(() {
items = jsonDecode(response.body);
print(items);
});
Check the setState inside your getData method, you are creating a new items variable instead of assigning the new value to it. Try this one.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class HomePage extends StatefulWidget {
#override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
Map items = {};
Future<void> getData() async {
http.Response res = await http.get(
"https://api.torn.com/torn/?selections=items&key=7PnSA9HkVB5B6eAK",
);
setState(() => items = jsonDecode(res.body)["items"]);
print(items);
}
#override
void initState() {
getData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
index++;
return Card(
child: Text(items[index.toString()]["name"] ?? "Empty"),
);
},
),
);
}
}
Related
I am trying to read a local json file named "catalog.json" I wrote all the nessessary codes but it's showing this error "lateinitializationError: Field 'catalogdata' has not been initialized."
then i tried by initializing the 'catalogdata' variable but then it shows that 'catalogdata' variable is empty . I dont know how to solve it . Please help me.
my code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
late List catalogdata;
Future<String> loadData() async {
var data = await rootBundle.loadString("assets/images/files/catalog.json");
setState(() {
catalogdata = json.decode(data);
});
return "success";
}
#override
void initState() {
// TODO: implement initState
this.loadData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Homepage"),
),
body: Center(
child: Text(
catalogdata[0],
style: TextStyle(fontSize: 20),
),
),
);
}
}
Here’s sample.json:
{
"items": [
{
"id": "p1",
"name": "Item 1",
"description": "Description 1"
},
{
"id": "p2",
"name": "Item 2",
"description": "Description 2"
},
{
"id": "p3",
"name": "Item 3",
"description": "Description 3"
}
]
}
The code which is used to fetch data from the JSON file (see the full code below):
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/sample.json');
final data = await json.decode(response);
// ...
}
Declare the json file in the assets section in your pubspec.yaml file:
flutter:
assets:
- assets/sample.json
main.dart
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List _items = [];
// Fetch content from the json file
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/sample.json');
final data = await json.decode(response);
setState(() {
_items = data["items"];
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text(
'Kindacode.com',
),
),
body: Padding(
padding: const EdgeInsets.all(25),
child: Column(
children: [
ElevatedButton(
child: const Text('Load Data'),
onPressed: readJson,
),
// Display the data loaded from sample.json
_items.isNotEmpty
? Expanded(
child: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return Card(
margin: const EdgeInsets.all(10),
child: ListTile(
leading: Text(_items[index]["id"]),
title: Text(_items[index]["name"]),
subtitle: Text(_items[index]["description"]),
),
);
},
),
)
: Container()
],
),
),
);
}
}
it's showing this error "lateinitializationError: Field 'catalogdata'
has not been initialized." then I tried by initializing the
'catalogdata'
While using late before variables make sure that, the variable must be initialized later. Otherwise, you can encounter a runtime error when the variable is used.
If you didn't add the correct location catalog.json in pubsec.yaml your variable catalog didn't gets the correct value so the late variable is not initialized.
So you must add asset path in pubsec.yaml
assets:
- assets/
- assets/images/files/catalog.json
Another case here is JSON.decode() return map<string,dynamic> value here you set list.maybe that also cause the problem and not initialised.
instead of this late List catalogdata; use this late var catalogdata; or late Map<string,dynamic> catalogdata;
Sample Code
Catalog.json
{
"name": "lava",
"Catagory": "man"
}
Main.dart
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class AppRoutes {
static String detail = "/Detail";
static String Page2 = "/FilterBeacon";
static String Page1 = "/FilterPoint";
static String home = "/";
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
// key: constItem.navigatorKey,
initialRoute: "/",
routes: {
AppRoutes.home: (context) => Home(),
},
title: _title,
// home: ,
);
}
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
State<Home> createState() => _HomeState();
}
var _index = 0;
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Homepage(),
);
}
}
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
late var catalogdata;
Future<String> loadDatas() async {
var data = await rootBundle.loadString("assets/images/files/catalog.json");
// setState(() {
catalogdata = json.decode(data);
// });
return "success";
}
Future<String> loadData() async {
var data = await rootBundle.loadString("assets/images/files/catalog.json");
setState(() {
catalogdata = json.decode(data);
});
return "success";
}
#override
void initState() {
loadData();
// loadData().then((value) => catalogdata=value);
} // String jsons = "";
// #override
// Future<void> initState() async {
// super.initState();
// await loadData();
// }
#override
Widget build(BuildContext context) {
var futureBuilder = FutureBuilder(
future: loadData(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(child: CircularProgressIndicator());
else if (snapshot.connectionState == ConnectionState.done)
return Center(
child: Text(
catalogdata.toString(),
style: TextStyle(),
),
);
else
return Container();
});
return Scaffold(
appBar: AppBar(
title: Text("Homepage"),
),
body: Center(
child: Text(
catalogdata.toString(),
style: TextStyle(),
),
),
);
}
}
Hi I tried calling the getContacts() function in both the initState and also the WidgetBuild method but I wont get any response whereas when I tried using the same function in Stateless widget main class and calling it inside the WidgetBuild method there it works.
class ContactsPage extends StatefulWidget {
#override
_ContactsPageState createState() => _ContactsPageState();
}
class _ContactsPageState extends State<ContactsPage>
with SingleTickerProviderStateMixin {
Query _ref;
bool isSearching = false;
get reference => null;
TabController _tabController;
Future<void> getContacts() async {
var client = http.Client();
String contacts_url =
'api url example';
String basicAuth = 'Basic auth example';
var response = await client.get(contacts_url,
headers: <String, String>{'authorization': basicAuth});
print(response.statusCode);
developer.log(response.body);
}
#override
Widget build(BuildContext context) {
getContacts();
return DefaultTabController(
length: 2,
..........
.......
I do not really understand what your intent is. If you want to use the value returned by getContacts in your build method, an option is to use a FutureBuilder. This will allow you to easily implement a control flow depending on the state of the Future. Find code below, I mocked the behavior of the getContacts method for the example.
class ContactsPage extends StatefulWidget {
#override
_ContactsPageState createState() => _ContactsPageState();
}
class _ContactsPageState extends State<ContactsPage> {
Future<List<String>> getContacts() {
return Future.value(['Contact A', 'Contact B', 'Contact C']);
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: getContacts(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
final contacts = snapshot.data as List<String>;
return ListView.builder(
itemCount: contacts.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text(contacts[index]));
},
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
Here is a complete code snippet that should demonstrate the issue that I am bumping into.
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
SystemChrome.setEnabledSystemUIOverlays([]);
runApp(
MaterialApp(
home: MyHomePage(),
),
);
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key,}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
Future<latestVersion> fetchAlbum() async {
final response = await http.get('https://api.jsonbin.io/b/5fd25941bef8b7699e57dce9');
if (response.statusCode == 200) {
print('yay');
return latestVersion.fromJson(jsonDecode(response.body));
} else {
print('nay');
throw Exception('Failed to load version');
}
}
class latestVersion {
final String title;
final String version;
latestVersion({this.version, this.title});
factory latestVersion.fromJson(Map<String, dynamic> json) {
return latestVersion(version: json['version'], title: json['title'],
);
}
}
class _MyHomePageState extends State<MyHomePage> {
static Future<latestVersion> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = fetchAlbum();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.yellow,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(''),
Text('CURRENT'),
Text('---------'),
Text('0.37'),
Text(''),
Text('LATEST'),
Text('--------'),
Text(latestVersion.version),
Text(''),
Text(''),
],
),
),
);
}
}
When trying to run this code, I get an error at line 76.
"instance member 'version' cannot be accessed using static access"
How exactly can I access this json-decoded variable? Thank you in advance. I'm new to working with asynchronous functions and Future and would appreciate any help that can be given.
The error means version is not a Static variable. So to access it like this LatestVersion.version either make version a static variable or
Replace
Text(LatestVersion.version),
with
Text(LatestVersion().version),
If everything else is correct in your code the above should work.
I am trying to use the response.body from a request made in network.dart in main.dart, but it does not seem to work here is my code
import 'package:http/http.dart'as http;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
class Network {
var data;
Future fetchData() async {
Map<String, String> headers = {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.acceptHeader: "application/json",
HttpHeaders.authorizationHeader: "Bearer $token",
};
http.Response response = await http.get (url),
headers: headers,
);
if (response.statusCode == 200) {
data = response.body;
return jsonDecode(data);
} else {
print('this is the ${response.statusCode}');
}
}
}
in the main.dart i am trying to print network.data but its null and when mapping json values i get all nulls what am i missing
Edit below i am assigning a var called body to to the result of the fetchdata in hte network but it does not seem to work when i print i run i get this "Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Future'"
import 'package:flutter/material.dart';
import 'package:foodicsclimamethod/networking.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Network network = Network();
String productName;
int productPrice;
String productData;
void updateUi() async {
Future<dynamic> body = await network.fetchData();
print(body);
}
#override
void initState() {
super.initState();
network.fetchData();
}
It looks like there is an issue with the updateUi method in your code sample. The body variable is typed as Future<dynamic>, however it should be dynamic because you are awaiting the fetchData method. If you wanted to, you could avoid specifying a type altogether and simply use final in order to infer the type. I have included a complete example below showing how this could all fit together:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class Network {
Future fetchData() async {
final headers = <String, String>{
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.acceptHeader: 'application/json',
HttpHeaders.authorizationHeader: 'Bearer $token',
};
final response = await http.get(url, headers: headers);
if (response.statusCode >= 200 && response.statusCode < 300) {
return json.decode(response.body);
} else {
throw Error();
}
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future _future;
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Text(snapshot.data.toString());
} else {
return CircularProgressIndicator();
}
},
),
);
}
#override
void initState() {
super.initState();
_future = Network().fetchData();
}
}
I have data in json format where one field subtitle has list of data again. How can I iterate through this list which already inside a list. here is the code.
#Data.json
[
{
"id":0,
"title":"Heading",
"subtitle":[
"sub1",
"sub2",
"sub3"
]
},
{
"id":1,
"title":"Heading1",
"subtitle":[
"sub4",
"sub5",
"sub6"
]
},
{
"id":2,
"title":"Heading2",
"subtitle":[
"sub7",
"sub8",
"sub9"
]
}
]
#list.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(new MaterialApp(
home: new HomePage()
));
}
class HomePage extends StatefulWidget {
#override
HomePageState createState() => new HomePageState();
}
class Location {
final String id;
final double lat;
final double long;
Location({this.id, this.lat, this.long});
}
class HomePageState extends State<HomePage> {
List data;
Future _future;
List<Location> locations;
Future<String> getData() async {
var response = await rootBundle.loadString('asset/sample.json');
this.setState(() {
data = jsonDecode(response);
});
for(var i=0; i< data.length; i++){
print( data[i]["subtitle"]);
}
return "Success!";
}
#override
void initState(){
this.getData();
}
#override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(title: new Text("Listviews"), backgroundColor: Colors.blue),
body: new ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index){
return new Card(
child: new Text(data[index]["title"]),
);
},
),
);
}
}
I want to list the items in subtitle. How can I do it?
You can do something like this with a column for example:
Column(children: [
for ( var subtitle in data[index]['subtitle'] ) Text(subtitle)
],
),