I wrote this below codes to pull json data and display it in my app, it returns data with status code of 200 but with this below mentioned error. the link to my json file is http://mvs.bslmeiyu.com/api/v1/products/popular . I am using flutter 2.10 and get depencencies. Kindly help me as I am stuck here, not being able to display the product list in my app.
error:
I/flutter ( 7254): got products
E/flutter ( 7254): [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: type 'String' is not a subtype of type 'Map<String, dynamic>',
stack trace: #0 PopularProductController.getPopularProductList (package:my_restaurant/controllers/popular_product_controller.dart:16:60)
E/flutter ( 7254): <asynchronous suspension>
E/flutter ( 7254):
This is my init function 'dependencies.dart'
import 'package:get/get.dart';
import 'package:my_restaurant/controllers/popular_product_controller.dart';
import 'package:my_restaurant/data/api/api_client.dart';
import 'package:my_restaurant/data/repository/popular_product_repo.dart';
import 'package:my_restaurant/utils/app_constants.dart';
Future<void> init()async {
//api client
Get.lazyPut(()=> ApiClient(appBaseUrl: AppConstants.BASE_URL));
//repositories
Get.lazyPut(()=> PopularProductRepo(apiClient: Get.find()));
//controllers
Get.lazyPut(()=> PopularProductController(popularProductRepo: Get.find()));
}
This is my api client 'api_client.dart'
import 'package:get/get.dart';
import 'package:my_restaurant/utils/app_constants.dart';
class ApiClient extends GetConnect implements GetxService{
late String token;
final String appBaseUrl;
late Map<String, String> _mainHeaders;
ApiClient({ required this.appBaseUrl}){
baseUrl = appBaseUrl;
timeout = Duration(seconds: 30);
token = AppConstants.TOKEN;
_mainHeaders = {
'Content-type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer $token',
};
}
Future<Response> getData(String uri) async {
try{
Response response = await get(uri);
return response;
}catch(e){
return Response(statusCode: 1, statusText: e.toString());
}
}
}
This is my repositories code 'popular_product_repo.dart'
import 'package:get/get.dart';
import 'package:my_restaurant/data/api/api_client.dart';
import 'package:my_restaurant/utils/app_constants.dart';
class PopularProductRepo extends GetxService{
final ApiClient apiClient;
PopularProductRepo({required this.apiClient});
Future<Response> getPopularProductList() async{
return await apiClient.getData(AppConstants.POPULAR_PRODUCT_URI);
}
}
and this is my controller code 'popular_product_controller.dart'
import 'package:my_restaurant/data/repository/popular_product_repo.dart';
import 'package:my_restaurant/models/products_model.dart';
class PopularProductController extends GetxController{
final PopularProductRepo popularProductRepo;
PopularProductController({required this.popularProductRepo});
List<dynamic> _popularProductList = [];
List<dynamic> get popularProductList => _popularProductList;
Future<void> getPopularProductList()async {
Response response = await popularProductRepo.getPopularProductList();
if(response.statusCode == 200){
print("got products");
_popularProductList = [];
_popularProductList.addAll(Product.fromJson(response.body).products);
//print(_popularProductList);
update();
}else{
print("No products");
}
}
}
This is my modal code 'products_modal.dart'
class Product {
int? _totalSize;
int? _typeId;
int? _offset;
late List<ProductModal> _products;
List<ProductModal> get products=> _products;
Product({required totalSize, required typeId, required offset, required products}) {
this._totalSize = totalSize;
this._typeId = typeId;
this._offset = offset;
this._products = products;
}
Product.fromJson(Map<String, dynamic> json) {
_totalSize = json['total_size'];
_typeId = json['type_id'];
_offset = json['offset'];
if (json['products'] != null) {
_products = <ProductModal>[];
json['products'].forEach((v) {
_products!.add(ProductModal.fromJson(v));
});
}
}
}
class ProductModal {
int? id;
String? name;
String? description;
int? price;
int? stars;
String? img;
String? location;
String? createdAt;
String? updatedAt;
int? typeId;
ProductModal(
{this.id,
this.name,
this.description,
this.price,
this.stars,
this.img,
this.location,
this.createdAt,
this.updatedAt,
this.typeId});
ProductModal.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
description = json['description'];
price = json['price'];
stars = json['stars'];
img = json['img'];
location = json['location'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
typeId = json['type_id'];
}
}
this is my main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:my_restaurant/controllers/popular_product_controller.dart';
import 'package:my_restaurant/pages/food/popular_food_detail.dart';
import 'package:my_restaurant/pages/food/recommended_food_detail.dart';
import 'package:my_restaurant/pages/home/food_page_body.dart';
import 'pages/home/main_food_page.dart';
import 'package:my_restaurant/helper/dependencies.dart' as dep;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await dep.init();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
Get.find<PopularProductController>().getPopularProductList();
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
)
);
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'My Restaurant',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainFoodPage(),
);
}
}
CodePudding user response:
The response you are getting is JSON encoded value which is a string whereas in popular product controller you have this line written
_popularProductList.addAll(Product.fromJson(response.body).products);
In this line Product.fromJson wants a Map<String, dynamic>, you can solve this issue through this.
Map rawData = jsonDecode(response.body);
_popularProductList.addAll(Product.fromJson(rawData).products);
This will solve your problem.