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(),
),
),
);
}
}
Related
Hi I have json containing almost 30 items I just waan display only 10 itmes in listview and on every time I refresh page should change (in other words random items) should be selected from the json.
Is ther any way and would be great If someone can show with example.
Thanks
Put json file in a folder called assets:
Image
Add this to pubspec.yaml:
assets:
- assets/
Image
main.dart file:
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List items = [];
int itemCount = 2;
Future<void> readJson() async {
final String response = await rootBundle.loadString('assets/items.json');
final data = await json.decode(response);
setState(() {
items = data["items"];
});
}
#override
void initState() {
super.initState();
readJson();
}
String randomItem() {
int random = Random().nextInt(items.length);
print(random);
String item = items[random]["item"];
List newItems = [];
for(int i = 0; i < items.length; i++){
if(item != items[i]["item"]){
newItems.add(items[i]);
}
}
items = [...newItems];
return item;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Title"),
),
body:
items.isNotEmpty ? Center(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: itemCount,
itemBuilder: (context, index) => Column(
children: [
Text(randomItem()),
],
),
),
): const Text("Loading..."),
);
}
}
Json file:
{
"items": [
{
"item": "One"
},
{
"item": "Two"
},
{
"item": "Three"
}
]
}
This picks two random items which are strings from the json file.
The itemCount variable can't be longer than the number of items in the json file. Change it to 10 if you want 10 different items.
I have a problem with parsed JSON in Flutter-Dart. Actually, there is no problem, but there is a method which I don't know. I'm getting data from a PHP server and I'm writing to listview from parsed JSON. However, I don't want to write to a listview, I just want to get data from the parsed JSON because I will set an another textview from parsed json data which I get.
This is my code.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response =
await client.get(Uri.parse('https://meshcurrent.online/get_20word.php'));
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parsePhotos, response.body);
}
// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
class Photo {
final String questId;
final String quest;
final String ans1;
final String ans2;
final String ans3;
final String ans4;
final String correctAns;
final String category;
const Photo({
required this.questId,
required this.quest,
required this.ans1,
required this.ans2,
required this.ans3,
required this.ans4,
required this.correctAns,
required this.category,
});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
questId: json['questId'] as String,
quest: json['quest'] as String,
ans1: json['ans1'] as String,
ans2: json['ans2'] as String,
ans3: json['ans3'] as String,
ans4: json['ans4'] as String,
correctAns: json['correctAns'] as String,
category: json['category'] as String,
);
}
}
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
const appTitle = 'Isolate Demo';
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Column(children: [
Text("ronalddo"),
Text("mecsfsi"),
FutureBuilder<List<Photo>>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text('An error has occurred!'),
);
} else if (snapshot.hasData) {
return PhotosList(photos: snapshot.data!);
} else {
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
]));
}
}
class PhotosList extends StatelessWidget {
const PhotosList({Key? key, required this.photos}) : super(key: key);
final List<Photo> photos;
#override
Widget build(BuildContext context) {
return ListView.builder(
padding: EdgeInsets.all(20),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: photos.length,
itemBuilder: (context, index) {
return ListTile(
title: Row(
children: [
Text(photos[index].quest),
Text(photos[index].ans1),
],
),
);
});
}
}
I want to do get only first column and get only questId from this parsed JSON. And I will set a textview using Getx library. I know set a data with Getx library but I can't do it because I don't know get the data.
If you just want to get the first questId of the List, do
photos[0].questId;
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)
],
),
I've implemented this code to show a list of json data from a web url.
I've tried to implement a simple pull to refresh, but nothing works.
Flutter code is long, but it's pretty simple actually. It has main classes of flutter, and a future method to load json data from web.
I just want to implement a simple pull to refresh.
What am I missing here?
Why is it not working?
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:pull_to_refresh/pull_to_refresh.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: 'XXX',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'XXX'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final RefreshController _refreshController = RefreshController();
Future<List<User>> _getUsers() async {
var data = await http.get("xxxxxxxxxxxxx");
if (data.statusCode == 200) {
print('Status Code 200: Ok!');
var jsonData = json.decode(data.body);
List<User> users = [];
for (var k in jsonData.keys) {
var u = jsonData[k];
//print(u["pubdate"]);
User user = User(u["id"], u["source"], u["desc"], u["link"], u["title"], u["img"], u["pubdate"]);
users.add(user);
}
print(users.length);
return users;
} else {
throw Exception('Failed to load json');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SmartRefresher(
controller: _refreshController,
enablePullDown: true,
header: WaterDropHeader(),
onRefresh: () async {
await Future.delayed(Duration(seconds: 1));
_refreshController.refreshCompleted();
},
child: FutureBuilder(
future: _getUsers(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.data == null){
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int id){
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data[id].img
),
),
title: Text(snapshot.data[id].title),
subtitle: Column(
children: <Widget>[
Row(
children: [
Text(
snapshot.data[id].source,
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
),
Spacer(),
Text(snapshot.data[id].pubdate),
],
),
],
)
);
},
);
}
},
),
),
);
}
}
class User {
final int id;
final String source;
final String desc;
final String link;
final String title;
final String img;
final String pubdate;
User(this.id, this.source, this.desc, this.link, this.title, this.img, this.pubdate);
}
Solved!
import 'package:flutter/material.dart';
import 'dart:async';
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: 'XXXX',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'XXXXXX'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//Funcao para buscar as noticias
Future<List<User>> _getUsers() async {
var data = await http.get("XXXXX");
if (data.statusCode == 200) {
print('Status Code 200: Ok!');
var jsonData = json.decode(data.body);
List<User> users = [];
for (var k in jsonData.keys) {
var u = jsonData[k];
//print(u["pubdate"]);
User user = User(u["id"], u["source"], u["desc"], u["link"], u["title"], u["img"], u["pubdate"]);
users.add(user);
}
print(users.length);
return users;
} else {
throw Exception('Failed to load json');
}
}
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
refreshList();
}
Future<Null> refreshList() async {
refreshKey.currentState?.show(atTop: false);
await Future.delayed(Duration(seconds: 2));
setState(() {
_getUsers();
});
return null;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: RefreshIndicator(
key: refreshKey,
child: FutureBuilder(
future: _getUsers(),
builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.data == null){
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int id){
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data[id].img
),
),
title: Text(snapshot.data[id].title),
subtitle: Column(
children: <Widget>[
Row(
children: [
Text(
snapshot.data[id].source,
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
),
Spacer(),
Text(snapshot.data[id].pubdate),
],
),
],
)
);
},
);
}
},
),
onRefresh: refreshList,
),
);
}
}
class User {
final int id;
final String source;
final String desc;
final String link;
final String title;
final String img;
final String pubdate;
User(this.id, this.source, this.desc, this.link, this.title, this.img, this.pubdate);
}
You have to get users on onLoading as shown below
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SmartRefresher(
....
onLoading: _getUsers,
.....
)
}
I'm a very beginner at Flutter development, in the code below I tried to get data from here and display it in ListView :
static final String URL = "https://corona.lmao.ninja/countries";
Future<List<CoronaModel>> getData() async {
var data = await http.get(URL);
var jsonData = json.decode(data.body);
print("the count is: " + jsonData.toString()); //Data successfully printed
List<CoronaModel> listCoronaCountries = [];
for (var item in jsonData) {
CoronaModel mCorona = CoronaModel(
item["country"],
item["recovered"],
item["cases"],
item["critical"],
item["deaths"],
item["todayCases"],
item["todayDeaths"]);
listCoronaCountries.add(mCorona);
}
if (listCoronaCountries.length > 0) {
print("the count is: " + listCoronaCountries.length.toString());
} else {
print("EMPTY");
}
return listCoronaCountries;
}
At run time, the first print works, I can see the data successfully printed, but the IF statement is not showing
if (listCoronaCountries.length > 0) {
print("the count is: " + listCoronaCountries.length.toString());
} else {
print("EMPTY");
}
Model :
class CoronaModel {
final String country;
final String recovered;
final String cases;
final String critical;
final String deaths;
final String todayCases;
final String todayDeaths;
CoronaModel(this.country, this.recovered, this.cases, this.critical,
this.deaths, this.todayCases, this.todayDeaths);
}
You can copy paste run full code below
You can parse with coronaModelFromJson and display with FutureBuilder
code snippet
List<CoronaModel> coronaModelFromJson(String str) => List<CoronaModel>.from(
json.decode(str).map((x) => CoronaModel.fromJson(x)));
Future<List<CoronaModel>> getData() async {
var data = await http.get(URL);
List<CoronaModel> listCoronaCountries = coronaModelFromJson(data.body);
return listCoronaCountries;
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
// To parse this JSON data, do
//
// final coronaModel = coronaModelFromJson(jsonString);
import 'dart:convert';
List<CoronaModel> coronaModelFromJson(String str) => List<CoronaModel>.from(
json.decode(str).map((x) => CoronaModel.fromJson(x)));
String coronaModelToJson(List<CoronaModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class CoronaModel {
String country;
int cases;
int todayCases;
int deaths;
int todayDeaths;
int recovered;
int active;
int critical;
int casesPerOneMillion;
CoronaModel({
this.country,
this.cases,
this.todayCases,
this.deaths,
this.todayDeaths,
this.recovered,
this.active,
this.critical,
this.casesPerOneMillion,
});
factory CoronaModel.fromJson(Map<String, dynamic> json) => CoronaModel(
country: json["country"],
cases: json["cases"],
todayCases: json["todayCases"],
deaths: json["deaths"],
todayDeaths: json["todayDeaths"],
recovered: json["recovered"],
active: json["active"],
critical: json["critical"],
casesPerOneMillion: json["casesPerOneMillion"],
);
Map<String, dynamic> toJson() => {
"country": country,
"cases": cases,
"todayCases": todayCases,
"deaths": deaths,
"todayDeaths": todayDeaths,
"recovered": recovered,
"active": active,
"critical": critical,
"casesPerOneMillion": casesPerOneMillion,
};
}
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> {
static final String URL = "https://corona.lmao.ninja/countries";
Future _future;
Future<List<CoronaModel>> getData() async {
var data = await http.get(URL);
List<CoronaModel> listCoronaCountries = coronaModelFromJson(data.body);
return listCoronaCountries;
}
#override
void initState() {
// TODO: implement initState
super.initState();
_future = getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder<List<CoronaModel>>(
future: _future,
builder: (BuildContext context,
AsyncSnapshot<List<CoronaModel>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Input a URL to start');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
' ${snapshot.data[index].country} , ${snapshot.data[index].cases}'),
);
});
}
}
}));
}
}
Instead of hand coding '.fromJson/.toJson' methods. you could rely on
this library https://github.com/k-paxian/dart-json-mapper,
It will help you not only for this case, but for all Dart Object => JSON => Dart Object cases.