Related
I'm using Flutter, I need to save image in SQLite as BLOB, then display it in my page.
I did it as String and it works fine but not image with 1.5 MB size, the app get unhanded exception, I tried to do it as blob but I could not find any tutorial anywhere.
My model:
import 'package:flutter/services.dart';
const String tablePersonal = 'personal_info';
class PersonalFields {
static final List<String> values = [
id,
name,
logo,
];
static const String id = '_id';
static const String name = 'name';
static const String logo = 'logo';
}
class PersonalInfoModel {
int? id;
final String name;
final Uint8List? logo;
PersonalInfoModel({
this.id,
required this.name,
this.logo,
});
PersonalInfoModel copy({
int? id,
String? name,
Uint8List? logo,
}) =>
PersonalInfoModel(
id: id ?? this.id,
name: name ?? this.name,
logo: logo ?? this.logo,
);
static PersonalInfoModel fromJson(Map<String, Object?> json) =>
PersonalInfoModel(
id: json[PersonalFields.id] as int?,
name: json[PersonalFields.name] as String,
logo: json[PersonalFields.logo] as Uint8List?,
);
Map<String, dynamic> toJson() => {
PersonalFields.id: id,
PersonalFields.name: name,
PersonalFields.logo: logo,
};
}
SQL Helper: after create the table I just make insert null record to save the id = 1 so that I will just update the record. That is means the table will only get one record.
batch.execute('''
CREATE TABLE IF NOT EXISTS $tablePersonal
(
${PersonalFields.id} $idType,
${PersonalFields.name} $textType,
${PersonalFields.logo} $blobType
)
''');
batch.execute('''
INSERT INTO $tablePersonal
(
${PersonalFields.name}
)
VALUES
(
''
)
''');
//read personal info
Future<List<PersonalInfoModel>> getPesonalInfo() async {
var db = await instanace.database;
final result = await db.query(tablePersonal);
return result.map((json) => PersonalInfoModel.fromJson(json)).toList();
}
Future<int> updatePersonalInfo(PersonalInfoModel personalInfoModel) async {
final db = await instanace.database;
return db.update(
tablePersonal,
personalInfoModel.toJson(),
where: '${PersonalFields.id} = ?',
whereArgs: [personalInfoModel.id],
);
}
My Page:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:ledger/database/sql_helper.dart';
import 'package:ledger/l10n/app_local.dart';
import 'package:ledger/models/personal_info_model.dart';
class PersonalInfoPage extends StatefulWidget {
const PersonalInfoPage({Key? key}) : super(key: key);
#override
State<PersonalInfoPage> createState() => _PersonalInfoPageState();
}
class _PersonalInfoPageState extends State<PersonalInfoPage> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _nameController = TextEditingController();
double boxWidth = 10;
double boxHieght = 10;
XFile? xImage;
var bytes;
final ImagePicker _picker = ImagePicker();
late List<PersonalInfoModel> personalList;
late PersonalInfoModel existPersonal;
bool isLoading = true;
#override
void initState() {
super.initState();
getPersonalInfo();
}
Future pickImage() async {
try {
xImage = await _picker.pickImage(source: ImageSource.gallery);
if (xImage == null) return;
final imagePath = File(xImage!.path);
bytes = imagePath;
setState(() {});
} on PlatformException catch (e) {
print('Failed to pick image: $e');
}
}
Future getPersonalInfo() async {
final data = await SQLHelper.instanace.getPesonalInfo();
setState(() {
personalList = data;
getData();
isLoading = false;
});
}
getData() {
existPersonal = personalList.firstWhere((element) => element.id == 1);
_nameController.text = existPersonal.name;
bytes = existPersonal.logo;
}
Future updatePersonalInfo(PersonalInfoModel personalInfoModel) async {
await SQLHelper.instanace.updatePersonalInfo(personalInfoModel);
getPersonalInfo();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocal.loc.personal_info),
actions: [
IconButton(
onPressed: () {
PersonalInfoModel personalInfoModel = PersonalInfoModel(
id: 1,
name: _nameController.text,
logo: bytes);
updatePersonalInfo(personalInfoModel);
},
icon: const Icon(Icons.save_as_outlined),
),
],
),
body: isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
child: Form(
key: _formKey,
child: Column(
children: [
SizedBox(height: boxHieght),
TextFormField(
controller: _nameController,
decoration: InputDecoration(
filled: true,
labelText: AppLocal.loc.name,
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
print('xxxxxx');
pickImage();
},
child: Text('from Gallary'),
),
],
),
Container(
color: Colors.grey.shade100,
height: 150,
width: 150,
child: bytes != null
? Image.memory(bytes)
: Image.asset('assets/logo.png'),
),
],
),
),
);
}
}
Here is how you can convert it into a blob and save it to SQLite
Future pickImage(ImageSource source) async {
try {
final image = await ImagePicker.pickImage(source: source);
final imagePath = File(image.path);
List<int> bytes = await image.readAsBytes();
String base64 = base64Encode(bytes);// here it is. Save it to sqflite
} on PlatformException catch (e) {
print(e);
}
}
for getting from SQLite
String blobImageFromSqflite; //get from sqflite
Uint8List _bytesImage = Base64Decoder().convert(blobImageFromSqflite);
to display it;
Image.memory(
_bytesImage,
);
I created project to look for sports stadiums in my town. It gets all data from website's Swagger API, data like addresses, price, images and names.
Swagger host: http://admin.sports.com.kg/swagger/
I created ApiRemote to get data from swagger host. It worked perfectly first week, but later it returned exception. Maybe it's because of http.
Terminal returns this error:
E/flutter (26867): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Failed host lookup: 'admin.sports.com.kg'
It says it has an exception in this line:
var responses = await client.get(uri);
import 'dart:async';
import 'dart:convert';
import 'package:untitled/models/post.dart';
import 'package:http/http.dart' as http;
class RemoteService {
Future<List<Result>?> getPosts() async {
List<Result> list;
var client = http.Client();
var uri = Uri.parse('http://admin.sports.com.kg/api/sports_areas');
var responses = await client.get(uri);
if (responses.statusCode == 200) {
final parsed = json.decode(responses.body) as Map<String, dynamic>;
list = parsed['results'].map<Result>((e) =>Result.fromJson(e)).toList();
print(parsed['results']);
// final p = Post.fromJson(parsed);
// list.add(p);
return list;
}
}
}
Post file that contains all data from Swagger
import 'dart:convert';
Post postFromJson(String str) => Post.fromJson(json.decode(str));
String postToJson(Post data) => json.encode(data.toJson());
class Post {
Post({
required this.next,
this.previous,
required this.count,
required this.pageSize,
required this.numPages,
required this.results,
});
int next;
dynamic previous;
int count;
int pageSize;
int numPages;
List<Result> results;
factory Post.fromJson(Map<String, dynamic> json) => Post(
next: json["next"],
previous: json["previous"],
count: json["count"],
pageSize: json["page_size"],
numPages: json["num_pages"],
results:
List<Result>.from(json["results"].map((x) => Result.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"next": next,
"previous": previous,
"count": count,
"page_size": pageSize,
"num_pages": numPages,
"results": List<dynamic>.from(results.map((x) => x.toJson())),
};
}
class Result {
Result({
required this.id,
required this.title,
required this.price,
required this.address,
required this.image,
});
int id;
String title;
int price;
String address;
String image;
factory Result.fromJson(Map<String, dynamic> json) => Result(
id: json["id"],
title: json["title"],
price: json["price"],
address: json["address"],
image: json["image"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"price": price,
"address": address,
"image": image,
};
}
Main Page class
class _HomePageState extends State<HomePage> {
int _selind = 0;
List<Result>? _stadiums;
var isLoaded = false;
#override
void initState() {
super.initState();
getData();
}
void getData() async {
_stadiums = (await RemoteService().getPosts()) as List<Result>?;
if (_stadiums != null) {
setState(() {
isLoaded = true;
});
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.indigo[50],
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 30),
child: Visibility(
visible: isLoaded,
child: ListView.builder(
itemCount: _stadiums?.length,
itemBuilder: (context, index) {
return Column(
// child: _widgetopt.elementAt(_selind),
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Column(
children: [
Image.network(_stadiums![index].image),
Text('Sportclubs "${_stadiums![index]
.title}"', textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 20,
fontWeight: FontWeight.bold),),
Row(
children: [
Icon(Icons.location_on_outlined,
color: Colors.redAccent, size: 40,),
Text(_stadiums![index].address),
],
)
]
),
),
SizedBox(
height: 10,
),
],
);
}),
replacement: Center(child: CircularProgressIndicator()),
),
),),);
}
}
fetchData is my function from where I call the API and put the data into an object, which is UserModel Somehow, it is working perfectly. But I want to put my data into a list because I want to make a search function where I can search by name. Look into my code, which will help you to understand.
Future<UserModel>? futureUser;
Future<UserModel>? fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
// this is a way which I've tried already and it works
// return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
But I want to put the data into a list and make the search available. Like if i put some name like r+a+b+b+i, it will show the matching name from the API.
I have tried this but I am not clear about the consepet. I am not familiar with how to manipulate the JSON data in a list or object or how to convert an object into a list.
List<UserModel>? userList = [];
Future<UserModel>? fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
// var result= UserModel.fromJson(jsonDecode(response.body));
// print('this is result $userList');
return userList.add(UserModel.fromJson(jsonDecode(response.body)));
// this is an way which i tried already and its works
// return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
This is my whole code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:learning_1ui_6228/utilities/app_colors.dart';
import 'package:learning_1ui_6228/utilities/helper.dart';
import 'package:learning_1ui_6228/utilities/widgets/app_line.dart';
import 'package:learning_1ui_6228/utilities/widgets/list_tile_widget.dart';
import 'package:learning_1ui_6228/views/nav_pages/profile_page.dart';
import 'package:http/http.dart' as http;
import '../model/UserModel.dart';
class FirstScreen extends StatefulWidget {
const FirstScreen({Key? key}) : super(key: key);
#override
State<FirstScreen> createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
Future<UserModel>? futureUser;
TextEditingController textController = TextEditingController();
// List<UserModel> userList=[];
#override
void initState() {
// searchedList = userList;
futureUser = fetchData();
super.initState();
}
List<UserModel>? userList = [];
Future<UserModel>? fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
// var result= UserModel.fromJson(jsonDecode(response.body));
// print('this is result $userList');
return userList.add(UserModel.fromJson(jsonDecode(response.body)));
// this is an way which i tried already and its works
// return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
List<UserModel> searchedList = [];
void searchUser(String enteredData){
print('entered word + ${enteredData}');
searchedList = [];
for(int i=0; i<userList!.length; i++){
if(userList[i].data![i].firstName!.toLowerCase().contains(enteredData.toLowerCase())){
searchedList.add(userList![i]);
}
}
}
#override
Widget build(BuildContext context) {
//print('user list data + $searchedList');
return SafeArea(
child: Scaffold(
backgroundColor: Color(0xfff8f8fa),
body: Column(
children: [
//1st Section
Container(
height: HelperClass.h250,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: AppColors.gradientColor,
),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(HelperClass.r10),
bottomLeft: Radius.circular(HelperClass.r10))),
child: Column(
children: <Widget>[
//Text and cross button
Container(
margin: EdgeInsets.only(
left: HelperClass.w10,
right: HelperClass.w10,
top: HelperClass.h20),
height: HelperClass.h50,
// color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: IconButton(
onPressed: () {},
icon: Icon(
Icons.clear,
color: Colors.white,
size: 30,
))),
Expanded(
child: Container(
margin: EdgeInsets.only(right: 30),
alignment: Alignment.center,
// color: Colors.lightBlueAccent,
child: Text(
'Search',
style: TextStyle(
fontSize: HelperClass.t25,
fontWeight: FontWeight.bold,
color: Colors.white),
),
),
),
],
),
),
SizedBox(
height: HelperClass.h25,
),
//Search Bar
Container(
margin: EdgeInsets.only(
left: HelperClass.w10, right: HelperClass.w10),
//color: Colors.amber,
height: HelperClass.h70,
width: double.infinity,
child: TextField(
controller: textController,
onChanged: (name) {
setState(() {
searchUser(name);
});
},
decoration: InputDecoration(
prefix: Icon(
Icons.search,
size: 26,
),
suffix: IconButton(
onPressed: () {
setState(() {
textController.clear();
searchedList = userList;
});
},
icon: Icon(
Icons.clear,
size: 26,
),
),
hintText: 'Search',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(3),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Colors.white,
),
),
),
],
),
),
// List View
Expanded(
child: FutureBuilder<UserModel>(
future: futureUser,
builder: (context, snapshot){
if(snapshot.hasData){
return ListView.builder(
itemCount: snapshot.data!.data!.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(10),
child: Column(
children: [
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfilePage(
userName:snapshot.data!.data![index].firstName??'',
followers: snapshot.data!.data![index].id.toString(),
address: snapshot.data!.data![index].email.toString(),
following: snapshot.data!.data![index].lastName.toString(),
imageUrl: snapshot.data!.data![index].avatar.toString(),
),
));
},
child: ListTileWidgets(
following: snapshot.data!.data![index].lastName.toString(),
address: snapshot.data!.data![index].email.toString(),
imageUrl:snapshot.data!.data![index].avatar.toString(),
name: snapshot.data!.data![index].firstName??'',
followersCount:
'Followers: ${snapshot.data!.data![index].id.toString()}',
iconWidget: Icon(
Icons.person_add_alt_outlined,
color: Colors.red,
size: 25,
),
),
),
AppLine(
paddingLeft: 10,
paddingRight: 10,
heightLine: 1,
lineColor: Colors.grey),
],
),
);
},
);
}
else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return Center(child: CircularProgressIndicator());
}),
),
],
),
),
);
}
}
This is my UserModel class
import 'dart:convert';
UserModel userModelFromJson(String str) => UserModel.fromJson(json.decode(str));
String userModelToJson(UserModel data) => json.encode(data.toJson());
class UserModel {
UserModel({
this.page,
this.perPage,
this.total,
this.totalPages,
this.data,
this.support,});
UserModel.fromJson(dynamic json) {
page = json['page'];
perPage = json['per_page'];
total = json['total'];
totalPages = json['total_pages'];
if (json['data'] != null) {
data = [];
json['data'].forEach((v) {
data?.add(Data.fromJson(v));
});
}
support = json['support'] != null ? Support.fromJson(json['support']) : null;
}
int? page;
int? perPage;
int? total;
int? totalPages;
List<Data>? data;
Support? support;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['page'] = page;
map['per_page'] = perPage;
map['total'] = total;
map['total_pages'] = totalPages;
if (data != null) {
map['data'] = data?.map((v) => v.toJson()).toList();
}
if (support != null) {
map['support'] = support?.toJson();
}
return map;
}
}
Support supportFromJson(String str) => Support.fromJson(json.decode(str));
String supportToJson(Support data) => json.encode(data.toJson());
class Support {
Support({
this.url,
this.text,});
Support.fromJson(dynamic json) {
url = json['url'];
text = json['text'];
}
String? url;
String? text;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['url'] = url;
map['text'] = text;
return map;
}
}
Data dataFromJson(String str) => Data.fromJson(json.decode(str));
String dataToJson(Data data) => json.encode(data.toJson());
class Data {
Data({
this.id,
this.email,
this.firstName,
this.lastName,
this.avatar,});
Data.fromJson(dynamic json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['email'] = email;
map['first_name'] = firstName;
map['last_name'] = lastName;
map['avatar'] = avatar;
return map;
}
}
this is my api link
https://reqres.in/api/users?page=2
No need to add UserModel to list.
change this
class _FirstScreenState extends State<FirstScreen> {
UserModel? usermodel;
List<Data?> searchResult= [];
change your fetch data . this will return UserModel as result.
Future<UserModel?> fetchData() async {
final response =
await http.get(Uri.parse('https://reqres.in/api/users?page=2'));
print('This is Response: $response');
if (response.statusCode == 200) {
return UserModel.fromJson(jsonDecode(response.body));
} else {
return throw Exception('Failed to load album');
}
}
create init function to set your initial data
void initFunction() async {
UserModel data = await fetchData(); // you have to await until get the response
//then setState to local variable so it can display to widget
// if you skip this , your usermodel is null
setState ({
usermodel = data ;
});
}
then in your initState
#override
void initState() {
initFunction();
super.initState();
}
usermodel.data consist of data user.
to then you can apply logic to search user from the list.
void searchUser(String enteredData){
List<Data?> temp = [];
for(int i=0; i<usermodel.data.length; i++){
if(enteredData.toLowerCase() == usermodel.data[i].firstName.toLowerCase()){
temp.add(usermodel.data[i];
}
}
// you need to setState again
setState({
searchResult = temp;
});
}
last in you can acces the data in userModel
#override
Widget build(BuildContext context) {
//print('user list data + $searchedList');
return SafeArea(
child: Scaffold(
backgroundColor: Color(0xfff8f8fa),
body: Column(
children: [
Text('${usermodel.data.length}'), /// number all list user
Text('${searchResult.length}'), /// number search user
// now you have list all user
// and all searched list user
// additional, you need to add logic when query is empty
.................
maybe there error in null-safety, please debug first.
You can simply do this
var myList= []; // declare an empty list
if (response.statusCode == 200) {
var result= UserModel.fromJson(jsonDecode(response.body));
if(result != null){
myList.clear();
myList.addAll(result);
}
}
eg:details about the questions....................................................................I have a model class Name is RasiphalaContent . i want to access main_img,title to display in home page. but not able to access in home page.below i've attached the model class and Home page code please find and check it.
Home Page:
import 'dart:io';
import 'dart:math';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'DetailsPage.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'Model/RasiphalaContent.dart';
var paddingBottom = 48.0;
var androidDeviceInfo;
var identifier;
var token;
var token1;
class HomePage extends StatelessWidget {
final String apiUrl = "https://www.sofikart.com/MobileApi/banners";
final String apiUrl1 =
"https://wayindia.net/indigo/odia_rashifal/rasifhala.php";
Future<RasiphalaContent> fetchData() async {
final response = await http.get(Uri.parse(apiUrl1));
print(response.body);
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return RasiphalaContent.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');
}
}
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ଆଜିର ରାଶିଫଳ'),
centerTitle: true,
),
body: Container(
child: FutureBuilder<RasiphalaContent>(
future: fetchData(),
builder: (BuildContext context, snapshot) {
final data = snapshot.data;
_getId();
if (snapshot.hasData) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 20,
mainAxisSpacing: 25,
),
padding: EdgeInsets.all(13),
shrinkWrap: true,
itemBuilder: (ctx, index) {
return InkWell(
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(12))),
child: Column(
children: [
Expanded(
flex: 9,
child: ClipRRect(
borderRadius:
BorderRadius.all(Radius.circular(12)),
child: Image.network(,
fit: BoxFit.fill)),
),
Expanded(
flex: 2,
child: Text(
title(),
style: TextStyle(
color: Colors.black, fontSize: 17),
)),
],
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsPage(),
),
);
},
);
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
Future<String?> _getId() async {
identifier;
final DeviceInfoPlugin deviceInfoPlugin = new DeviceInfoPlugin();
if (Platform.isAndroid) {
// import 'dart:io'
var build = await deviceInfoPlugin.androidInfo;
identifier = build.androidId!; //UUID for Android
token = await FirebaseMessaging.instance.getToken();
token1 = await FirebaseMessaging.instance.getToken();
login();
}
}
login() async {
final response = await http.post(
"https://wayindia.net/indigo/odia_rashifal/device_create.php",
body: {
//"flag": 1.toString(),
"device_id": identifier,
"device_token": token,
});
final data = jsonDecode(response.body);
int value = data['status'];
String message = data['message'];
if (value == 1) {
print(message);
} else {
print("fail");
print(message);
}
}
}
Model Class :
// To parse this JSON data, do
//
// final rasiphalaContent = rasiphalaContentFromJson(jsonString);
import 'dart:convert';
RasiphalaContent rasiphalaContentFromJson(String str) => RasiphalaContent.fromJson(json.decode(str));
String rasiphalaContentToJson(RasiphalaContent data) => json.encode(data.toJson());
class RasiphalaContent {
RasiphalaContent({
required this.status,
required this.message,
required this.data,
});
int status;
String message;
List<Datum> data;
factory RasiphalaContent.fromJson(Map<String, dynamic> json) => RasiphalaContent(
status: json["status"],
message: json["message"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
required this.id,
required this.title,
required this.content,
required this.engTitle,
required this.mainImg,
required this.image2,
required this.image3,
required this.image4,
});
String id;
String title;
String content;
String engTitle;
String mainImg;
String image2;
String image3;
String image4;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
title: json["title"],
content: json["content"],
engTitle: json["eng_title"],
mainImg: json["main_img"],
image2: json["image_2"],
image3: json["image_3"],
image4: json["image_4"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"content": content,
"eng_title": engTitle,
"main_img": mainImg,
"image_2": image2,
"image_3": image3,
"image_4": image4,
};
}
I'm new to flutter. I'm trying to learn about flutter rest api.
When I'm trying to post data using fullter api(using http dart package), It shows me this error.
I tried to fix it doing some changes to my code, but I still unable to fix it. Here the code that I trying to execute.
Model
import 'dart:convert';
DataModel dataModelFromJSON(String str) => DataModel.fromJson(jsonDecode(str));
String dataModelToJson(DataModel data) => json.encode(data.toJson());
class DataModel {
DataModel(
{required this.name,
required this.job,
required this.id,
required this.createdAt});
String name;
String job;
String id;
String createdAt;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
name: json['name'],
job: json['job'],
id: json['id'],
createdAt: json['createdAt']);
Map<String, dynamic> toJson() =>
{"name": name, "job": job, "id": id, "createdAt": createdAt};
}
main.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'DataModel.dart';
void main() {
runApp(
MaterialApp(
home: MyHomePage(),
),
);
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
Future<DataModel?> submitData(String name, String job) async {
var response = await http.post(
Uri.https('reqres.in', 'api/users'),
body: {"name": name, "job": job},
);
var data = response.body;
print(data);
if (response.statusCode == 201) {
String responseString = response.body;
dataModelFromJSON(responseString);
} else
return null;
}
class _MyHomePageState extends State<MyHomePage> {
late DataModel _dataModel;
TextEditingController nameController = TextEditingController();
TextEditingController jobController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text('HTTP Post'),
),
),
body: Container(
padding: EdgeInsets.all(20.0),
child: Column(
children: [
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(), hintText: 'Name'),
controller: nameController,
),
SizedBox(height: 20.0),
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(), hintText: 'Job'),
controller: jobController,
),
ElevatedButton(
onPressed: () async {
String name = nameController.text;
String job = jobController.text;
DataModel? data = await submitData(name, job);
setState(() {
_dataModel = data!;
});
},
child: Text("Submit"),
)
],
),
),
);
}
}
I appreciate if somebody can help me to fix this issue.
You are not returning data in your function
add return here
return dataModelFromJSON(responseString);
Now your Function will be like this
Future<DataModel?> submitData(String name, String job) async {
var response = await http.post(
Uri.https('reqres.in', 'api/users'),
body: {"name": name, "job": job},
);
var data = response.body;
print(data);
if (response.statusCode == 201) {
String responseString = response.body;
return dataModelFromJSON(responseString);
} else
return null;
}
Remove ! from this line _dataModel = data!;
In your data model you have this
String responseString = response.body;
dataModelFromJSON(responseString);
} else
return null;
}
Which will return null if the status code of the request is not 201, which it's doing so using ! To do the null check is what's causing the error.