Flutter null check operator used on null value - flutter

This is my first month as coder. I am trying to develop nearby places app. When i used following codes im getting error of "null check operator used on a null value". But based on what i see or when i printed url and checked manually or when i used if condition i see no problem or no error. Just when i rendered screen im getting this error. I would like to ask if someone can point me what is wrong ? Thanks in advance!
The line im getting error is locationName: locationSuggestion!.query.pages[0]!.title. Probibly and following locationSuggestion class.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_data_final.dart';
import 'package:flutter_udemy_examples/http_api_data/get_location_names.dart';
import 'package:flutter_udemy_examples/screens/login_ekrani.dart';
import 'package:flutter_udemy_examples/screens/map_screen.dart';
import 'login_ekrani.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../banner.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_udemy_examples/http_api_data/get_location_images.dart';
// ignore: must_be_immutable
class HomeScreen extends StatefulWidget {
#override
State<HomeScreen> createState() => HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
LocationDataFinal? locationSuggestion;
bool isLoading = true;
#override
void initState() {
super.initState();
asyncInitState();
}
Future<void> asyncInitState() async {
await fecthlocationData();
}
Future fecthlocationData() async {
var locations = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
final double enlem = locations.latitude;
final double boylam = locations.longitude;
final url = Uri.parse(
"https://en.wikipedia.org/w/api.php?action=query&format=json&prop=coordinates%7Cpageimages%7Cdescription%7Cextracts&generator=geosearch&piprop=original&descprefersource=central&exlimit=20&exintro=1&explaintext=1&exsectionformat=plain&ggscoord=${enlem}%7C${boylam}&ggsradius=10000");
print(url);
final response = await http.get(url);
//print(response.body);
if (response.statusCode == 200) {
locationSuggestion = await locationDataFinalFromJson(response.body);
if (locationSuggestion != null) {
setState(() {
isLoading = false;
});
} else {
print("null1");
}
} else {
print("null2");
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: _buildAppBar(context),
body: isLoading
? Center(
child: CircularProgressIndicator(),
)
: ListView(
children: [
MyBanner(
// info: locationSuggestion!.query.pages[0]!.description,
locationName: locationSuggestion!.query.pages[0]!.title,
imagePath:
locationSuggestion!.query.pages[0]!.original.source,
context: context,
),
MyBanner(
//info: locationSuggestion!.query.pages[1]!.description,
locationName: locationSuggestion!.query.pages[1]!.title,
imagePath:
locationSuggestion!.query.pages[1]!.original.source,
context: context,
),
MyBanner(
// info: locationSuggestion!.query.pages[2]!.description,
locationName: locationSuggestion!.query.pages[2]!.title,
imagePath:
locationSuggestion!.query.pages[2]!.original.source,
context: context,
),
MyBanner(
// info: locationSuggestion!.query.pages[3]!.description,
locationName: locationSuggestion!.query.pages[3]!.title,
imagePath:
locationSuggestion!.query.pages[3]!.original.source,
context: context,
),
MyBanner(
// info: locationSuggestion!.query.pages[4]!.description,
locationName: locationSuggestion!.query.pages[4]!.title,
imagePath:
locationSuggestion!.query.pages[4]!.original.source,
context: context,
),
],
),
);
}
AppBar _buildAppBar(BuildContext context) {
return AppBar(
automaticallyImplyLeading: false,
leading: RotatedBox(
quarterTurns: 2,
child: _buildExitButton(context),
),
actions: [
_buildOpenMapButton(),
_buildCallEmergencyNumberButton(),
],
titleSpacing: 25,
shadowColor: Colors.white,
elevation: 0.0,
backgroundColor: Colors.blue[800],
//titleSpacing: Padding(padding: EdgeInsets.fromLTRB(25.85.0, 0, 25.85.0, 0)),
title: Text("Traveler Doctor"),
);
}
Widget _buildCallEmergencyNumberButton() {
return IconButton(
disabledColor: Colors.red,
color: Colors.red,
icon: Icon(Icons.phone_enabled),
tooltip: "Local emergency number",
onPressed: null,
);
}
Widget _buildOpenMapButton() {
return IconButton(
disabledColor: Colors.orangeAccent,
color: Colors.limeAccent,
icon: Icon(Icons.map_rounded),
tooltip: "Map",
enableFeedback: false,
onPressed: () => {
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) => MapScreen()))
},
);
}
}
Widget _buildExitButton(BuildContext context) {
return IconButton(
onPressed: () async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('KullaniciAdi', "");
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext context) => LoginEkrani()));
},
icon: Icon(
Icons.exit_to_app,
color: Colors.red,
),
tooltip: "Exit",
);
}
And this is the model im using for parsing api response
import 'dart:convert';
LocationDataFinal locationDataFinalFromJson(String str) =>
LocationDataFinal.fromJson(json.decode(str));
class LocationDataFinal {
LocationDataFinal({
required this.batchcomplete,
required this.query,
});
String batchcomplete;
Query query;
factory LocationDataFinal.fromJson(Map<String, dynamic> json) =>
LocationDataFinal(
batchcomplete: json["batchcomplete"],
query: Query.fromJson(json["query"]),
);
}
class Query {
Query({
required this.pages,
});
Map<String, Page> pages;
factory Query.fromJson(Map<String, dynamic> json) => Query(
pages: Map.from(json["pages"])
.map((k, v) => MapEntry<String, Page>(k, Page.fromJson(v))),
);
}
class Page {
Page({
required this.pageid,
required this.ns,
required this.title,
required this.index,
required this.coordinates,
required this.original,
required this.description,
required this.descriptionsource,
required this.extract,
});
int pageid;
int ns;
String title;
int index;
List<Coordinate> coordinates;
Original original;
String description;
String descriptionsource;
String extract;
factory Page.fromJson(Map<String, dynamic> json) => Page(
pageid: json["pageid"],
ns: json["ns"],
title: json["title"],
index: json["index"],
coordinates: List<Coordinate>.from(
json["coordinates"].map((x) => Coordinate.fromJson(x))),
original: json["original"] == null
? Original(
source:
"https://tigres.com.tr/wp-content/uploads/2016/11/orionthemes-placeholder-image-1.png",
width: 300,
height: 200)
: Original.fromJson(json["original"]),
description: json["description"] == null ? "asd" : json["description"],
descriptionsource:
json["descriptionsource"] == null ? " " : json["descriptionsource"],
extract: json["extract"],
);
}
class Coordinate {
Coordinate({
required this.lat,
required this.lon,
required this.primary,
required this.globe,
});
double lat;
double lon;
String primary;
Globe globe;
factory Coordinate.fromJson(Map<String, dynamic> json) => Coordinate(
lat: json["lat"].toDouble(),
lon: json["lon"].toDouble(),
primary: json["primary"],
globe: globeValues.map[json["globe"]]!,
);
}
enum Globe { EARTH }
final globeValues = EnumValues({"earth": Globe.EARTH});
class Original {
Original({
required this.source,
required this.width,
required this.height,
});
String source;
int width;
int height;
factory Original.fromJson(Map<String, dynamic> json) => Original(
source: json["source"],
width: json["width"],
height: json["height"],
);
}
class EnumValues<T> {
late Map<String, T> map;
late Map<T, String> reverseMap;
EnumValues(this.map);
}
I will be checking this post frequently.
Thanks in advance again.
Sincerely ur noob coder.

Would leave this as a comment but apparently I only have enough reputation to write answers.
In your Query object pages is a Map<String, Page> but you're accessing it with a int key: locationSuggestion!.query.pages[0]!.title
To access the map with an int key, it needs to be Map<int,Page> (or List<Page>)

Somewhat i solved issue by replacing
locationSuggestion!.query.pages[0]!.titlewith
locationSuggestion!.query.pages.values.elementAt(0).title
This way of adressing solved issue for me :)

Related

Can't show the list from my API in flutter

iam new to flutter and i tried to make an app using my own API, i tried running the app but the listview just showing anything besides no error occured, someone said i should use FutureListView but idk how to implemented in my code.
here is my homepage code
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart';
import 'package:medreminder/TipsAndTricks/models/tips.dart';
import 'package:medreminder/TipsAndTricks/models/tips_model.dart';
import 'package:medreminder/TipsAndTricks/screens/tips_details.dart';
import 'package:medreminder/TipsAndTricks/tips_repo.dart';
class TipsList extends StatefulWidget {
const TipsList({super.key});
#override
State<TipsList> createState() => _TipsListState();
}
class _TipsListState extends State<TipsList> {
List<Tips> listTips = [];
Repo repo = Repo();
getData() async {
listTips = await repo.getData();
}
#override
void initState() {
getData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Get.isDarkMode?Colors.grey[600]:Colors.white,
leading: IconButton(
onPressed: ()=>Get.back(),
icon: Icon(Icons.arrow_back_ios,
color: Get.isDarkMode?Colors.white:Colors.black
),
),
title: Text("Healthy Tips & Tricks", style: TextStyle(
color: Get.isDarkMode?Colors.white:Colors.black
),),
),
body: ListView.builder(
itemCount: listTips.length,
itemBuilder: (context, index){
Tips tips = listTips[index];
return Card(
child: ListTile(
title: Text(listTips[index].title),
subtitle: Text(listTips[index].source),
leading: Image.network(listTips[index].imageUrl),
trailing: Icon(Icons.arrow_forward_ios),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => TipsDetails(listTips[index])));
},
),
);
})
);
}
}
my model class
class Tips {
final String title;
final String desc;
final String imageUrl;
final String source;
const Tips({
required this.title,
required this.desc,
required this.imageUrl,
required this.source,
});
factory Tips.fromJson(Map<String, dynamic> json) {
return Tips(
source: json['source'],
desc: json['desc'],
title: json['title'],
imageUrl: json['imageUrl']
);
}
}
my repository code
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:medreminder/TipsAndTricks/models/tips_model.dart';
class Repo{
final _baseUrl = 'http://10.0.2.2:8000/tips';
Future getData() async{
try {
final response = await http.get(Uri.parse(_baseUrl));
if(response.statusCode == 200){
print(response.body);
Map<String, dynamic> apiRespose = jsonDecode(response.body);
Iterable<dynamic> it = apiRespose['tips'];
//Iterable it = jsonDecode(response.body);
List<Tips> tips = it.map((e) => Tips.fromJson(e)).toList();
return tips;
}
} catch (e) {
print(e.toString());
}
}
}
if you guys needs to see more of my code, please let me know. any help would mean so much to me. thankyou guys

Troubles with making a Favorite page with Hive DB Flutter

Hello everyone here's my test app and I have some problems with making a Favorite page section where you can tap on button and add the item into fav page.
I'm receiving a data from API and implementing it by Listview.builder
Here are some photos of how it should look like:
Home page
Favorite page
main.dart, here I'm openning a box called 'favorites_box'
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
void main() async{
await GetStorage.init();
await Hive.openBox('favorites_box');
runApp(MainPage());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => MyApp()),
GetPage(name: '/main-page', page: () => MainPage()),
GetPage(name: '/favorite_page', page: () => FavoritePage()),
// Dynamic route
],
home: MainPage(),
);
}
}
Well here's a code of home page:
main_page.dart
import 'package:flutter/material.dart';
import '../View/listview_api.dart';
class MainPage extends StatefulWidget {
#override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int currentIndex = 0;
List<BottomNavigationBarItem>? items;
final screens = [
HomePage(),
HomePage()
FavoritePage(),
HomePage()
];
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Container(
width: double.infinity,
height: 40,
color: Colors.white,
child: Center(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
),
hintText: 'Searching',
prefixIcon: Icon(Icons.search),
suffixIcon: Icon(Icons.notifications)),
),
),
),
),
body: screens[currentIndex],
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.grey,//AppColors.unselectedBottomNavItem,
selectedItemColor: Colors.blue,//AppColors.assets,
onTap: (index) => setState(() {
currentIndex = index;
}),//controller.setMenu(BottomMenu.values[pos]),
//currentIndex: ,//controller.bottomMenu.index,
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.white,
currentIndex: currentIndex,
selectedLabelStyle: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
),
unselectedLabelStyle: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w500,
),
elevation: 8,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.blue,
),
BottomNavigationBarItem(
icon: Icon(Icons.add_shopping_cart),
label: 'Shopping cart',
backgroundColor: Colors.red,
),
BottomNavigationBarItem(
icon: Icon(Icons.favorite),
label: 'Favorite',
backgroundColor: Colors.green,
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
backgroundColor: Colors.yellow,
),
],
),
),
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Center(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
//Image.asset('images/image0.jpg'),
SizedBox(
height: 25.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'New!',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
),
),
IconButton(
onPressed: () {},
icon: Icon(
Icons.arrow_forward_outlined,
),
),
],
),
SizedBox(
height: 25.0,
),
SizedBox(
height: 300.0,
width: double.infinity,
child: ListViewAPI(),
),
],
),
),
),
),
);
}
}
And now, below is a code of ListViewAPI(), here I've added the elements which I tap to the box('favorites_box'): listview_api.dart
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
String? stringResponse;
Map? mapResponse;
Map? dataResponse;
List? listResponse;
class ListViewAPI extends StatefulWidget {
const ListViewAPI({Key? key}) : super(key: key);
#override
_ListViewAPIState createState() => _ListViewAPIState();
}
class _ListViewAPIState extends State<ListViewAPI> {
Future apiCall() async {
http.Response response;
response = await http.get(Uri.parse("https://api.client.macbro.uz/v1/product"));
if(response.statusCode == 200) {
setState(() {
// stringResponse = response.body;
mapResponse = jsonDecode(response.body);
listResponse = mapResponse!['products'];
});
}
}
#override
void initState() {
super.initState();
apiCall();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scrollbar(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
listResponse![index]['image'],
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box('favorites_box').put(listResponse![index]['image'], listResponse);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: listResponse == null ? 0 : listResponse!.length,
),
),
);
}
}
So here, I created a list, and tried to save the elements from box named "favorites_box" and got data which was added while I tap favorite IconButton upper but without success( :
favorite_page.dart
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../View/gridview_api.dart';
class FavoritePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ValueListenableBuilder(
valueListenable: Hive.box('favorites_box').listenable(),
builder: (context, box, child) {
List posts = List.from(Hive.box('favorites_box').values);
return ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Column(
children: [
Text(
'List of favorite products'
),
Card(
child: posts[index] == null ? Text('nothing(') : posts[index],
// child: Hive.box('favorites_box').get(listResponse),
),
],
);
},
);
},
),
);
}
}
I'll be grateful if someone could help me with this problem, as I'm trying to fix this issue for a couple of days
P.s. I'm so sorry for some inconveniences, I'm a novice yet that's why hope you'll understand me
Thanks!
Alright. I now have a solution. It is a bit more complex than what you started with but it worked during testing.
Using https://marketplace.visualstudio.com/items?itemName=hirantha.json-to-dart I created a model class from the API data JSON. One for the Product and one for the Price map inside of Product.
product_model.dart
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'price.dart';
part 'product_model.g.dart';
#HiveType(typeId: 1)
class ProductModel extends Equatable {
#HiveField(0)
final String? id;
#HiveField(1)
final String? name;
#HiveField(2)
final String? slug;
#HiveField(3)
final bool? active;
#HiveField(4)
final String? image;
#HiveField(5)
final String? code;
#HiveField(6)
final String? order;
#HiveField(7)
final int? cheapestPrice;
#HiveField(8)
final Price? price;
#HiveField(9)
final int? discount;
const ProductModel({
this.id,
this.name,
this.slug,
this.active,
this.image,
this.code,
this.order,
this.cheapestPrice,
this.price,
this.discount,
});
factory ProductModel.fromMap(Map<String, dynamic> data) => ProductModel(
id: data['id'] as String?,
name: data['name'] as String?,
slug: data['slug'] as String?,
active: data['active'] as bool?,
image: data['image'] as String?,
code: data['code'] as String?,
order: data['order'] as String?,
cheapestPrice: data['cheapest_price'] as int?,
price: data['price'] == null
? null
: Price.fromMap(data['price'] as Map<String, dynamic>),
discount: data['discount'] as int?,
);
Map<String, dynamic> toMap() => {
'id': id,
'name': name,
'slug': slug,
'active': active,
'image': image,
'code': code,
'order': order,
'cheapest_price': cheapestPrice,
'price': price?.toMap(),
'discount': discount,
};
/// `dart:convert`
///
/// Parses the string and returns the resulting Json object as [ProductModel].
factory ProductModel.fromJson(String data) {
return ProductModel.fromMap(json.decode(data) as Map<String, dynamic>);
}
/// `dart:convert`
///
/// Converts [ProductModel] to a JSON string.
String toJson() => json.encode(toMap());
ProductModel copyWith({
String? id,
String? name,
String? slug,
bool? active,
String? image,
String? code,
String? order,
int? cheapestPrice,
Price? price,
int? discount,
}) {
return ProductModel(
id: id ?? this.id,
name: name ?? this.name,
slug: slug ?? this.slug,
active: active ?? this.active,
image: image ?? this.image,
code: code ?? this.code,
order: order ?? this.order,
cheapestPrice: cheapestPrice ?? this.cheapestPrice,
price: price ?? this.price,
discount: discount ?? this.discount,
);
}
#override
bool get stringify => true;
#override
List<Object?> get props {
return [
id,
name,
slug,
active,
image,
code,
order,
cheapestPrice,
price,
discount,
];
}
}
price.dart
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:hive_flutter/hive_flutter.dart';
part 'price.g.dart';
#HiveType(typeId: 2)
class Price extends Equatable {
#HiveField(0)
final int? price;
#HiveField(1)
final int? oldPrice;
#HiveField(2)
final int? uzsPrice;
#HiveField(3)
final int? secondPrice;
#HiveField(4)
final int? secondUzsPrice;
const Price({
this.price,
this.oldPrice,
this.uzsPrice,
this.secondPrice,
this.secondUzsPrice,
});
factory Price.fromMap(Map<String, dynamic> data) => Price(
price: data['price'] as int?,
oldPrice: data['old_price'] as int?,
uzsPrice: data['uzs_price'] as int?,
secondPrice: data['second_price'] as int?,
secondUzsPrice: data['second_uzs_price'] as int?,
);
Map<String, dynamic> toMap() => {
'price': price,
'old_price': oldPrice,
'uzs_price': uzsPrice,
'second_price': secondPrice,
'second_uzs_price': secondUzsPrice,
};
/// `dart:convert`
///
/// Parses the string and returns the resulting Json object as [Price].
factory Price.fromJson(String data) {
return Price.fromMap(json.decode(data) as Map<String, dynamic>);
}
/// `dart:convert`
///
/// Converts [Price] to a JSON string.
String toJson() => json.encode(toMap());
Price copyWith({
int? price,
int? oldPrice,
int? uzsPrice,
int? secondPrice,
int? secondUzsPrice,
}) {
return Price(
price: price ?? this.price,
oldPrice: oldPrice ?? this.oldPrice,
uzsPrice: uzsPrice ?? this.uzsPrice,
secondPrice: secondPrice ?? this.secondPrice,
secondUzsPrice: secondUzsPrice ?? this.secondUzsPrice,
);
}
#override
bool get stringify => true;
#override
List<Object?> get props {
return [
price,
oldPrice,
uzsPrice,
secondPrice,
secondUzsPrice,
];
}
}
I then used https://docs.hivedb.dev/#/custom-objects/generate_adapter to create adapters for both of those. You can read the documentation to see how that is done using build_runner and the hive_generator packages.
In main.dart I registered both of the adapters and opened up a box with the ProductModel type from product_model.dart.
main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:test/product_model/price.dart';
import 'package:test/product_model/product_model.dart';
import 'favorite_page.dart';
import 'homepage.dart';
void main() async {
// await GetStorage.init();
await Hive.initFlutter();
Hive.registerAdapter(PriceAdapter());
Hive.registerAdapter(ProductModelAdapter());
await Hive.openBox<ProductModel>('favorites_box');
runApp(MainPage());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => MyApp()),
GetPage(name: '/main-page', page: () => MainPage()),
GetPage(name: '/favorite_page', page: () => FavoritePage()),
// Dynamic route
],
home: MainPage(),
);
}
}
listview_api.dart is mostly the same with the exception of mapping the products from listResponse to ProductModel objects.
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:test/product_model/product_model.dart';
String? stringResponse;
Map? mapResponse;
Map? dataResponse;
List? listResponse;
class ListViewAPI extends StatefulWidget {
const ListViewAPI({Key? key}) : super(key: key);
#override
_ListViewAPIState createState() => _ListViewAPIState();
}
class _ListViewAPIState extends State<ListViewAPI> {
Future apiCall() async {
http.Response response;
response =
await http.get(Uri.parse("https://api.client.macbro.uz/v1/product"));
if (response.statusCode == 200) {
setState(() {
// stringResponse = response.body;
mapResponse = jsonDecode(response.body);
listResponse = mapResponse!['products'];
listResponse =
listResponse!.map((e) => ProductModel.fromMap(e)).toList(); // Map all of the products in listResponse to a ProductModel object.
});
}
}
#override
void initState() {
super.initState();
apiCall();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scrollbar(
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
listResponse![index].image!,
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box<ProductModel>('favorites_box').put(
listResponse![index].image, listResponse![index]);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: listResponse == null ? 0 : listResponse!.length,
),
),
);
}
}
homepage.dart is unchanged.
favorite_page.dart was changed to a stateful widget and then gets the box values on init.
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:test/product_model/product_model.dart';
class FavoritePage extends StatefulWidget {
#override
State<FavoritePage> createState() => _FavoritePageState();
}
class _FavoritePageState extends State<FavoritePage> {
var posts;
#override
void initState() {
super.initState();
posts = Hive.box<ProductModel>('favorites_box').values.toList();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
posts[index].image!,
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box<ProductModel>('favorites_box')
.delete(posts[index]);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: posts == null ? 0 : posts.length,
),
);
}
}
I really encourage you to read the documentation on Hive as it contains a wealth of information. Another tip when coding with hive is to make sure you are clearing out the storage and cache for your emulator or physical device regularly. I have had too many headaches dealing with errors in Hive simply because I forgot to clear the storage and cache which was resulting in bad data despite having changed my source code.
I don't believe this is a problem with your code. However, I do recommend creating a model class for your data and maybe using a FutureBuilder https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html.
I believe the problem is that you have not updated your AndroidManifest.xml file to allow for internet connectivity.
Try adding:
<uses-permission android:name="android.permission.INTERNET" />
to your android\app\src\main\AndroidManifest.xml, above <application.
Further reading: https://flutter-examples.com/add-permissions-in-androidmanifest-xml-file/
After taking a closer look at your issue, I think I figured out the problem.
Hive requires an init:
void main() async {
// await GetStorage.init(); // Not sure why this was here but doesn't seem to be needed.
await Hive.initFlutter();
await Hive.openBox('favorites_box');
runApp(MainPage());
}
You were also missing a comma in main_page.dart
final screens = [
HomePage(),
HomePage() <----
FavoritePage(),
HomePage()
];
For your favorites page, I replaced the ValueListenableBuilder with just a ListView.builder:
class FavoritePage extends StatelessWidget {
List posts = List.from(Hive.box('favorites_box').values);
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Stack(
children: [
Card(
child: Image.network(
posts[index]['image'],
),
),
Positioned(
right: 0,
child: InkWell(
child: IconButton(
onPressed: () async {
await Hive.box('favorites_box').delete(posts[index]);
},
icon: Icon(
Icons.favorite_rounded,
color: Colors.red,
),
),
),
),
],
);
},
itemCount: posts == null ? 0 : posts.length,
),
);
}
}
There is still an error when you try to use this that says that posts[index]['image'] type 'String' is not a subtype of type 'int' of 'index' but you can easily fix this by creating a model class and accessing everything with those properties. Using model class in flutter (dart) here is an example of a model class. Instead of using DocumentSnapshot, you can add a toList() or toMap() method.
Hope this helps. It is working on my emulator. but I am just printing out the full string instead of using the image in the Card child.
Example Model Class:
import 'dart:convert';
void main() async {
String data = '{"id":"626694d4f1ce2a0012f0fe1c","name":"JBL Party Box On-The-Go","slug":"jbl-party-box-on-the-go-juqgil2ep8ult","active":true,"image":"https://cdn.macbro.uz/macbro/1fad4f47-51f4-4f12-975b-657d780c98af","code":"","order":"0","cheapest_price":0,"price":{"price":520,"old_price":0,"uzs_price":5994000,"second_price":0,"second_uzs_price":7012500},"discount":0}';
var test = new ProductModel.fromJson(json.decode(data));
print(test.image);
}
class ProductModel {
String? name;
String? image;
ProductModel.fromJson(Map json) {
this.name = json['id'];
this.image = json['image'];
}
}

How do I resolve a Sqlite Error (1) in Flutter?

Im new to flutter and first time to work with sqlite database.
I have created a todo app that is linked to a Sqlite database. It has simple cards that i can add and it works fine. The problem is, I have a delete icon, but for some reason the cards do not delete when I press the delete icon. I get the following error message in the stack:
E/SQLiteLog(22653): (1) no such table: çustomerblueprint in "DELETE FROM çustomerblueprint WHERE id == ?"
E/flutter (22653): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: DatabaseException(no such table: çustomerblueprint (code 1 SQLITE_ERROR[1]): , while compiling: DELETE FROM çustomerblueprint WHERE id == ?) sql 'DELETE FROM çustomerblueprint WHERE id == ?' args [1]
I have read for hours to try and fine a solution, but don't seem to get this one.
My code is:
Database Code
class CustomerBluePrint {
int? id;
final String title;
DateTime creationDate;
bool isChecked;
CustomerBluePrint({
this.id,
required this.title,
required this.creationDate,
required this.isChecked,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'title': title,
'creationDate': creationDate.toString(),
'isChecked': isChecked ? 1 : 0,
};
}
#override
String toString() {
return 'CustomerBluePrint(id : $id, title : $title, creationDate : $creationDate, isChecked
: $isChecked )'; // , phone : $phone, mobile : $mobile, fax : $fax, email : $email, name :
$name)';
}
}
class DatabaseConnect {
Database? _database;
Future<Database> get database async {
final dbpath = await getDatabasesPath();
const dbname = 'customerblueprint.db';
final path = join(dbpath, dbname);
_database = await openDatabase(path, version: 1, onCreate: _createDB);
return _database!;
}
Future<void> _createDB(Database db, int version) async {
await db.execute('''
CREATE TABLE todo(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
creationDate TEXT,
isChecked INTEGER
)
''');
}
Future<void> insertCustomerBluePrint(
CustomerBluePrint customerblueprint) async {
final db = await database;
await db.insert(
'customerblueprint',
customerblueprint.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<void> deleteCustomerBluePrint(
CustomerBluePrint customerblueprint) async {
final db = await database;
await db.delete(
'çustomerblueprint',
where: 'id == ?',
whereArgs: [customerblueprint.id],
);
}
Future<List<CustomerBluePrint>> getCustomerBluePrint() async {
final db = await database;
List<Map<String, dynamic>> items = await db.query(
'customerblueprint',
orderBy: 'id DESC',
);
return List.generate(
items.length,
(i) => CustomerBluePrint(
id: items[i]['id'],
title: items[i]['title'],
creationDate: DateTime.parse(items[i]['creationDate']),
isChecked: items[i]['isChecked'] == 1 ? true : false,
),
);
}
}
Customer List Code
import 'package:flutter/material.dart';
import 'library.dart';
import 'customer_card.dart';
class CustomerList extends StatelessWidget {
final Function insertFunction;
final Function deleteFunction;
final db = DatabaseConnect();
CustomerList(
{required this.insertFunction, required this.deleteFunction, Key? key})
: super(key: key);
#override
Widget build(BuildContext context) {
return Expanded(
child: FutureBuilder(
future: db.getCustomerBluePrint(),
initialData: const [],
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
var data = snapshot.data;
var datalength = data!.length;
return datalength == 0
? const Center(
child: Text('no data found'),
)
: ListView.builder(
itemCount: datalength,
itemBuilder: (context, i) => CustomerCard(
id: data[i].id,
title: data[i].title,
creationDate: data[i].creationDate,
isChecked: data[i].isChecked,
insertFunction: insertFunction,
deleteFunction: deleteFunction,
),
);
},
),
);
}
}
Customer Card Code
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'library.dart';
class CustomerCard extends StatefulWidget {
final int id;
final String title;
final DateTime creationDate;
bool isChecked;
final Function insertFunction;
final Function deleteFunction;
CustomerCard(
{required this.id,
required this.title,
required this.creationDate,
required this.isChecked,
required this.insertFunction,
required this.deleteFunction,
Key? key})
: super(key: key);
#override
_CustomerCardState createState() => _CustomerCardState();
}
class _CustomerCardState extends State<CustomerCard> {
#override
Widget build(BuildContext context) {
var anotherCustomerBluePrint = CustomerBluePrint(
id: widget.id,
title: widget.title,
creationDate: widget.creationDate,
isChecked: widget.isChecked);
return Card(
child: Row(
children: [
Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: Checkbox(
value: widget.isChecked,
onChanged: (bool? value) {
setState(() {
widget.isChecked = value!;
});
anotherCustomerBluePrint.isChecked = value!;
widget.insertFunction(anotherCustomerBluePrint);
},
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
const SizedBox(height: 5),
Text(
DateFormat('dd MMM yyyy - hh:mm aaa')
.format(widget.creationDate),
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xFF8F8F8F),
),
)
],
),
),
IconButton(
onPressed: () {
widget.deleteFunction(anotherCustomerBluePrint);
},
icon: const Icon(Icons.close),
),
],
),
);
}
}
Customer Code
This is my Homepage
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:invoice_app/customer_profile.dart';
import 'customer_list.dart';
import 'library.dart';
class Customer extends StatefulWidget {
const Customer({Key? key}) : super(key: key);
#override
_CustomerState createState() => _CustomerState();
}
class _CustomerState extends State<Customer> {
var db = DatabaseConnect();
void addItem(CustomerBluePrint customerblueprint) async {
await db.insertCustomerBluePrint(customerblueprint);
setState(() {});
}
void deleteItem(CustomerBluePrint customerblueprint) async {
await db.deleteCustomerBluePrint(customerblueprint);
setState(() {
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF5EBFF),
body: Column(
children: [
CustomerList(
insertFunction: addItem, deleteFunction: deleteItem),
CustomerProfile(
insertFunction: addItem
),
],
),
);
}
The deletefunction is suppose to delete an entry based on the 'id'assigned to it. Everything works fine, except I cannot delete a card (entry) as it throws the error.
Please help. Would really appreciate it.
Found your mistake take a look at Database Code and implementation of the method Future<void> deleteCustomerBluePrint(CustomerBluePrint customerblueprint) You have an error there. Your:
await db.delete(
'çustomerblueprint',
where: 'id == ?',
whereArgs: [customerblueprint.id],
);
Mine Repaired:
await db.delete(
'customerblueprint',
where: 'id == ?',
whereArgs: [customerblueprint.id],
);
An error in the word customerblueprint, you do not have the letter "c" there, you have some other sign.

Flutter : Image not showing in CarouselSlider...?

eg: details about the questions ......................................................I've implemented CarouselSlider to make a banner in home page. I've debug from my mobile data is coming correct but image not showing. Below I've mentioned the model class and home page please find and check.
Model Class:-
// To parse this JSON data, do
//
// final bannerModel = bannerModelFromJson(jsonString);
import 'dart:convert';
BannerModel bannerModelFromJson(String str) => BannerModel.fromJson(json.decode(str));
String bannerModelToJson(BannerModel data) => json.encode(data.toJson());
class BannerModel {
BannerModel({
required this.status,
required this.imgPath,
required this.banner,
});
int status;
String imgPath;
List<Banner> banner;
factory BannerModel.fromJson(Map<String, dynamic> json) => BannerModel(
status: json["status"],
imgPath: json["img_path"],
banner: List<Banner>.from(json["Banner"].map((x) => Banner.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"img_path": imgPath,
"Banner": List<dynamic>.from(banner.map((x) => x.toJson())),
};
}
class Banner {
Banner({
required this.id,
required this.type,
required this.parentId,
required this.title,
required this.caption,
required this.image,
required this.link,
required this.status,
required this.sliderOrder,
required this.entryTime,
});
String id;
String type;
String parentId;
String title;
String caption;
String image;
String link;
String status;
String sliderOrder;
DateTime entryTime;
factory Banner.fromJson(Map<String, dynamic> json) => Banner(
id: json["id"],
type: json["type"],
parentId: json["parent_id"],
title: json["title"],
caption: json["caption"],
image: json["image"],
link: json["link"],
status: json["status"],
sliderOrder: json["slider_order"],
entryTime: DateTime.parse(json["entry_time"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"type": type,
"parent_id": parentId,
"title": title,
"caption": caption,
"image": image,
"link": link,
"status": status,
"slider_order": sliderOrder,
"entry_time": entryTime.toIso8601String(),
};
}
Home Page :-
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:newbharatbiz/VendorRegistrationPage.dart';
import 'dart:convert';
import 'NavDrawer.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'Model Class/banner_model.dart';
var paddingBottom = 48.0;
var androidDeviceInfo;
var identifier;
var token = "debendra";
var token1;
class HomePage extends StatelessWidget {
final String bannerAPI =
"https://newbharatbiz.in/mobile_api/v4/all_banner.php";
Future<BannerModel> fetchAlbum() async {
final response = await http.get(Uri.parse(bannerAPI));
print(response.body);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return BannerModel.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
late DateTime currentBackPressTime;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.deepOrangeAccent,
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => VendorRegistrationPage(),
),
);
},
),
drawer: NavDrawer(),
appBar:
AppBar(title: Text('New Bharat Biz'), centerTitle: true, actions: [
IconButton(
onPressed: () async {},
icon: Icon(Icons.search),
),
]),
body: Column(mainAxisAlignment: MainAxisAlignment.start, children: [
FutureBuilder<BannerModel>(
future: fetchAlbum(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<String> imagesList = [];
print(imagesList);
snapshot.data!.banner.forEach((e) {
imagesList.add(snapshot.data!.imgPath + e.image);
});
Container(
child: CarouselSlider(
options: CarouselOptions(
height: 330,
aspectRatio: 16 / 9,
viewportFraction: 0.8,
initialPage: 0,
enableInfiniteScroll: true,
reverse: false,
autoPlay: true,
autoPlayInterval: Duration(seconds: 3),
autoPlayAnimationDuration: Duration(milliseconds: 800),
autoPlayCurve: Curves.fastOutSlowIn,
enlargeCenterPage: true,
),
items: imagesList
.map(
(item) => Container(
child: Center(
child: Image.network(item,
fit: BoxFit.cover, width: 1000)),
),
)
.toList(),
),
);
}
// By default, show a loading spinner.
return Center(
child: SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation(Colors.blue),
),
),
);
},
)
]));
}
Future<bool> onWillPop() {
DateTime now = DateTime.now();
if (currentBackPressTime == null ||
now.difference(currentBackPressTime) > Duration(seconds: 2)) {
currentBackPressTime = now;
return Future.value(false);
}
return Future.value(true);
}
}

Parsing Nested JSON with Flutter (Dart)

This is the JSON Response I'm getting. I want to Parse the text which says "url" (With. I want to Get this Text)
{
"data": [
{
"id": 1,
"attributes": {
"Title": "My Story",
"Story": "My story is about my life",
"Image": {
"data": {
"id": 1,
"attributes": {
"name": "lifeImage.jpeg",
"alternativeText": "lifeImage.jpeg",
"caption": "lifeImage.jpeg",
"url": "/uploads/lifeImage_0e9293ee8d.jpeg", <-- I want to Get this Text
"previewUrl": null,
"provider": "local"
}
}
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 3
}
}
}
I easily parsed the Title, Story with the Below Dart File.
But I'm not sure how can I parse the URL text (One with arrow marks says "<-- I want to Get this Text"). Since it's nested one I don't know how to do that. Please help me with this. Thanks
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'StoryPage.dart';
void main() => runApp(App());
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My Stories',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Homepage(),
);
}
}
class Homepage extends StatefulWidget {
const Homepage({Key? key}) : super(key: key);
#override
_HomepageState createState() => _HomepageState();
}
class _HomepageState extends State<Homepage> {
Future<List<Story>> _getStories() async {
var response = await http.get(Uri.parse(
'https://exampleapi.com/api/stories/?populate=Image'));
if (response.statusCode == 200) {
Map responseData = jsonDecode(response.body);
List StoriesList = responseData["data"];
List<Story> stories = [];
for (var storyMap in StoriesList) {
stories.add(Story.fromJson(storyMap["attributes"]));
}
return stories;
} else {
throw Exception('Failed to load stories');
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('My Stories'),
),
body: Container(
child: FutureBuilder(
future: _getStories(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Card(
child: Padding(
padding: const EdgeInsets.only(
top: 32.0, bottom: 32.0, left: 16.0, right: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
snapshot.data[index].title,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new StoryPage(
snapshot.data[index],
title: snapshot.data[index].title,
body: snapshot.data[index].body,
)));
},
);
},
);
}
},
),
),
);
}
}
class Story {
final String title;
final String body;
Story({required this.title, required this.body});
factory Story.fromJson(Map<String, dynamic> json) {
return Story(
title: json['Title'],
body: json['Story'],
);
}
}
You can simply parse them like this:
final url = json['image']?['data']?['attributes']?['url'];
here we're using question marks (?) in between, because we're not sure that each element is not null, for example, the data under image may be null, so by using question marks, we're staying safe from null exceptions.
I took #Adnan approach and modified it little.
final ImageURL = json['Image']?['data']?['attributes']?['url'] ?? ''
Thanks to GitHub Co-Pilot.
I suggest using this website to generate dart or any other language object from json.
you just need to covert it to null safety.
here a example:
class AnswerResponse {
AnswerResponse({
required this.id,
required this.description,
required this.isAccepted,
required this.isMine,
required this.media,
required this.caseId,
required this.voteUp,
required this.voteDown,
required this.votes,
required this.user,
required this.comment,
required this.createdAt,
});
factory AnswerResponse.fromJson(final String str) => AnswerResponse.fromMap(json.decode(str));
factory AnswerResponse.fromMap(final Map<String, dynamic> json) => AnswerResponse(
id: json["id"],
description: json["description"],
isAccepted: json["isAccepted"],
isMine: json["isMine"],
media: json["media"] == null ? null : List<MediaResponse>.from(json["media"].map((final dynamic x) => MediaResponse.fromMap(x))),
caseId: json["caseId"],
voteUp: json["voteUp"],
voteDown: json["voteDown"],
votes: json["votes"],
user: json["user"] == null ? null : ProfileResponse.fromMap(json["user"]),
comment: json["comment"] == null ? null : List<CommentResponse>.from(json["comment"].map((final dynamic x) => CommentResponse.fromMap(x))),
createdAt: json["createdAt"],
);
final int? id;
final int? caseId;
final int? votes;
final bool? isAccepted;
final bool? isMine;
final bool? voteUp;
final bool? voteDown;
final String? description;
final String? createdAt;
final ProfileResponse? user;
final List<MediaResponse>? media;
final List<CommentResponse>? comment;
}
and to convert json string to dart object:
var data = AnswerResponse.fromMap(jsonString)