How To Compare Objects By Name In Query Flutter by Property - sorting

I am adding a search bar in my application and trying to query a object by an attribute name but, cant get it working.
EDIT 1) Future function:
Widget _buildDiner() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FutureBuilder(
future: _setDiner,
builder: (context, AsyncSnapshot snapshot) {
var diner = snapshot.data;
if (snapshot.data == null) {
return Center(child: CircularProgressIndicator());
} else {
var sponsoredDiner = diner
.where((e) => e.sponsored == 'Yes')
.toList();
return Column(
children: <Widget>[
_makeDiner(sponsoredDiner),
_buildCoupon(),
_buildVendors()
],
);
}
})
]));
}
Diners =
class Diners {
String keyword;
int id;
String name;
String sponsored;
Diners({
this.keyword,
this.id,
this.name,
this.sponsored
});
factory Diners.fromJson(Map<String, dynamic> parsedJson) {
return Diners(
keyword: parsedJson['keyword'] as String,
id: parsedJson['id'],
name: parsedJson['name'] as String,
sponsored: parsedJson['sponsored'] as String
);
}
}
And I am comparing two instances of Diners( sponsored and diners)
I use this query to attempt to compare the text that is put in to the search bar:
final suggestionList = query.isEmpty
? sponsored
: diners
.where((p) => p.name.startsWith(query)).toList();
But I'm getting this error
"type '(dynamic) => dynamic' is not a subtype of type '(Diner) => bool' of 'test'
I'm not sure why

Related

Flutter file picker unexpected null value

id love your support on this one.
The thing is that im trying to upload a file to firebase useing file-picker with flutter.
This is my code:
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:hire_me/firebase/firebaseApi.dart';
import 'package:hire_me/buttonWidget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
class ImageUploader extends StatefulWidget {
const ImageUploader({Key? key}) : super(key: key);
#override
_ImageUploaderState createState() => _ImageUploaderState();
}
class _ImageUploaderState extends State<ImageUploader> {
UploadTask? task;
File? file;
#override
Widget build(BuildContext context) {
final fileName =
file != null ? basename(file!.path) : 'No File Selected Yet';
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Upload Image'),
),
body: Container(
padding: EdgeInsets.all(32),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ButtonWidget(
icon: Icons.attach_file,
text: 'Select File',
onClicked: selectFile,
),
SizedBox(
height: 8,
),
Text(fileName,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(
height: 48,
),
ButtonWidget(
icon: Icons.cloud_upload_outlined,
text: 'Upload File',
onClicked: uploadFile)
],
),
),
),
);
}
Future selectFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
final path = result.files.single.path!;
setState(() => file = File(path));
}
}
Future uploadFile() async {
if (file == null) return;
final fileName = basename(file!.path);
final destination = 'files/$fileName';
FirebaseApi.uploadFile(destination, file!);
setState(() {});
if (task == null) return;
final snapshot = await task!.whenComplete(() => {});
final urlDownload = await snapshot.ref.getDownloadURL();
print('Download Link: $urlDownload');
}
}
When i click on the upload file button, it opens the platform file picker and after selecting an image i get the following error:
Error: Unexpected null value.
at Object.throw_ [as throw] (http://localhost:51207/dart_sdk.js:5037:11)
at Object.nullCheck (http://localhost:51207/dart_sdk.js:5362:30)
at imageUploader._ImageUploaderState.new.selectFile
(http://localhost:51207/packages/hire_me/screens/imageUploader.dart.lib.js:417:27)
at selectFile.next (<anonymous>)
at http://localhost:51207/dart_sdk.js:37374:33
at _RootZone.runUnary (http://localhost:51207/dart_sdk.js:37245:59)
at _FutureListener.thenAwait.handleValue (http://localhost:51207/dart_sdk.js:32501:29)
at handleValueCallback (http://localhost:51207/dart_sdk.js:33028:49)
at Function._propagateToListeners (http://localhost:51207/dart_sdk.js:33066:17)
at _Future.new.[_completeWithValue] (http://localhost:51207/dart_sdk.js:32914:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:51207/dart_sdk.js:32935:35)
at Object._microtaskLoop (http://localhost:51207/dart_sdk.js:37497:13)
at _startMicrotaskLoop (http://localhost:51207/dart_sdk.js:37503:13)
at http://localhost:51207/dart_sdk.js:33274:9
I have tested this on chrome and android.
I had the same problem.
In this case, your variable that you have made-
UploadTask? task;
File? file;
you have to assign these variables. This is the reason they are showing the Unexpected null error.
In my case I had a boolean variable, I assigned it with false ->
this.isActive = false,
So you should make a constructor for your variables. Such as:
class ImageUploader extends StatefulWidget {
UploadTask? task;
File? file;
const ImageUploader({Key? key, this.task, this.file}) : super(key: key);
#override
_ImageUploaderState createState() => _ImageUploaderState();
}
class _ImageUploaderState extends State<ImageUploader> {
#override
Widget build(BuildContext context) {
final fileName =
file != null ? basename(file!.path) : 'No File Selected Yet';
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Upload Image'),
),
body: Container(
padding: EdgeInsets.all(32),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ButtonWidget(
icon: Icons.attach_file,
text: 'Select File',
onClicked: selectFile,
),
SizedBox(
height: 8,
),
Text(fileName,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(
height: 48,
),
ButtonWidget(
icon: Icons.cloud_upload_outlined,
text: 'Upload File',
onClicked: uploadFile)
],
),
),
),
);
}
Future selectFile() async {
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
final path = result.files.single.path!;
setState(() => file = File(path));
}
}
Future uploadFile() async {
if (file == null) return;
final fileName = basename(file!.path);
final destination = 'files/$fileName';
FirebaseApi.uploadFile(destination, file!);
setState(() {});
if (task == null) return;
final snapshot = await task!.whenComplete(() => {});
final urlDownload = await snapshot.ref.getDownloadURL();
print('Download Link: $urlDownload');
}
}
if this still shows the unexpected null error, then you have to assign the variables in the constructor.
Hope it works for you.
just add this line in file picker:
withData: true,

Flutter FutureBuilder shows data then disappears when calling Rest API (Backend Laravel)

I'm running a flutter application with a laravel backend and I have some issues.
The problem is the FutureBuilder show data then it disappears; Sometimes length==4 then it turns to 0 and shows 'no data' in Scaffold🙄
The same when I refresh the code.
PS: I'm running laravel on localhost and using a real device to test.
Environment: Android Studio, Windows 10, Real device
Laravel project: https://github.com/brakenseddik/blog_api_laravel
Flutter project: https://github.com/brakenseddik/blog_api_flutter
import 'package:http/http.dart' as http;
class Repository {
String _baseUrl = 'http://192.168.1.2:8000/api';
httpGet(String api) async {
return await http.get(_baseUrl + '/' + api);
}
}
here the homepage source code
import 'dart:convert';
import 'package:blog_api/models/post_model.dart';
import 'package:blog_api/services/post_service.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
PostService _postService = PostService();
List<PostModel> _list = List<PostModel>();
Future<List<PostModel>> _getPosts() async {
var result = await _postService.getAllPosts();
_list = [];
if (result != null) {
var blogPosts = json.decode(result.body);
blogPosts.forEach((post) {
PostModel model = PostModel();
setState(() {
model.title = post['title'];
model.details = post['details'];
model.imageUrl = post['featured_image_url'];
_list.add(model);
});
});
}
return _list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Blog App'),
),
body: FutureBuilder(
future: _getPosts(),
builder:
(BuildContext context, AsyncSnapshot<List<PostModel>> snapshot) {
print('length of list ${_list.length}');
_list = snapshot.data;
if (_list.length == 0) {
return Center(
child: Text('No data'),
);
} else if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.network(
snapshot.data[index].imageUrl,
height: 150,
// width: double.maxFinite,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data[index].title,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w700),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
snapshot.data[index].details.substring(0, 25),
style: TextStyle(
fontSize: 16,
),
),
),
],
),
),
);
});
}
},
));
}
}
And the PostService
import 'package:blog_api/repository/repository.dart';
class PostService {
Repository _repository;
PostService() {
_repository = Repository();
}
getAllPosts() async {
return await _repository.httpGet('get-posts');
}
}
I think the issue is that you're calling setState in _getPosts(). This will rebuild everything and never give the response to the FutureBuilder. Just run the code without setState:
blogPosts.forEach((post) {
PostModel model = PostModel();
model.title = post['title'];
model.details = post['details'];
model.imageUrl = post['featured_image_url'];
_list.add(model);
FutureBuilder will initially call its builder with a snapshot that doesn't have any data yet. Once it receives the data, it will call its builder again. Because of this, if (_list.length == 0) will result in a NPE, since _list is null.
I would try changing the order of the if statements:
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.data.length == 0) {
return Center(
child: Text('No data'),
);
} else {
return ListView.builder(
//...
}
future: _getPosts(),
Don't do that. This means every time build is called, you are querying your API again.
Create a variable of type Future<List<PostModel>>, assign _getPosts() to it once and then use that variable with your FutureBuilder.

How to populate JSON data when id is passed from first activity to second activities

I'm new to flutter am developing contacts app using laravel backend i have two tables which are constrained on foreign key and json response works on postman. in Flutter i have two models users model and userdetail model. users name in list view like below and works fine
class ListUsers extends StatefulWidget {
#override
_ListItemsState createState() => _ListItemsState();
}
class _ListUsersState extends State<ListUsers> {
UsersApi usersApi;
#override
void initState() {
super.initState();
usersApi = UsersApi();
usersApi.fetchAllUsers();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Contacts'),
),
body: Container(
padding: EdgeInsets.all(16),
child:FutureBuilder(
future: itemsApi.fetchAllUsers(),
builder: (BuildContext context, AsyncSnapshot<List<Users>> snapshot)
{
switch(snapshot.connectionState)
{
case ConnectionState.active:
// working
return _loading();
break;
case ConnectionState.waiting:
//working
return _loading();
break;
case ConnectionState.none:
// no connection
return _error('No connection has been made');
break;
case ConnectionState.done:
// completed
if(snapshot.hasError)
{
return _error(snapshot.error.toString());
}
if(snapshot.hasData)
{
return _drawItemsList(snapshot.data,context);
}
break;
}
return Container();
},
),
),
);
}
Widget _drawItemsList(List<Users> myusers,BuildContext context)
{
return ListView.builder(
itemCount: myusers.length,
itemBuilder: (BuildContext context, int position){
return InkWell(
child:Card(
child:Padding(
padding: const EdgeInsets.all(8.0),
child: Text(musers[position].myuser_name),
) ,
),
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>UserDetails(muysers[position].id)));
},
);
},
);
}
Widget _loading()
{
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
Widget _error(String error)
{
return Container(
child: Center(
child: Text('Something went wrong'
),
),
);
}
}
my Api call to load listView is here also works fine
class UsersApi {
Future<List<Users>> fetchAllUsers() async //
{
String allUsers = CallApi.url + CallApi.items_url;
Map<String, String> headers =
{
'Accept': 'application/json',
};
var response = await http.get(allUsers, headers: headers);
List<Users> users = []; // its empty list we add it below
if (response.statusCode == 200) {
Map<String, dynamic> body = jsonDecode(response.body);
for (var item in body['data']) {
Users myUsers = Users.fromJson(item);
items.add(myUsers);
}
}
return users;
}
}
Now the error happens remember by passing single id from the first screen makes request of
CallApi.url+CallApi.My_Contacts+itemId;
to second screen and loads details of clicked info.
for loading other information of user from another table i created model and here is my request for second screen
class UserDetailApi {
Future<List<UserDetailModel>> fetchDetailOfSingleUser(String itemId) async
{
String userDetailUrl = CallApi.url+CallApi.My_Contacts+itemId;
Map<String,String> headers =
{
'Accept' : 'application/json',
};
var response = await http.get(userDetailUrl ,headers:headers);
List<UserDetailModel> user =[];
if(response.statusCode == 200)
{
Map<String, dynamic> body = jsonDecode(response.body);
for(var item in body['data'])
{
UserDetailModel userr = UserDetailModel.fromJson(item);
user.add(userr);
}
}
return user;
}
}
here is second activity
class UserDetails extends StatefulWidget
{
final String uId;
UserDetails(this.uId);
#override
_UserDetailsState createState()=>_UserDetailsState();
}
class _UserDetailsState extends State<UserDetails>
{
UserDetailApi itemsApi = UserDetailApi();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title:Text('Detailed Info'),
),
body: Container(
padding: EdgeInsets.all(16),
child: FutureBuilder(
future: itemsApi.fetchDetailOfSingleUser(widget.uId),
builder: (BuildContext context, AsyncSnapshot<List<UserDetailModel>> snapshot)
{
switch(snapshot.connectionState)
{
case ConnectionState.active:
// working
return _loading();
break;
case ConnectionState.waiting:
//working
return _loading();
break;
case ConnectionState.none:
// no connection
return _error('No connection has been made');
break;
case ConnectionState.done:
// completed
if(snapshot.hasError)
{
//return _error(snapshot.error.toString());
}
if(snapshot.hasData)
{
return _drawItemsList(snapshot.data);
}
break;
}
return Container();
},
),
),
);
}
Widget _drawItemsList(List<UserDetailModel> mdetail)
{
return ListView.builder(
itemCount: mdetail.length,
itemBuilder: (BuildContext context, int position){
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: mdetail.length,
itemBuilder: (BuildContext context, int position){
return InkWell(
child: Card(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text(here i need to display full user info from second table),
),
),
);
},
),
);
},
);
}
Widget _loading()
{
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
Widget _error(String error)
{
return Container(
child: Center(
child: Text('Something went wrong'
),
),
);
}
}
empty screen no results populated on TextBox so please tell me where i have missed or if my works are not correct for detailed activity thanks.

Variable considered as undefined while defined in an if structure

I'm quite new to Flutter and I face a small problem. Inspired by the second part of the Flutter tutorial on the official Website, I'd like to display an error message when an array is empty.
The error code is below:
Undefined name 'divided'.
Try correcting the name to one that is defined, or defining the name.
The code is:
void _showSaved() {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
if (_saved.isEmpty) {
final Text divided = Text('List is empty');
} else {
final Iterable<ListTile> tiles = _saved.map(
(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
},
);
final ListView divided = ListView(
children: ListTile.divideTiles(
context: context,
tiles: tiles,
).toList());
}
return Scaffold(
appBar: AppBar(
title: Text('Saved Suggestions'),
),
//body: _saved.isEmpty ? Text('List is empty') : ListView(children: divided),
body: divided);
},
),
);
}
The variable is defined in an if condition, but VSCode still displays an error that the variable is undefined. Is there something I don't understand properly?
For your information, working with the inline condition does work (commented line in code sample).
Thank you!
Your variable divided is scoped only between the braces of the if and the else blocks
defining it like this solves the problem:
void _showSaved() {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
var divided;
if (_saved.isEmpty) {
divided = Text('List is empty');
} else {
final Iterable<ListTile> tiles = _saved.map(
(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
},
);
divided = ListView(
children: ListTile.divideTiles(
context: context,
tiles: tiles,
).toList());
}
return Scaffold(
appBar: AppBar(
title: Text('Saved Suggestions'),
),
//body: _saved.isEmpty ? Text('List is empty') : ListView(children: divided),
body: divided);
},
),
);
}

validation is becomes true before validation is checked in flutter

I have a question about validation. My widget field validation is become true before checked. when I am just open this page validation is automatically becomes true.
I want that validation after user input. but this validation is becoming true before the user entering something inside from the field. so can anyone help me? your help will be appreciated.
Here is the code I've tried.
class BspSignupPage extends StatefulWidget {
static const String routeName = "/bspSignup";
#override
_BspSignupPageState createState() => _BspSignupPageState();
}
class _BspSignupPageState extends State<BspSignupPage>
with AfterLayoutMixin<BspSignupPage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// final TextEditingController _bspPhone = TextEditingController();
final MaskedTextController _bspPhone =
new MaskedTextController(mask: '(000)-000-0000');
final TextEditingController _bspBusinessName = TextEditingController();
final TextEditingController _bspBusinessLegalAddress =
TextEditingController();
final TextEditingController _bspBusinessLicense = TextEditingController();
final TextEditingController _bspLicenseAuthority = TextEditingController();
final TextEditingController _bspEstYear = TextEditingController();
final TextEditingController _bspNumberOfEmployee = TextEditingController();
final TextEditingController _bspBusinessDetailsComment =
TextEditingController();
final TextEditingController _countryCodeController =
new TextEditingController();
BSPSignupRepository _bspSignupRepository = new BSPSignupRepository();
bool bspcheck = false;
BspSignupCommonModel model = BspSignupCommonModel();
int radioValue = -1;
String _alternatephone;
String _businessname;
bool addressenabled = false;
List<dynamic> _type = <dynamic>[];
Map<String, dynamic> _typeValue;
String _establishyear;
String _numberofemployee;
LocationResult _pickedLocation;
DateTime selectedDate = DateTime.now();
bool flexibletime = false;
DateTime date;
TimeOfDay time;
Map<String, dynamic> bspsignupdata = new Map<String, dynamic>();
#override
void initState() {
super.initState();
print(model);
_bspNumberOfEmployee.text = "1";
_bspSignupRepository.getBSTypes().then((businessTypeResponse) {
print('businessTypeResponse');
print(businessTypeResponse);
if (businessTypeResponse['error'] != null) {
} else {
setState(() {
_type = businessTypeResponse['data']['businessTypes'];
});
}
});
setState(() {
date = new DateTime.now().add(new Duration(hours: 1));
time = new TimeOfDay.fromDateTime(date);
});
}
#override
void afterFirstLayout(BuildContext context) {
model = ModalRoute.of(context).settings.arguments;
if (model == null) {
model = new BspSignupCommonModel();
} else {
print('model for edit');
_setExistingDetails(model);
}
}
void _setExistingDetails(bspModel) {
_bspBusinessName.text = bspModel.businessLegalName;
_bspPhone.text = model.businessPhoneNumber;
_bspEstYear.text = model.businessYear;
_bspNumberOfEmployee.text = model.numberofEmployees;
_bspBusinessLegalAddress.text = model.businessLegalAddress;
_typeValue = model.businessTypes;
}
Widget _buildlegalbusinessname() {
return new TudoTextWidget(
controller: _bspBusinessName,
textCapitalization: TextCapitalization.sentences,
prefixIcon: Icon(Icons.business),
labelText: AppConstantsValue.appConst['bspSignup']['legalbusinessname']
['translation'],
hintText: AppConstantsValue.appConst['bspSignup']['legalbusinessname']
['translation'],
validator: (val) =>
Validators.validateRequired(val, "Business legal name"),
onSaved: (val) {
_businessname = val;
bspsignupdata['businessname'] = _businessname;
},
);
}
Widget _buildalternatephone() {
return Row(
children: <Widget>[
new Expanded(
child: new TudoTextWidget(
controller: _countryCodeController,
enabled: false,
prefixIcon: Icon(FontAwesomeIcons.globe),
labelText: "code",
hintText: "Country Code",
),
flex: 2,
),
new SizedBox(
width: 10.0,
),
new Expanded(
child: new TudoNumberWidget(
controller: _bspPhone,
validator: Validators().validateMobile,
labelText: AppConstantsValue.appConst['bspSignup']['alternatephone']
['translation'],
hintText: AppConstantsValue.appConst['bspSignup']['alternatephone']
['translation'],
prefixIcon: Icon(Icons.phone),
onSaved: (val) {
_alternatephone = val;
bspsignupdata['alternatephone'] = _alternatephone;
},
),
flex: 5,
),
],
);
}
Widget _buildestablishedyear() {
return new TudoNumberWidget(
controller: _bspEstYear,
prefixIcon: Icon(FontAwesomeIcons.calendar),
labelText: AppConstantsValue.appConst['bspSignup']['establishedyear']
['translation'],
hintText: AppConstantsValue.appConst['bspSignup']['establishedyear']
['translation'],
validator: Validators().validateestablishedyear,
maxLength: 4,
onSaved: (val) {
_establishyear = val.trim();
bspsignupdata['establishyear'] = _establishyear;
},
);
}
Widget _buildnumberofemployees() {
return new TudoNumberWidget(
controller: _bspNumberOfEmployee,
prefixIcon: Icon(Icons.control_point_duplicate),
labelText: AppConstantsValue.appConst['bspSignup']['numberofemployees']
['translation'],
hintText: AppConstantsValue.appConst['bspSignup']['numberofemployees']
['translation'],
validator: Validators().validatenumberofemployee,
onSaved: (val) {
_numberofemployee = val.trim();
bspsignupdata['numberofemployes'] = _numberofemployee;
},
);
}
Widget _buildbusinesslegaladdress() {
return Row(
children: <Widget>[
new Expanded(
child: new TudoTextWidget(
prefixIcon: Icon(Icons.business),
labelText: AppConstantsValue.appConst['bspSignup']
['businesslegaladdress']['translation'],
hintText: AppConstantsValue.appConst['bspSignup']
['businesslegaladdress']['translation'],
controller: _bspBusinessLegalAddress,
enabled: addressenabled,
validator: (val) =>
Validators.validateRequired(val, "Business legal name"),
),
flex: 5,
),
new SizedBox(
width: 10.0,
),
new Expanded(
child: new FloatingActionButton(
backgroundColor: colorStyles['primary'],
child: Icon(
FontAwesomeIcons.globe,
color: Colors.white,
),
elevation: 0,
onPressed: () async {
LocationResult result = await LocationPicker.pickLocation(
context,
"AIzaSyDZZeGlIGUIPs4o8ahJE_yq6pJv3GhbKQ8",
);
print("result = $result");
setState(() {
_pickedLocation = result;
addressenabled = !addressenabled;
});
// setState(() => _pickedLocation = result);
_bspBusinessLegalAddress.text = _pickedLocation.address;
model.businessGeoLocation = new BusinessGeoLocation(
lat: _pickedLocation.latLng.latitude.toString(),
lng: _pickedLocation.latLng.longitude.toString(),
);
},
),
flex: 2,
),
],
);
}
Widget _buildbusinesstype() {
return FormBuilder(
autovalidate: true,
child: FormBuilderCustomField(
attribute: "Business type",
validators: [FormBuilderValidators.required()],
formField: FormField(
builder: (FormFieldState<dynamic> field) {
return InputDecorator(
decoration: InputDecoration(
prefixIcon: Icon(Icons.perm_identity),
labelText: _type == []
? 'Select Personal Identification type'
: 'Business type',
hintText: "Select Personal Identification type",
errorText: field.errorText,
),
isEmpty: _typeValue == [],
child: new DropdownButtonHideUnderline(
child: new DropdownButton(
// isExpanded: true,
hint: Text("Select Personal Identification type"),
value: _typeValue,
isDense: true,
onChanged: (dynamic newValue) {
print('newValue');
print(newValue);
setState(() {
_typeValue = newValue;
field.didChange(newValue);
});
},
items: _type.map(
(dynamic value) {
return new DropdownMenuItem(
value: value,
child: new Text(value['name']),
);
},
).toList(),
),
),
);
},
)),
);
}
Widget _buildlegalbusinesscheck() {
return TudoConditionWidget(
text: AppConstantsValue.appConst['bspSignup']['legalbusinesscheck']
['translation'],
errortext: AppConstantsValue.appConst['bspSignup']['errortext']
['translation'],
);
}
Widget content(BuildContext context, BspSignupViewModel bspSignupVm) {
final appBar = AppBar(
title: Text("BSP Signup"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
NavigationHelper.navigatetoBack(context);
},
),
centerTitle: true,
);
final bottomNavigationBar = Container(
color: Colors.transparent,
height: 56,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new FlatButton.icon(
icon: Icon(Icons.close),
label: Text('Clear'),
color: Colors.redAccent,
textColor: Colors.black,
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () {
_formKey.currentState.reset();
_bspPhone.clear();
_bspBusinessName.clear();
_bspBusinessLicense.clear();
_bspLicenseAuthority.clear();
_bspEstYear.clear();
_bspNumberOfEmployee.clear();
_bspBusinessDetailsComment.clear();
_bspBusinessLegalAddress.clear();
},
),
new FlatButton.icon(
icon: Icon(FontAwesomeIcons.arrowCircleRight),
label: Text('Next'),
color: colorStyles["primary"],
textColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
model.businessLegalName = _bspBusinessName.text;
model.businessPhoneNumber = _bspPhone.text;
model.businessYear = _bspEstYear.text;
model.numberofEmployees = _bspNumberOfEmployee.text;
model.businessType = _typeValue['id'];
model.businessLegalAddress = _bspBusinessLegalAddress.text;
model.businessTypes = _typeValue;
print('model');
print(model.licensed);
if (_typeValue['name'].toLowerCase() ==
"Licensed / Registered".toLowerCase()) {
model.isLicensed = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BspLicensedSignupPage(
bspSignupCommonModel: model,
),
),
);
} else {
model.isLicensed = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BspUnlicensedSignupPage(
bspSignupCommonModel: model,
),
),
);
}
}
},
),
],
),
);
return Scaffold(
appBar: appBar,
bottomNavigationBar: bottomNavigationBar,
body: Container(
height: double.infinity,
width: double.infinity,
child: Form(
autovalidate: true,
key: _formKey,
child: Stack(
children: <Widget>[
// Background(),
SingleChildScrollView(
padding: const EdgeInsets.all(30.0),
child: new Container(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildlegalbusinessname(),
_buildalternatephone(),
_buildestablishedyear(),
_buildnumberofemployees(),
SizedBox(
height: 5,
),
_buildbusinesslegaladdress(),
_buildbusinesstype(),
_buildlegalbusinesscheck(),
],
),
),
),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new StoreConnector<AppState, BspSignupViewModel>(
converter: (Store<AppState> store) => BspSignupViewModel.fromStore(store),
onInit: (Store<AppState> store) {
_countryCodeController.text =
store.state.auth.loginUser.user.country.isdCode;
},
builder: (BuildContext context, BspSignupViewModel bspSignupVm) =>
content(context, bspSignupVm),
);
}
}
your widget field validation is become true before checked becuase you have given static flag true to "autovalidate" to solve this issue you have to manage flag variable for that
Example:-
bool _autoValidate = false;
Form(
key: _formKey,
autovalidate: _autoValidate,
child: Container(child:Text("")));
And change flag value when first time validating form
void _buttonClicked(BuildContext context) {
setState(() {
_autoValidate = true;
});
}
Update:-
autovalidate is deprecated from Flutter v1.19
Replace autovalidate with autovalidateMode.autovalidateMode can have one of the below 3 values:
autovalidateMode: AutovalidateMode.disabled: No auto validation will occur.
autovalidateMode: AutovalidateMode.always: Used to auto-validate FormField even without user interaction.
autovalidateMode: AutovalidateMode.onUserInteraction: Used to auto-validate FormField only after each user interaction.

Resources