I try to create user using api but it throws an exception when executed.
So, here is my json response as below.
{
"success": 1,
"user": {
"user_id": "612f02fc4ae19",
"name": "Test User3",
"mobile": "8347406873",
"email": "dhaval#gmail.com",
"standard_id": "5d1594e283e1a",
"medium_id": "5d15938aa1344",
"location": "Vyara",
"created_at": "2021-09-01"
},
"msg": "Your account has been created successfully."
}
As response i created model class as below in signup_model.dart file.
import 'dart:convert';
SignupModel signupModelFromJson(String str) =>
SignupModel.fromJson(json.decode(str));
String signupModelToJson(SignupModel data) => json.encode(data.toJson());
class SignupModel {
SignupModel({
this.success,
this.user,
this.msg,
});
int? success;
UserRegistration? user;
String? msg;
factory SignupModel.fromJson(Map<String, dynamic> json) => SignupModel(
success: json["success"],
user: UserRegistration.fromJson(json["user"]),
msg: json["msg"],
);
Map<String, dynamic> toJson() => {
"success": success,
"user": user?.toJson(),
"msg": msg,
};
}
class UserRegistration {
UserRegistration({
this.userId,
this.name,
this.mobile,
this.email,
this.standardId,
this.mediumId,
this.location,
this.createdAt,
});
String? userId;
String? name;
String? mobile;
String? email;
String? standardId;
String? mediumId;
String? location;
DateTime? createdAt;
factory UserRegistration.fromJson(Map<String, dynamic> json) =>
UserRegistration(
userId: json["user_id"],
name: json["name"],
mobile: json["mobile"],
email: json["email"],
standardId: json["standard_id"],
mediumId: json["medium_id"],
location: json["location"],
createdAt: DateTime.parse(json["created_at"]),
);
Map<String, dynamic> toJson() => {
"user_id": userId,
"name": name,
"mobile": mobile,
"email": email,
"standard_id": standardId,
"medium_id": mediumId,
"location": location,
"created_at":
"${createdAt?.year.toString().padLeft(4, '0')}-${createdAt?.month.toString().padLeft(2, '0')}-${createdAt?.day.toString().padLeft(2, '0')}",
};
}
Function which i created as below in api_manager.dart file.
Future<UserRegistration> createUser(
String name,
String email,
String mobile,
String standardId,
String mediumId,
) async {
final registrationUrl = "$baseUrl/user/register";
final response = await http.post(
Uri.parse(registrationUrl),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'name': name,
'email': email,
'mobile': mobile,
'standard_id': standardId,
'medium_id': mediumId,
}),
);
if (response.statusCode == 200) {
print(response.body);
return UserRegistration.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to create User.');
}
}
And My signup screen Code as below in signup_screen.dart file.
class _SignUp1State extends State<SignUp1> {
final baseUrl = SankalpApi().baseUrl;
bool value = false;
var _standards = <Standard>[];
var _mediums = <Medium>[];
Standard? selectedStandard;
Medium? selectedMedium;
var standardId;
var mediumId;
final TextEditingController _nameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _mobileController = TextEditingController();
Future<UserRegistration>? userRegistration;
GlobalKey<FormState> _globalFormKey = GlobalKey<FormState>();
bool isApiCallProcess = false;
#override
void initState() {
super.initState();
ApiManager().getStandards().then((standards) {
setState(() {
_standards = standards;
});
});
}
void onMediumChange(standard) {
setState(() {
selectedStandard = standard;
_mediums = [];
});
String mediumUrl =
"$baseUrl/medium/get_by_course_id?standard_id=${selectedStandard?.standardId}";
ApiManager().getMediums(mediumUrl).then((List<Medium> value) => {
setState(() {
_mediums = value;
})
});
}
#override
Widget build(BuildContext context) {
final Shader linearGradient = LinearGradient(
colors: <Color>[
Color(0xff8921aa),
Color(0xffDA44bb),
],
).createShader(new Rect.fromLTWH(0.0, 0.0, 200.0, 70.0));
return SingleChildScrollView(
child: Form(
key: _globalFormKey,
child: Container(
padding: EdgeInsets.all(12),
child: Column(
children: [
SizedBox(height: 30),
Text(
'Learn from wide range of videos and tutorials',
textAlign: TextAlign.center,
style: GoogleFonts.openSans(
fontSize: 15,
color: Colors.grey[600],
),
),
TextFormField(
decoration: InputDecoration(labelText: "Full Name"),
controller: _nameController,
validator: (value) {
if (value!.isEmpty) {
return "Name is required.";
}
return null;
},
onSaved: (value) {
//this.userRegistration.name = value.toString().trim();
},
),
SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(labelText: "Email"),
controller: _emailController,
validator: (value) {
if (value!.isEmpty) {
return 'Email is required.';
}
if (!RegExp("^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]")
.hasMatch(value)) {
return 'Enter valid Email';
}
return null;
},
onSaved: (value) {
//this.userRegistration.email = value.toString().trim();
},
),
SizedBox(height: 10),
TextFormField(
decoration: InputDecoration(labelText: "Mobile Number"),
controller: _mobileController,
validator: (value) {
String pattern = r'(^[0-9]*$)';
RegExp regExp = new RegExp(pattern);
if (value!.length == 0) {
return "Mobile is required";
} else if (value.length != 10) {
return "Mobile number must 10 digits";
} else if (!regExp.hasMatch(value)) {
return "Mobile Number must be digits";
}
return null;
},
onSaved: (value) {
//this.userRegistration.mobile = value.toString().trim();
},
),
SizedBox(height: 20),
DropdownButtonFormField<Standard>(
validator: (value) {
if (value == null) {
return "Select Standard";
}
},
isExpanded: true,
hint: Text('Select Standard'),
value: selectedStandard,
items: _standards.map((Standard standard) {
return DropdownMenuItem<Standard>(
value: standard,
child: Text(standard.standardName),
);
}).toList(),
onSaved: (value) {
selectedStandard = value;
//this.userRegistration.standardId = value!.standardId;
},
onChanged: (val) {
setState(() {
selectedStandard = val;
standardId = val?.standardId;
// print("StandardId : ${val?.standardId}");
// print("StandardId : ${val?.standardName}");
onMediumChange(val);
});
},
),
SizedBox(height: 20),
DropdownButtonFormField<Medium>(
validator: (value) {
if (value == null) {
return "Select Medium";
}
},
isExpanded: true,
hint: Text('Select Medium'),
value: selectedMedium,
items: _mediums.map((Medium medium) {
return DropdownMenuItem<Medium>(
value: medium,
child: Text(medium.mediumName),
);
}).toList(),
onSaved: (value) {
selectedMedium = value;
//this.userRegistration.mediumId = value!.mediumId;
},
onChanged: (val) {
setState(() {
selectedMedium = val;
mediumId = val?.mediumId;
// print("Medium id : ${val?.mediumId}");
// print("Medium id : ${val?.mediumName}");
});
}),
SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton(
onPressed: () {
if (validateAndSave()) {
setState(() {
this.isApiCallProcess = true;
print(_nameController.text);
print(_emailController.text);
print(_mobileController.text);
print(standardId);
print(mediumId);
userRegistration = ApiManager().createUser(
_nameController.text,
_emailController.text,
_mobileController.text,
standardId,
mediumId,
);
});
}
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25))),
child: Ink(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0xff8921aa),
const Color(0xffDA44bb),
],
),
borderRadius: BorderRadius.circular(25)),
child: Container(
width: 100,
height: 50,
alignment: Alignment.center,
child: Text(
'SIGNUP',
style: TextStyle(
fontSize: 15,
),
),
),
),
),
],
),
SizedBox(
height: 60,
),
Text('Already have an account?'),
TextButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Login2()));
},
child: Text(
'Login',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
foreground: new Paint()..shader = linearGradient,
),
),
)
],
),
),
),
);
}
bool validateAndSave() {
final form = _globalFormKey.currentState;
if (form!.validate()) {
form.save();
return true;
}
return false;
}
}
So, when i try to sign up it thorows an Exception as below.
So what is the problem in given code.?
Related
Flutter beginner here. Working on a flutter project where I can submit a form where I can upload it's content in firebase. I took the data from TextFormField and DropDownButton and the images from ImagePicker. I can upload the image file perfectly to the firebase but the data are not uploading. Here is the code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
class AddDoctor extends StatefulWidget {
#override
State<AddDoctor> createState() => AddDoctorState();
}
class AddDoctorState extends State<AddDoctor> {
late String name;
late int age;
late String description;
String specialistValue = 'Select Specialist';
String hospitalValue = 'Select Hospital';
List<String> imageUrlList = [];
final controllerName = TextEditingController();
final controllerAge = TextEditingController();
final controllerDesciption = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final FirebaseStorage _firebaseStorage = FirebaseStorage.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final ImagePicker _picker = ImagePicker();
XFile? image;
void pickDoctorImage() async {
try {
final pickedImage = await _picker.pickImage(source: ImageSource.gallery);
setState(() {
image = pickedImage!;
});
} catch (e) {}
}
Widget displayImage() {
return Image.file(File(image!.path));
}
Future<void> uploadImage() async {
Reference ref =
_firebaseStorage.ref('products/${path.basename(image!.path)}');
await ref.putFile(File(image!.path)).whenComplete(() async {
await ref.getDownloadURL().then((value) {
imageUrlList.add(value);
});
});
}
void uploadInfo() async {
CollectionReference infoRef = _firestore.collection('DoctorList');
await infoRef.doc().set({
'name': name,
'age': age,
'description': description,
'specialist': specialistValue,
'hospital': hospitalValue,
'doctorImage': imageUrlList,
}).whenComplete(() {
Navigator.pop(context);
});
}
void uploadDoctorInfo() async {
await uploadImage().whenComplete(() => uploadInfo);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFD9E4EE),
appBar: AppBar(
title: const Text('Add Doctor'),
actions: [
IconButton(
icon: const Icon(Icons.menu),
onPressed: () {},
),
],
),
body: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(16),
children: <Widget>[
TextFormField(
keyboardType: TextInputType.name,
validator: (value) {
if (value!.isEmpty) {
return 'Please Name must not be empty';
} else {
return null;
}
},
controller: controllerName,
decoration: const InputDecoration(
label: Text('Name'),
),
onSaved: (value) {
name = value!;
},
),
const SizedBox(height: 10),
TextFormField(
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) {
return 'Please Age must not be empty';
} else {
return null;
}
},
controller: controllerAge,
decoration: const InputDecoration(
label: Text('Age'),
),
onSaved: (value) {
age = int.parse(value!);
},
),
const SizedBox(height: 10),
DropdownButton(
borderRadius: BorderRadius.circular(30),
value: specialistValue,
items: specialistList.map<DropdownMenuItem<String>>((e) {
return DropdownMenuItem(
value: e,
child: Text(e),
);
}).toList(),
onChanged: (String? value) {
setState(() {
specialistValue = value!;
});
},
),
DropdownButton(
borderRadius: BorderRadius.circular(30),
value: hospitalValue,
items: hospitalList.map<DropdownMenuItem<String>>((e) {
return DropdownMenuItem(
value: e,
child: Text(e),
);
}).toList(),
onChanged: (String? value) {
setState(() {
hospitalValue = value!;
});
},
),
const SizedBox(height: 10),
TextFormField(
keyboardType: TextInputType.number,
validator: (value) {
if (value!.isEmpty) {
return 'Please Description must not be empty';
} else {
return null;
}
},
maxLength: 100,
maxLines: 3,
controller: controllerDesciption,
decoration: const InputDecoration(
label: Text('Description'),
),
onChanged: (value) {
description = value;
},
),
const SizedBox(height: 10),
// CircleAvatar(
// radius: 50,
// backgroundImage: image != null ? FileImage(image) : null,
// ),
InkWell(
onTap: () {
setState(() {
image = null;
});
},
child: Container(
padding: const EdgeInsetsDirectional.only(top: 60),
height: 150,
width: 150,
decoration: const BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: Center(
child: image != null
? displayImage()
: const Text(
'You have not pick any image',
style: TextStyle(fontSize: 11),
textAlign: TextAlign.center,
),
)),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: () {
pickDoctorImage();
},
child: const Text('Upload Image'),
),
const SizedBox(height: 10),
ElevatedButton(
child: const Text('Submit'),
onPressed: () {
uploadDoctorInfo();
},
),
],
),
),
);
}
}
There aren't any error in the file either. I can't figure out where the source of the problem is.
Fixed it. The problem was in
void uploadDoctorInfo() async {
await uploadImage().whenComplete(() => uploadInfo);
}
I changed it to
void uploadDoctorInfo() async {
await uploadImage().whenComplete(uploadInfo);
}
And now it's working fine
You should add for the new entry instead set data in collection. Try using the following code
void uploadInfo() async {
CollectionReference infoRef = _firestore.collection('DoctorList');
await infoRef.add({
'name': name,
'age': age,
'description': description,
'specialist': specialistValue,
'hospital': hospitalValue,
'doctorImage': imageUrlList,
}).whenComplete(() {
Navigator.pop(context);
});
}
Edited
Your are referencing uploadInfo function instead of call that. updateInfo should be called by adding (), so uploadDoctorInfo will be look like.
void uploadDoctorInfo() async {
await uploadImage().whenComplete(() => uploadInfo());
}
or
void uploadDoctorInfo() async {
await uploadImage().whenComplete(uploadInfo);
}
What could be the possible reasons for this error, please guide.
This is my code
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/product.dart';
import '../provider/products.dart';
class EditProductScreen extends StatefulWidget {
static const routeName = '/edite-product-screen';
#override
State<EditProductScreen> createState() => _EditProductScreenState();
}
class _EditProductScreenState extends State<EditProductScreen> {
final priceFocusNode = FocusNode();
final descriptionFocusNode = FocusNode();
final imageURLController = TextEditingController();
// TextEditingController listens to updates in the associated TextField and alert its listeners of any changes
final imageURLFocusNode = FocusNode();
final keyForForm = GlobalKey<FormState>();
var emptyProduct =
Product(id: "", title: "", description: "", price: 0, imageUrl: "");
var isInit = true;
var initValues = {
'title': "",
'description': "",
'price': "",
'imageURL': "",
};
#override
void initState() {
super.initState();
imageURLFocusNode.addListener(updateImageUrl);
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
if (isInit) {
final receivedProductID =
ModalRoute.of(context)?.settings.arguments as String;
if (receivedProductID != null) {
emptyProduct = Provider.of<Products>(context, listen: false)
.selectedProduct(receivedProductID);
initValues = {
'title': emptyProduct.title.toString(),
'description': emptyProduct.description.toString(),
'price': emptyProduct.price.toString(),
// 'imageURL': "",
};
imageURLController.text = emptyProduct.imageUrl as String;
}
}
isInit = false;
}
void updateImageUrl() {
if (!imageURLFocusNode.hasFocus) {
if ((!imageURLController.text.startsWith("http") &&
!imageURLController.text.startsWith("https")) ||
(!imageURLController.text.endsWith("jpg") &&
!imageURLController.text.endsWith("png") &&
!imageURLController.text.endsWith("jpeg")) ||
(imageURLController.text.isEmpty)) {
return;
}
setState(() {});
}
}
void saveTheProductBasedOnInformationOfTheForm() {
final validStatus = keyForForm.currentState?.validate();
if (!validStatus!) {
return;
}
keyForForm.currentState?.save();
if (emptyProduct.id != null) {
Provider.of<Products>(context, listen: false)
.updateProduct(emptyProduct.id as String, emptyProduct);
} else {
Provider.of<Products>(context, listen: false).addProduct(emptyProduct);
}
Navigator.of(context).pop();
}
#override
void dispose() {
imageURLFocusNode.removeListener(updateImageUrl);
priceFocusNode.dispose();
descriptionFocusNode.dispose();
imageURLController.dispose();
imageURLFocusNode.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Products"),
actions: [
IconButton(
onPressed: saveTheProductBasedOnInformationOfTheForm,
icon: Icon(Icons.save))
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: keyForForm,
child: ListView(
children: [
TextFormField(
initialValue: initValues['title'],
validator: (value) {
if (value!.isEmpty) {
return "Please enter a valid value";
} else {
return null;
}
},
decoration: InputDecoration(labelText: "Title"),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) => {
FocusScope.of(context).requestFocus(priceFocusNode),
},
onSaved: (value) {
emptyProduct = Product(
id: emptyProduct.id,
title: value,
description: emptyProduct.description,
price: emptyProduct.price,
imageUrl: emptyProduct.imageUrl,
isFavorite: emptyProduct.isFavorite);
},
),
TextFormField(
initialValue: initValues['price'],
onSaved: (value) {
emptyProduct = Product(
id: emptyProduct.id,
title: emptyProduct.title,
description: emptyProduct.description,
price: double.parse(value as String),
imageUrl: emptyProduct.imageUrl,
isFavorite: emptyProduct.isFavorite);
},
decoration: InputDecoration(labelText: "Price"),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
focusNode: priceFocusNode,
onFieldSubmitted: (_) =>
FocusScope.of(context).requestFocus(descriptionFocusNode),
validator: (value) {
if (value!.isEmpty) {
return "Please enter a valid price";
}
if (double.tryParse(value) == null) {
return "Please enter a valid number";
}
if (double.parse(value) <= 0) {
return "Please enter a value greater than 0";
} else {
return null;
}
},
),
TextFormField(
initialValue: initValues['description'],
onSaved: (value) {
emptyProduct = Product(
id: emptyProduct.id,
title: emptyProduct.title,
description: value,
price: emptyProduct.price,
imageUrl: emptyProduct.imageUrl,
isFavorite: emptyProduct.isFavorite);
},
decoration: InputDecoration(labelText: "Description"),
keyboardType: TextInputType.multiline,
maxLines: 3,
validator: (value) {
if (value!.isEmpty) {
return "Please enter a valid description";
}
if (value.length < 10) {
return "Please enter more description";
} else {
return null;
}
},
),
Row(crossAxisAlignment: CrossAxisAlignment.end, children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 10, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey)),
child: imageURLController.text.isEmpty
? Text("Please enter URL")
: Image.network(imageURLController.text),
),
Expanded(
child: TextFormField(
initialValue: initValues['imageURL'],
validator: (value) {
if (value!.isEmpty) {
return "Please enter valid Image URL";
}
if ((!value.startsWith("http") &&
!value.startsWith("https")) ||
(!value.endsWith("jpg") &&
!value.endsWith("png") &&
!value.endsWith("jpeg"))) {
return "Please enter a valid URL!";
}
},
onSaved: (value) {
emptyProduct = Product(
id: emptyProduct.id,
title: emptyProduct.title,
description: emptyProduct.description,
price: emptyProduct.price,
imageUrl: value,
isFavorite: emptyProduct.isFavorite);
},
decoration: InputDecoration(labelText: "Image URL"),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: imageURLController,
maxLines: 3,
focusNode: imageURLFocusNode,
onFieldSubmitted: (_) {
saveTheProductBasedOnInformationOfTheForm();
},
),
),
])
],
)),
),
);
}
}
The screen opens without error when (receivedProductID != null), but shows the following error when (receivedProductID == null);
see errror image
And when I try going back from the screen, I see this error
see error image
What could be the possible reasons for this error, please guide.
The reason for the first error is this type cast:
final receivedProductID = ModalRoute.of(context)?.settings.arguments as String;
You cast a nullable value to String. It should be String? instead because it can be null.
final receivedProductID =
ModalRoute.of(context)?.settings.arguments as String?;
import 'package:ecommerce_shop/providers/product.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:ecommerce_shop/providers/products.dart';
class EditProductScreen extends StatefulWidget {
static const routeName = 'edit-product';
const EditProductScreen({Key? key}) : super(key: key);
#override
_EditProductScreenState createState() => _EditProductScreenState();
}
class _EditProductScreenState extends State<EditProductScreen> {
final _priceFocusNode = FocusNode();
final _descriptionFocusNode = FocusNode();
final _imageUrlController = TextEditingController();
final _imageUrlFocusNode = FocusNode();
final _form = GlobalKey<FormState>();
var _edittedProduct = Product(
id: '',
title: '',
description: '',
imageUrl: '',
price: 0,
);
var _initValues = {
'title': '',
'description': '',
'price': '',
'imageUrl': '',
'id': '',
};
var _isInit = true;
#override
void initState() {
_imageUrlFocusNode.addListener(_updateImageUrl);
super.initState();
}
#override
void didChangeDependencies() {
if (_isInit) {
final productId = ModalRoute.of(context)?.settings.arguments as String;
if (productId != null) {
_edittedProduct =
Provider.of<Products>(context, listen: false).findById(productId);
_initValues = {
'id': _edittedProduct.id,
'title': _edittedProduct.title,
'description': _edittedProduct.description,
'price': _edittedProduct.price.toString(),
// 'imageUrl': _editedProduct.imageUrl,
'imageUrl': '',
};
_imageUrlController.text = _edittedProduct.imageUrl;
}
}
// if (_isInit) {
// // var productId = ModalRoute.of(context)!.settings.arguments ?? "";
// // // var productId =
// // // ModalRoute.of(context)!.settings.arguments as String ?? " ";
// // // productId ??= " ";
// // // final productId = ModalRoute.of(context)!.settings.arguments as String;
// // // print('$productId **********************************************');
// // _edittedProduct = Provider.of<Products>(
// // context,
// // listen: false,
// // ).findById(productId as String);
// }
_isInit = false;
super.didChangeDependencies();
}
void _updateImageUrl() {
if (_imageUrlController.text.isEmpty ||
!_imageUrlController.text.startsWith('http') ||
!_imageUrlController.text.startsWith('https')) {
return;
}
if (!_imageUrlFocusNode.hasFocus) {
setState(() {});
}
}
#override
void dispose() {
_imageUrlFocusNode.removeListener(_updateImageUrl);
_priceFocusNode.dispose();
_descriptionFocusNode.dispose();
super.dispose();
_imageUrlController.dispose();
_imageUrlFocusNode.dispose();
}
void _saveForm() {
final isValid = _form.currentState!.validate();
if (!isValid) {
return;
}
_form.currentState!.save();
Provider.of<Products>(context, listen: false).addProduct(_edittedProduct);
// _form.currentState!.save();
// if (_edittedProduct.id != '') {
// Provider.of<Products>(context, listen: false)
// .updateProduct(_edittedProduct.id!, _edittedProduct);
// } else {
// }
Navigator.of(context).pop();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit Product'),
actions: [
IconButton(
onPressed: _saveForm,
icon: const Icon(Icons.save),
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _form,
child: ListView(
children: [
TextFormField(
initialValue: _initValues['title'],
decoration: const InputDecoration(
labelText: 'Title',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(_priceFocusNode);
},
validator: (value) {
if (value!.isEmpty) {
return 'please provide a value';
}
return null;
},
onSaved: (value) {
_edittedProduct = Product(
id: _edittedProduct.id,
isFavourite: _edittedProduct.isFavourite,
title: value!,
description: _edittedProduct.description,
imageUrl: _edittedProduct.imageUrl,
price: _edittedProduct.price);
},
),
TextFormField(
initialValue: _initValues['price'],
decoration: const InputDecoration(
labelText: 'Price',
),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
focusNode: _priceFocusNode,
onFieldSubmitted: (_) {
FocusScope.of(context).requestFocus(_descriptionFocusNode);
},
validator: (value) {
if (value!.isEmpty) {
return 'please enter a price';
}
if (double.tryParse(value) == null) {
return 'Please enter a valid number';
}
if (double.parse(value) <= 0) {
return 'please enter a number greater than 0';
}
return null;
},
onSaved: (value) {
_edittedProduct = Product(
id: _edittedProduct.id,
isFavourite: _edittedProduct.isFavourite,
title: _edittedProduct.title,
description: _edittedProduct.description,
imageUrl: _edittedProduct.imageUrl,
price: double.parse(value!),
);
},
),
TextFormField(
initialValue: _initValues['description'],
decoration: const InputDecoration(
labelText: 'Description',
),
maxLines: 3,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.multiline,
focusNode: _descriptionFocusNode,
validator: (value) {
if (value!.isEmpty) {
return 'please enter a description';
}
if (value.length < 10) {
return 'should be atleast 10 characters long';
}
return null;
},
onSaved: (value) {
_edittedProduct = Product(
id: _edittedProduct.id,
isFavourite: _edittedProduct.isFavourite,
title: _edittedProduct.title,
description: value!,
imageUrl: _edittedProduct.imageUrl,
price: _edittedProduct.price);
},
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
width: 100,
height: 100,
margin: const EdgeInsets.only(
top: 8,
right: 10,
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey),
),
child: Container(
child: _imageUrlController.text.isEmpty
? const Text('Enter a Url ')
: FittedBox(
child: Image.network(
_imageUrlController.text,
fit: BoxFit.cover,
),
),
),
),
Expanded(
child: TextFormField(
// initialValue: _initValues['imageUrl'],
decoration: const InputDecoration(labelText: 'Image Url'),
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imageUrlController,
focusNode: _imageUrlFocusNode,
onFieldSubmitted: (_) {
_saveForm();
},
validator: (value) {
return null;
},
onSaved: (value) {
_edittedProduct = Product(
id: _edittedProduct.id,
isFavourite: _edittedProduct.isFavourite,
title: _edittedProduct.title,
description: _edittedProduct.description,
imageUrl: value!,
price: _edittedProduct.price);
},
),
),
],
),
],
),
),
),
);
}
}
This is the code and I am getting the error as null is not a subtype of string But I couldn't get how to resolve it, if you want my complete project files for checking
it is on https://github.com/SaivigneshAdepu20/ecommerce_shop.Actually I have shared the arguments in provider as id in product item screen which is available in my Github account.
What exactly contents do you expect? If it i s List or similar, try:
final List<String> files = ModalRoute
.of(context)
.settings
.arguments as List<String>;
Also it may be that you try calling .of(context) too soon. Try closing it in
Future.delayed(Duration.zero,(){
//Here
});
i'm following the same tutorial and this is code below fix it
#override
void didChangeDependencies() {
if (_isInit == true) {
final String productId = ModalRoute.of(context)?.settings.arguments == null ? '':ModalRoute.of(context)!.settings.arguments as String;
if (productId.isEmpty != true) {
final product =
Provider.of<Products>(context, listen: false).findById(productId!);
_editProduct = product;
_initValues = {
'title': _editProduct.title,
'price': _editProduct.price.toString(),
'description': _editProduct.description,
'imageUrl': _editProduct.imageUrl
};
_imageUrlController.text= _editProduct.imageUrl;
}
}
_isInit = false;
// TODO: implement didChangeDependencies
super.didChangeDependencies();
}
Is it possible to POST data from flutter app to woocommerce localhost using woocommerce localhost server rest api.
i have GET & POST data with private domain but i want to POST & GET data with localhost woocommerce rest api. i have setup my wordpress and woocommerce on localhost I am trying to make flutter ecommerce app and trying to GET & POST data from woocommerce localhost. but its not working and i dont want to send from private domain rest api, i can get data on postman if i select OAuth 1.0 but if i dont use OAuth 1.0 i cant get data.
Config.dart
class Config {
static String key =
'ck_00000000000000000000000000';
static String sceret =
'cs_00000000000000000000000000';
static String url = 'http://10.0.2.2:80/wordpress_new/wp-json/wc/v3/';
static String customerURL = 'customers';
}
customer.dart
class CustomerModel {
String email;
String firstName;
String lastName;
String password;
CustomerModel({
this.email,
this.firstName,
this.lastName,
this.password,
});
Map<String, dynamic> toJson() {
Map<String, dynamic> map = {};
map.addAll({
'email': email,
'first_name': firstName,
'last_name': lastName,
'password': password,
'username': email,
});
return map;
}
}
apiservice.dart
class APIService {
Future<bool> createCustomer(CustomerModel model) async {
var authToken = base64.encode(
utf8.encode(Config.key + ':' + Config.sceret),
);
bool ret = false;
try {
var response = await Dio().post(
Config.url +
Config.customerURL,
data: model.toJson(),
options: new Options(headers: {
HttpHeaders.authorizationHeader: 'Basic $authToken',
HttpHeaders.contentTypeHeader: 'application/json',
}));
if (response.statusCode == 201) {
ret = true;
}
} on DioError catch (e) {
if (e.response.statusCode == 404) {
print(e.response.statusCode);
ret = false;
} else {
print(e.message);
print(e.request);
ret = false;
}
}
return ret;
}
Future<LoginResponseModel> loginCustomer(
String username,
String password,
) async {
LoginResponseModel model;
try {
var response = await Dio().post(Config.tokenURL,
data: {
'username': username,
'password': password,
},
options: new Options(headers: {
HttpHeaders.contentTypeHeader: 'application/x-www-form-urlencoded',
}));
if (response.statusCode == 200) {
model = LoginResponseModel.fromJson(response.data);
}
} on DioError catch (e) {
print(e.message);
}
return model;
}
}
signuppage.dart
class SignupPage extends StatefulWidget {
#override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
APIService apiService;
CustomerModel model;
GlobalKey<FormState> globalKey = GlobalKey<FormState>();
bool hidePassword = true;
bool isApiCallProcess = false;
#override
void initState() {
apiService = new APIService();
model = new CustomerModel();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
automaticallyImplyLeading: true,
title: Text('Sign Up'),
),
body: ProgressHUD(
child: Form(
key: globalKey,
child: _formUI(),
),
inAsyncCall: isApiCallProcess,
opacity: 0.3),
);
}
Widget _formUI() {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(10.00),
child: Container(
child: Align(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FormHelper.fieldLabel('First Name'),
FormHelper.textInput(
context,
model.firstName,
(value) => {
this.model.firstName = value,
},
onValidate: (value) {
if (value.toString().isEmpty) {
return 'Please enter First Name.';
}
return null;
},
),
FormHelper.fieldLabel('Last Name'),
FormHelper.textInput(
context,
model.lastName,
(value) => {
this.model.lastName = value,
},
onValidate: (value) {
return null;
},
),
FormHelper.fieldLabel('Email Id'),
FormHelper.textInput(
context,
model.email,
(value) => {
this.model.email = value,
},
onValidate: (value) {
if (value.toString().isEmpty) {
return 'Please enter Email id.';
}
if (value.isNotEmpty && !value.toString().isValidEmail()) {
return 'Please enter valid email id';
}
},
),
FormHelper.fieldLabel('Password'),
FormHelper.textInput(
context,
model.password,
(value) => {
this.model.password = value,
},
onValidate: (value) {
if (value.toString().isEmpty) {
return 'Please enter Password.';
}
return null;
},
obscureText: hidePassword,
suffixIcon: IconButton(
onPressed: () {
setState(() {
hidePassword = !hidePassword;
});
},
color: Theme.of(context).accentColor.withOpacity(0.4),
icon: Icon(
hidePassword ? Icons.visibility_off : Icons.visibility,
),
),
),
SizedBox(
height: 20,
),
Center(
child: FormHelper.saveButton(
'Register',
() {
if (validateAndSave()) {
print(model.toJson());
setState(() {
isApiCallProcess = true;
});
apiService.createCustomer(model).then(
(ret) {
setState(() {
isApiCallProcess = false;
});
if (ret) {
FormHelper.showMessage(
context,
'WooCommerce App',
'Registration Successfull',
'Ok',
() {
Navigator.of(context).pop();
},
);
} else {
FormHelper.showMessage(
context,
'WooCommerce App',
'Email Id already registered.',
'Ok',
() {
Navigator.of(context).pop();
},
);
}
},
);
}
},
),
)
],
),
),
),
),
);
}
bool validateAndSave() {
final form = globalKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
}
form_helper.dart
class FormHelper {
static Widget textInput(
BuildContext context,
Object initialValue,
Function onChanged, {
bool isTextArea = false,
bool isNumberInput = false,
obscureText: false,
Function onValidate,
Widget prefixIcon,
Widget suffixIcon,
}) {
return TextFormField(
initialValue: initialValue != null ? initialValue.toString() : "",
decoration: fieldDecoration(
context,
"",
"",
suffixIcon: suffixIcon,
),
obscureText: obscureText,
maxLines: !isTextArea ? 1 : 3,
keyboardType: isNumberInput ? TextInputType.number : TextInputType.text,
onChanged: (String value) {
return onChanged(value);
},
validator: (value) {
return onValidate(value);
},
);
}
static InputDecoration fieldDecoration(
BuildContext context,
String hintText,
String helperText, {
Widget prefixIcon,
Widget suffixIcon,
}) {
return InputDecoration(
contentPadding: EdgeInsets.all(6),
hintText: hintText,
helperText: helperText,
prefixIcon: prefixIcon,
suffixIcon: suffixIcon,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 1,
),
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 1,
),
),
);
}
static Widget fieldLabel(String labelName) {
return new Padding(
padding: EdgeInsets.fromLTRB(0, 5, 0, 10),
child: Text(
labelName,
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
);
}
static Widget saveButton(String buttonText, Function onTap,
{String color, String textColor, bool fullWidth}) {
return Container(
height: 50.0,
width: 150,
child: GestureDetector(
onTap: () {
onTap();
},
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.redAccent,
style: BorderStyle.solid,
width: 1.0,
),
color: Colors.redAccent,
borderRadius: BorderRadius.circular(30.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Text(
buttonText,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
letterSpacing: 1,
),
),
),
],
),
),
),
);
}
static void showMessage(
BuildContext context,
String title,
String message,
String buttonText,
Function onPressed,
) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(title),
content: new Text(message),
actions: [
new FlatButton(
onPressed: () {
return onPressed();
},
child: new Text(buttonText),
)
],
);
},
);
}
}
progressHUD.dart
class ProgressHUD extends StatelessWidget {
final Widget child;
final bool inAsyncCall;
final double opacity;
final Color color;
final Animation<Color> valueColor;
ProgressHUD({
Key key,
#required this.child,
#required this.inAsyncCall,
this.opacity = 0.3,
this.color = Colors.grey,
this.valueColor,
}) : super(key: key);
#override
Widget build(BuildContext context) {
List<Widget> widgetList = new List<Widget>();
widgetList.add(child);
if (inAsyncCall) {
final modal = new Stack(
children: [
new Opacity(
opacity: opacity,
child: ModalBarrier(dismissible: false, color: color),
),
new Center(child: new CircularProgressIndicator()),
],
);
widgetList.add(modal);
}
return Stack(
children: widgetList,
);
}
}
I'm populating states name from JSON and display as a dropdown list after that I show 2nd dropdown list based on first value selected. But I don't now how to populate 2nd dropdown when 1st dropdown value changed. I also want to get location id, name and city when select 2nd dropdown value.
My Json
{
"data": [
{
"state": "TEXAS",
"locations": [
{
"id": 1,
"name": "FITT Sugarland",
"city": "HOUSTON",
"state": "TEXAS",
"timezone": "",
"ownerName": "",
"ownerPhoneNumber": "",
"ownerEmail": "",
"ownerWebsite": "",
"capacity": 0,
"description": "HOUSTON SUGARLAND",
"createdBy": "",
"modifiedBy": "",
"createdAt": "2020-08-18T10:17:55.000Z",
"modifiedAt": "2020-08-18T10:17:55.000Z"
},
{
"id": 2,
"name": "FITT Pearland",
"city": "HOUSTON",
"state": "TEXAS",
"timezone": "",
"ownerName": "",
"ownerPhoneNumber": "",
"ownerEmail": "",
"ownerWebsite": "",
"capacity": 0,
"description": "second location",
"createdBy": "",
"modifiedBy": "",
"createdAt": "2020-08-18T10:18:38.000Z",
"modifiedAt": "2020-08-18T10:18:38.000Z"
}
]
}
]
}
Model Class
class LocationModel {
List<LocationList> data;
LocationModel({this.data});
LocationModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
data = new List<LocationList>();
json['data'].forEach((v) {
data.add(new LocationList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class LocationList {
String state;
List<Locations> locations;
LocationList({this.state, this.locations});
LocationList.fromJson(Map<String, dynamic> json) {
state = json['state'];
if (json['locations'] != null) {
locations = new List<Locations>();
json['locations'].forEach((v) {
locations.add(new Locations.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['state'] = this.state;
if (this.locations != null) {
data['locations'] = this.locations.map((v) => v.toJson()).toList();
}
return data;
}
}
class Locations {
int id;
String name;
String city;
String state;
String timezone;
String ownerName;
String ownerPhoneNumber;
String ownerEmail;
String ownerWebsite;
int capacity;
String description;
String createdBy;
String modifiedBy;
String createdAt;
String modifiedAt;
Locations(
{this.id,
this.name,
this.city,
this.state,
this.timezone,
this.ownerName,
this.ownerPhoneNumber,
this.ownerEmail,
this.ownerWebsite,
this.capacity,
this.description,
this.createdBy,
this.modifiedBy,
this.createdAt,
this.modifiedAt});
Locations.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
city = json['city'];
state = json['state'];
timezone = json['timezone'];
ownerName = json['ownerName'];
ownerPhoneNumber = json['ownerPhoneNumber'];
ownerEmail = json['ownerEmail'];
ownerWebsite = json['ownerWebsite'];
capacity = json['capacity'];
description = json['description'];
createdBy = json['createdBy'];
modifiedBy = json['modifiedBy'];
createdAt = json['createdAt'];
modifiedAt = json['modifiedAt'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['city'] = this.city;
data['state'] = this.state;
data['timezone'] = this.timezone;
data['ownerName'] = this.ownerName;
data['ownerPhoneNumber'] = this.ownerPhoneNumber;
data['ownerEmail'] = this.ownerEmail;
data['ownerWebsite'] = this.ownerWebsite;
data['capacity'] = this.capacity;
data['description'] = this.description;
data['createdBy'] = this.createdBy;
data['modifiedBy'] = this.modifiedBy;
data['createdAt'] = this.createdAt;
data['modifiedAt'] = this.modifiedAt;
return data;
}
}
My Code
import 'dart:io';
import 'package:fittheorem/models/location_list.dart';
import 'package:fittheorem/providers/auth_session.dart';
import 'package:fittheorem/providers/user_details.dart';
import 'package:fittheorem/ui/widgets/error_snakbar.dart';
import 'package:fittheorem/utils/app_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
class LocationUpdate extends StatefulWidget {
#override
_LocationUpdateState createState() => _LocationUpdateState();
}
class _LocationUpdateState extends State<LocationUpdate> {
LocationModel _locationModel;
bool isLoading = true;
String _selectedState = "TEXAS";
List<String> _statesList = [];
String _selectedLocation = "FITT Sugarland";
List<Locations> _locationsList = List();
#override
void initState() {
// TODO: implement initState
super.initState();
getList();
}
Future<void> getList() async {
try {
_locationModel = await Provider.of<UserDetails>(context, listen: false)
.getLocationList("token");
for (int i = 0; i < _locationModel.data.length; i++) {
_statesList.add(_locationModel.data[i].state);
}
_locationsList = _locationModel.data[0].locations;
_selectedState = _statesList[0];
_selectedLocation = _locationsList[0].name;
if (mounted) {
setState(() {
isLoading = false;
});
}
} on HttpException catch (error) {
CustomWidgets.buildErrorSnackbar(context);
} catch (error) {
CustomWidgets.buildErrorSnackbar(context);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: AppConfig.bgColor,
child: SafeArea(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
height: 40.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pop(context, true);
},
child: Container(
height: 25.0,
width: 25.0,
child: SvgPicture.asset(AppConfig.backImage,
color: Colors.white, semanticsLabel: 'back')),
),
Text('LOCATION',
style: GoogleFonts.roboto(
textStyle: TextStyle(
fontSize: 18.0, color: Color(0xffFFFFFF)),
)),
SizedBox(
width: 25.0,
),
],
),
),
Expanded(
child: Container(
color: Colors.white,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(30.0),
child: isLoading
? Center(
child: AppConfig().myLoader(),
)
: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 20.0,
),
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Text('UPDATE YOUR LOCATION',
style: GoogleFonts.roboto(
textStyle: TextStyle(
fontSize: 16.0,
color: Color(0xff000000)),
)),
),
SizedBox(
height: 20.0,
),
Container(
height: 40.0,
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.black54, width: 0.0),
borderRadius: new BorderRadius.circular(10.0),
),
child: new DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: new DropdownButton(
value: _selectedState,
hint: Text("State"),
isExpanded: true,
items: _statesList
.map((String item) =>
DropdownMenuItem<String>(
child: Text(item),
value: item))
.toList(),
onChanged: (String newValue) {
if (mounted)
setState(() {
_selectedState = newValue;
});
},
style: Theme.of(context)
.textTheme
.bodyText2,
))),
),
SizedBox(
height: 20.0,
),
Container(
height: 40.0,
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.black54, width: 0.0),
borderRadius: new BorderRadius.circular(10.0),
),
child: new DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: new DropdownButton(
value: _selectedLocation,
hint: Text("Location"),
isExpanded: true,
items: _locationsList.map((item) {
return new DropdownMenuItem(
child: new Text(item.name),
value: item.name,
);
}).toList(),
onChanged: (newValue) {
if (mounted) print(newValue);
setState(() {
_selectedLocation = newValue;
});
},
style: Theme.of(context)
.textTheme
.bodyText2,
))),
)
],
),
),
)
],
),
),
),
);
}
}
You can copy paste run full code below
Step 1: Change data type of _selectedLocation
Locations _selectedLocation;
Step 2: _selectedState's onChanged
onChanged: (String Value) {
if (mounted)
setState(() {
_selectedState = Value;
int index = _locationModel.data
.indexWhere((element) =>
element.state ==
_selectedState);
_locationsList = _locationModel
.data[index].locations;
_selectedLocation =
_locationsList[0];
});
},
Step 3: _selectedLocation's onChanged
onChanged: (Value) {
if (mounted) print(Value);
setState(() {
_selectedLocation = Value;
print(
"${_selectedLocation.name} ${_selectedLocation.id} ${_selectedLocation.city}");
});
},
working demo
full code
import 'dart:convert';
import 'package:flutter/material.dart';
LocationModel locationModelFromJson(String str) =>
LocationModel.fromJson(json.decode(str));
class LocationModel {
List<LocationList> data;
LocationModel({this.data});
LocationModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
data = List<LocationList>();
json['data'].forEach((v) {
data.add(LocationList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class LocationList {
String state;
List<Locations> locations;
LocationList({this.state, this.locations});
LocationList.fromJson(Map<String, dynamic> json) {
state = json['state'];
if (json['locations'] != null) {
locations = List<Locations>();
json['locations'].forEach((v) {
locations.add(Locations.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['state'] = this.state;
if (this.locations != null) {
data['locations'] = this.locations.map((v) => v.toJson()).toList();
}
return data;
}
}
class Locations {
int id;
String name;
String city;
String state;
String timezone;
String ownerName;
String ownerPhoneNumber;
String ownerEmail;
String ownerWebsite;
int capacity;
String description;
String createdBy;
String modifiedBy;
String createdAt;
String modifiedAt;
Locations(
{this.id,
this.name,
this.city,
this.state,
this.timezone,
this.ownerName,
this.ownerPhoneNumber,
this.ownerEmail,
this.ownerWebsite,
this.capacity,
this.description,
this.createdBy,
this.modifiedBy,
this.createdAt,
this.modifiedAt});
Locations.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
city = json['city'];
state = json['state'];
timezone = json['timezone'];
ownerName = json['ownerName'];
ownerPhoneNumber = json['ownerPhoneNumber'];
ownerEmail = json['ownerEmail'];
ownerWebsite = json['ownerWebsite'];
capacity = json['capacity'];
description = json['description'];
createdBy = json['createdBy'];
modifiedBy = json['modifiedBy'];
createdAt = json['createdAt'];
modifiedAt = json['modifiedAt'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['city'] = this.city;
data['state'] = this.state;
data['timezone'] = this.timezone;
data['ownerName'] = this.ownerName;
data['ownerPhoneNumber'] = this.ownerPhoneNumber;
data['ownerEmail'] = this.ownerEmail;
data['ownerWebsite'] = this.ownerWebsite;
data['capacity'] = this.capacity;
data['description'] = this.description;
data['createdBy'] = this.createdBy;
data['modifiedBy'] = this.modifiedBy;
data['createdAt'] = this.createdAt;
data['modifiedAt'] = this.modifiedAt;
return data;
}
}
class LocationUpdate extends StatefulWidget {
#override
_LocationUpdateState createState() => _LocationUpdateState();
}
class _LocationUpdateState extends State<LocationUpdate> {
LocationModel _locationModel;
bool isLoading = true;
String _selectedState = "TEXAS";
List<String> _statesList = [];
Locations _selectedLocation;
List<Locations> _locationsList = List();
#override
void initState() {
// TODO: implement initState
super.initState();
getList();
}
Future<void> getList() async {
try {
/*_locationModel = await Provider.of<UserDetails>(context, listen: false)
.getLocationList("token");*/
String jsonString = '''
{
"data": [
{
"state": "TEXAS",
"locations": [
{
"id": 1,
"name": "FITT Sugarland",
"city": "HOUSTON",
"state": "TEXAS",
"timezone": "",
"ownerName": "",
"ownerPhoneNumber": "",
"ownerEmail": "",
"ownerWebsite": "",
"capacity": 0,
"description": "HOUSTON SUGARLAND",
"createdBy": "",
"modifiedBy": "",
"createdAt": "2020-08-18T10:17:55.000Z",
"modifiedAt": "2020-08-18T10:17:55.000Z"
},
{
"id": 2,
"name": "FITT Pearland",
"city": "HOUSTON",
"state": "TEXAS",
"timezone": "",
"ownerName": "",
"ownerPhoneNumber": "",
"ownerEmail": "",
"ownerWebsite": "",
"capacity": 0,
"description": "second location",
"createdBy": "",
"modifiedBy": "",
"createdAt": "2020-08-18T10:18:38.000Z",
"modifiedAt": "2020-08-18T10:18:38.000Z"
}
]
},
{
"state": "A",
"locations": [
{
"id": 1,
"name": "A1",
"city": "A City 1",
"state": "A",
"timezone": "",
"ownerName": "",
"ownerPhoneNumber": "",
"ownerEmail": "",
"ownerWebsite": "",
"capacity": 0,
"description": "HOUSTON SUGARLAND",
"createdBy": "",
"modifiedBy": "",
"createdAt": "2020-08-18T10:17:55.000Z",
"modifiedAt": "2020-08-18T10:17:55.000Z"
},
{
"id": 2,
"name": "A2",
"city": "A city 2",
"state": "A",
"timezone": "",
"ownerName": "",
"ownerPhoneNumber": "",
"ownerEmail": "",
"ownerWebsite": "",
"capacity": 0,
"description": "second location",
"createdBy": "",
"modifiedBy": "",
"createdAt": "2020-08-18T10:18:38.000Z",
"modifiedAt": "2020-08-18T10:18:38.000Z"
}
]
}
]
}
''';
_locationModel = locationModelFromJson(jsonString);
for (int i = 0; i < _locationModel.data.length; i++) {
_statesList.add(_locationModel.data[i].state);
}
_locationsList = _locationModel.data[0].locations;
_selectedState = _statesList[0];
_selectedLocation = _locationsList[0];
if (mounted) {
setState(() {
isLoading = false;
});
}
//} on HttpException catch (error) {
// CustomWidgets.buildErrorSnackbar(context);
} catch (error) {
//CustomWidgets.buildErrorSnackbar(context);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
//color: AppConfig.bgColor,
child: SafeArea(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
height: 40.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Navigator.pop(context, true);
},
child: Container(
height: 25.0,
width: 25.0,
child: Image.network(
'https://picsum.photos/250?image=9',
color: Colors.white)),
),
Text('LOCATION',
style: TextStyle(
fontSize: 18.0,
color: Color(0xffFFFFFF),
)),
SizedBox(
width: 25.0,
),
],
),
),
Expanded(
child: Container(
color: Colors.white,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(30.0),
child: isLoading
? Center(
child: CircularProgressIndicator(),
)
: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 20.0,
),
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Text('UPDATE YOUR LOCATION',
style: TextStyle(
fontSize: 16.0,
color: Color(0xff000000),
)),
),
SizedBox(
height: 20.0,
),
Container(
height: 40.0,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black54, width: 0.0),
borderRadius: BorderRadius.circular(10.0),
),
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton(
value: _selectedState,
hint: Text("State"),
isExpanded: true,
items: _statesList
.map((String item) =>
DropdownMenuItem<String>(
child: Text(item),
value: item))
.toList(),
onChanged: (String Value) {
if (mounted)
setState(() {
_selectedState = Value;
int index = _locationModel.data
.indexWhere((element) =>
element.state ==
_selectedState);
_locationsList = _locationModel
.data[index].locations;
_selectedLocation =
_locationsList[0];
});
},
style: Theme.of(context)
.textTheme
.bodyText2,
))),
),
SizedBox(
height: 20.0,
),
Container(
height: 40.0,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black54, width: 0.0),
borderRadius: BorderRadius.circular(10.0),
),
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton(
value: _selectedLocation,
hint: Text("Location"),
isExpanded: true,
items: _locationsList.map((item) {
return DropdownMenuItem(
child: Text(item.name),
value: item,
);
}).toList(),
onChanged: (Value) {
if (mounted) print(Value);
setState(() {
_selectedLocation = Value;
print(
"${_selectedLocation.name} ${_selectedLocation.id} ${_selectedLocation.city}");
});
},
style: Theme.of(context)
.textTheme
.bodyText2,
))),
)
],
),
),
)
],
),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: LocationUpdate(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}