AlertDialog widget not working setState function in Flutter - android-studio

I started to work with DropdownButton widget and I created List of cities. I want to see AlertDialog when i choose my favorite city on the list but it can't work.
Here is codes :
import 'package:flutter/material.dart';
import './func.dart';
class ChooseCity extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return ChooseCityState();
}
}
class ChooseCityState extends State<ChooseCity> {
var cities = ["Ankara", "İzmir", "İstanbul", "Edirne", "Antalya"];
String choosenCity = "Edirne";
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<String>(
items: cities.map((String city) {
return DropdownMenuItem<String>(
child: Text(city),
value: city,
);
}).toList(),
value: choosenCity,
onChanged: (String choosen) {
setState(() {
choosenCity = choosen;});
choosen=="Antalya" ?
AlertDialog(
title:Text("ATTENTION"),
content: Text("You chose the best place!!"),
actions: [
FlatButton(child: Text("I see,I agree"),onPressed: ()=>{},)
],
)
: Text("go on");
},
),
SizedBox(
height: 60,
),
Text(
" You choosed :" + choosenCity,
textAlign: TextAlign.center,
),
],
);
}
}
View of my page :
It doesn't look like as i want. I want to see AlertDialog when i chose "Antalya" . Where is the error? Where should i put the bool function? I tried to put this bool function out of setState function but it didn't be as i want.

If you want to show alert dialog you should use 'showDialog', then in its builder use your Alert Dialog.
Like this
class ChooseCity extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return ChooseCityState();
}
}
class ChooseCityState extends State<ChooseCity> {
var cities = ["Ankara", "İzmir", "İstanbul", "Edirne", "Antalya"];
String chosenCity = "Edirne";
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<String>(
items: cities.map((String city) {
return DropdownMenuItem<String>(
child: Text(city),
value: city,
);
}).toList(),
value: chosenCity,
onChanged: (String choosen) {
chosenCity = choosen;
showAlertDialog();
setState(() {});
},
),
SizedBox(
height: 60,
),
Text(
" You choosed :" + chosenCity,
textAlign: TextAlign.center,
),
],
);
}
showAlertDialog() {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("ATTENTION"),
content: Text("You chose the best place!!"),
actions: [
FlatButton(
child: Text("I see,I agree"),
onPressed: () => {},
)
],
);
},
);
}
}

Related

how to set background color in excel js, depending on the value?

How can I get the values of a column and paint the background color depending on the value.
I have the column: "Stock" and I need to know when the value is 0 to make the background red.
in this way I paint the first row of the header. Is it possible to implement the logic to obtain the mentioned values?
ws.eachRow((row, rowNumber) => {
row.eachCell((cell) => {
console.log(rowNumber);
if (rowNumber == 1) {
cell.fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "2563EB" },
};
}
cell.font = {
color: { argb: "FFFFFF" },
bold: true,
};
cell.border = {
top: { style: "thin" },
left: { style: "thin" },
bottom: { style: "thin" },
right: { style: "thin" },
};
});
row.commit();
});
ws.addRows(arrProducts);
.......

No errors for dropdown list, but still not working on Flutter

Here's my code for my sign in page on Flutter. I have no errors, but it's still not showing the dropdown list, does anyone know why?
I've used the auto-complete search method.
Here's what I've done so far :
Edited the pubspec.yaml
Imported the unilist.json (which I'm using)
Created a Plain Old Dart Object to represent json structure
And finally, edited my sign in dart file.
I'm having no errors so far, so I believe I'm missing something..
Thanks,
import 'package:autocomplete_textfield/autocomplete_textfield.dart';
import 'package:flutter/material.dart';
import 'package:shop_app/components/custom_surfix_icon.dart';
import 'package:shop_app/components/default_button.dart';
import 'package:shop_app/components/form_error.dart';
import 'package:shop_app/screens/complete_profile/complete_profile_screen.dart';
import 'package:shop_app/screens/sign_up/components/unilist.dart';
import '../../../constants.dart';
import '../../../size_config.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
TextEditingController controller = new TextEditingController();
class UniViewModel {
static List<UniName> uni;
static Future loadUni() async {
try {
uni = new List<UniName>();
String jsonString = await rootBundle.loadString('assets/unilist.json');
Map parsedJson = json.decode(jsonString);
var categoryJson = parsedJson['uni'] as List;
for (int i = 0; i < categoryJson.length; i++) {
uni.add(new UniName.fromJson(categoryJson[i]));
}
} catch (e) {
print(e);
}
}
}
class SignUpForm extends StatefulWidget {
#override
_SignUpFormState createState() => _SignUpFormState();
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: AutoComplete(),
),
);
}
}
class AutoComplete extends StatefulWidget {
#override
_AutoCompleteState createState() => new _AutoCompleteState();
}
class _AutoCompleteState extends State<AutoComplete> {
GlobalKey<AutoCompleteTextFieldState<UniName>> key = new GlobalKey();
AutoCompleteTextField searchTextField;
TextEditingController controller = new TextEditingController();
_AutoCompleteState();
void _loadData() async {
await UniViewModel.loadUni();
}
#override
void initState() {
_loadData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text('Auto Complete List Demo'),
),
body: new Center(
child: new Column(children: <Widget>[
new Column(children: <Widget>[
searchTextField = AutoCompleteTextField<UniName>(
style: new TextStyle(color: Colors.black, fontSize: 16.0),
decoration: new InputDecoration(
suffixIcon: Container(
width: 85.0,
height: 60.0,
),
contentPadding: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 20.0),
filled: true,
hintText: 'Search Uni Name',
hintStyle: TextStyle(color: Colors.black)),
itemSubmitted: (item) {
setState(() => searchTextField.textField.controller.text =
item.nom_court);
},
clearOnSubmit: false,
key: key,
suggestions: UniViewModel.uni,
itemBuilder: (context, item) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(item.nom_court,
style: TextStyle(
fontSize: 16.0
),),
Padding(
padding: EdgeInsets.all(15.0),
),
Text(item.localisation,
)
],
);
},
itemSorter: (a, b) {
return a.nom_court.compareTo(b.nom_court);
},
itemFilter: (item, query) {
return item.nom_court
.toLowerCase()
.startsWith(query.toLowerCase());
}),
]),
])));
}
}
class _SignUpFormState extends State<SignUpForm> {
final _formKey = GlobalKey<FormState>();
String email;
String password;
String uni;
String conform_password;
bool remember = false;
final List<String> errors = [];
void addError({String error}) {
if (!errors.contains(error))
setState(() {
errors.add(error);
});
}
void removeError({String error}) {
if (errors.contains(error))
setState(() {
errors.remove(error);
});
}
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
buildEmailFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
FormError(errors: errors),
SizedBox(height: getProportionateScreenHeight(40)),
DefaultButton(
text: "Continuer",
press: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
// if all are valid then go to success screen
Navigator.pushNamed(context, CompleteProfileScreen.routeName);
}
},
),
],
),
);
}
TextFormField buildConformPassFormField() {
return TextFormField(
obscureText: true,
onSaved: (newValue) => conform_password = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPassNullError);
} else if (value.isNotEmpty && password == conform_password) {
removeError(error: kMatchPassError);
}
conform_password = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPassNullError);
return "";
} else if ((password != value)) {
addError(error: kMatchPassError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Confirmez le mot de passe",
hintText: "Reconfirmez le mot de passe",
// If you are using latest version of flutter then lable text and hint text shown like this
// if you r using flutter less then 1.20.* then maybe this is not working properly
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Lock.svg"),
),
);
}
TextFormField buildPasswordFormField() {
return TextFormField(
obscureText: true,
onSaved: (newValue) => password = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPassNullError);
} else if (value.length >= 8) {
removeError(error: kShortPassError);
}
password = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPassNullError);
return "";
} else if (value.length < 8) {
addError(error: kShortPassError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Mot de passe",
hintText: "Saisissez votre mot de passe",
// If you are using latest version of flutter then lable text and hint text shown like this
// if you r using flutter less then 1.20.* then maybe this is not working properly
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Lock.svg"),
),
);
}
TextFormField buildEmailFormField() {
return TextFormField(
keyboardType: TextInputType.emailAddress,
onSaved: (newValue) => email = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kEmailNullError);
} else if (emailValidatorRegExp.hasMatch(value)) {
removeError(error: kInvalidEmailError);
}
return null;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kEmailNullError);
return "";
} else if (!emailValidatorRegExp.hasMatch(value)) {
addError(error: kInvalidEmailError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Email",
hintText: "Enter your email",
// If you are using latest version of flutter then lable text and hint text shown like this
// if you r using flutter less then 1.20.* then maybe this is not working properly
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Mail.svg"),
),
);
}
TextFormField buildUniFormField() {
return TextFormField(
keyboardType: TextInputType.uni,
onSaved: (newValue) => uni = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kEmailNullError);
} else if (emailValidatorRegExp.hasMatch(value)) {
removeError(error: kInvalidEmailError);
}
return null;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kEmailNullError);
return "";
} else if (!emailValidatorRegExp.hasMatch(value)) {
addError(error: kInvalidEmailError);
return "";
}
return null;
},
);
}
}

How to set future String to 'initial value' of TextFormField

Hello Everyone i'm a beginner. I am facing a problem. Below is my code. I want to set Future String as initial value of TextFormField. I successfully did it for only one TextFormField but now i have multiple TextFormField and i tried to fetch data from every field of firebase document and set as initial value of corresponding TextFormField.
If i assign the value to TextFormField 'label' it shows correctly but when i assign the same value to 'initial value' it doesnot show.
Sorry for poor conversation
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:shop_app/components/custom_surfix_icon.dart';
import 'package:shop_app/components/default_button.dart';
import 'package:shop_app/components/form_error.dart';
import 'package:shop_app/size_config.dart';
import '../../../../../../constants.dart';
class EditProfileForm extends StatefulWidget {
#override
_EditProfileFormState createState() => _EditProfileFormState();
}
class _EditProfileFormState extends State<EditProfileForm> {
final _formKey = GlobalKey<FormState>();
final List<String> errors = [];
String name;
String phoneNo;
String gender;
String address;
String about;
String education;
String specialities;
String languages;
String work;
String storeName;
String storePhoneNo;
String storeGender;
String storeAddress;
String storeAbout;
String storeEducation;
String storeSpecialities;
String storeLanguages;
String storeWork;
static const menuItems = <String>[
'Male',
'Female',
'Other',
];
final List<DropdownMenuItem<String>> popUpMenuItem = menuItems
.map((String value) => DropdownMenuItem<String>(
value: value,
child: Text(value),
))
.toList();
void addError({String error}) {
if (!errors.contains(error))
setState(() {
errors.add(error);
});
}
void removeError({String error}) {
if (errors.contains(error))
setState(() {
errors.remove(error);
});
}
// #override
// void initState() {
// super.initState();
// getData();
// }
getData() {
getName();
getPhoneNo();
getAddress();
getAbout();
getEducation();
getSpecialities();
getLanguages();
getWork();
}
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
getNameFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getGenderFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getPhoneNoFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getAddressFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getAboutFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getEducationFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getSpecialitiesFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getLanguagesFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getWorkFormField(),
FormError(errors: errors),
SizedBox(height: getProportionateScreenHeight(40)),
DefaultButton(
text: "Update Profile",
press: () async {
if (_formKey.currentState.validate()) {
print(storeName);
}
},
),
],
),
);
}
///////////////////////////////////////////////////////////////////////////////
Widget getNameFormField() {
return FutureBuilder(
future: getName(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
storeName = snapshot.data;
return TextFormField(
initialValue: storeName,
onSaved: (newValue) => name = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kNamelNullError);
}
name = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kNamelNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: storeName,
hintText: "Enter your name",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getName() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getName = document['Name'];
return getName;
}
///////////////////////////////////////////////////////////////////////////////
Widget getPhoneNoFormField() {
return FutureBuilder(
future: getPhoneNo(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot1) {
storePhoneNo = snapshot1.data;
return TextFormField(
initialValue: storePhoneNo,
onSaved: (newValue) => phoneNo = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPhoneNumberNullError);
}
phoneNo = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPhoneNumberNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Phone No",
hintText: "Enter Phone No",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Phone.svg"),
),
);
},
);
}
Future<String> getPhoneNo() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getPhoneNo = document['Phone Number'];
return getPhoneNo;
}
///////////////////////////////////////////////////////////////////////////////
DropdownButtonFormField getGenderFormField() {
return DropdownButtonFormField(
onSaved: (newValue) {
gender = newValue;
},
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kNamelNullError);
}
gender = value;
print(gender);
},
validator: (value) {
if (value.isEmpty) {
addError(error: kNamelNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Gender",
hintText: "Select your gender",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/gender.svg"),
),
items: popUpMenuItem,
);
}
Future<String> getGender() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getGender = document['Gender'];
return getGender;
}
///////////////////////////////////////////////////////////////////////////////
Widget getAddressFormField() {
return FutureBuilder(
future: getAddress(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot2) {
storeAddress = snapshot2.data;
return TextFormField(
initialValue: storeAddress,
onSaved: (newValue) => address = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kAddressNullError);
}
address = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kAddressNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Address",
hintText: "Enter your address",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Location point.svg"),
),
);
},
);
}
Future<String> getAddress() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getName = document['Address'];
return getName;
}
///////////////////////////////////////////////////////////////////////////////
Widget getAboutFormField() {
return FutureBuilder(
future: getAbout(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot3) {
storeAbout = snapshot3.data;
return TextFormField(
initialValue: storeAbout,
onSaved: (newValue) => about = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kAboutNullError);
}
about = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kAboutNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "About",
hintText: "Describe Yourself",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getAbout() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getAbout = document['About'];
return getAbout;
}
///////////////////////////////////////////////////////////////////////////////
Widget getEducationFormField() {
return FutureBuilder(
future: getEducation(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot4) {
storeEducation = snapshot4.data;
return TextFormField(
initialValue: storeEducation,
onSaved: (newValue) => education = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kEducationNullError);
}
education = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kEducationNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Education",
hintText: "Enter your education",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getEducation() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getEducation = document['Education'];
return getEducation;
}
///////////////////////////////////////////////////////////////////////////////
Widget getSpecialitiesFormField() {
return FutureBuilder(
future: getSpecialities(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot5) {
storeSpecialities = snapshot5.data;
return TextFormField(
initialValue: storeSpecialities,
onSaved: (newValue) => specialities = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kSkillsNullError);
}
specialities = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kSkillsNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Specialities",
hintText: "Enter your specialities",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getSpecialities() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getSpecialities = document['Specialities'];
return getSpecialities;
}
///////////////////////////////////////////////////////////////////////////////
Widget getLanguagesFormField() {
return FutureBuilder(
future: getLanguages(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot6) {
storeLanguages = snapshot6.data;
return TextFormField(
initialValue: storeLanguages,
onSaved: (newValue) => languages = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kLanguagesNullError);
}
languages = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kLanguagesNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Languages",
hintText: "Enter Your Languages",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getLanguages() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getLanguages = document['Languages'];
return getLanguages;
}
///////////////////////////////////////////////////////////////////////////////
Widget getWorkFormField() {
return FutureBuilder(
future: getWork(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot7) {
storeWork = snapshot7.data;
return TextFormField(
initialValue: storeWork,
onSaved: (newValue) => work = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kWorkNullError);
}
work= value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kWorkNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Work",
hintText: "What you do?",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getWork() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getWork = document['Work'];
return getWork;
}
}
you can just call the function that returns you the Future String in the initState() and after that, you can set that string as TextInput hint

SwiftUI - Changing struct data set in ForEach?

I'm new to programming and SwiftUI and I am making this app where users can select these buttons labeled A-D. They may choose more than 1, and I am hoping that when they click on the button, the background colour will change from grey to green. However, if I replace "// Here" in the code at the bottom with
Data.Selected = true
Data.Colour = .green
I get an error saying "Cannot assign to property: 'Data' is a 'let' constant". I understand what that means, but I don't know how to change Data to var. I tried typing var in front of "Data in" but I got this error instead "Consecutive statements on a line must be separated by ';'". Is there anyway I can directly modify Data/ButtonsData? Or is there a workaround?
struct Buttons: Hashable {
var Crit: String
var Selected: Bool
var Colour: Color
}
var ButtonsData = [
Buttons(Crit: "A", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "B", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "C", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "D", Selected: false, Colour: Color(.systemGray4))
]
struct CritView: View {
#Binding var CritBoard: Bool
#Binding var BackgroundColor: Color
var body: some View {
ZStack(alignment: .topLeading) {
ScrollView(.vertical, showsIndicators: false) {
HStack(spacing: 15) {
ForEach(ButtonsData, id: \.self) { Data in
Button(action: {
// HERE
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(Data.Colour)
.cornerRadius(10)
}
}
.padding(.top, 50)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/8)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.background(Color(.white))
.cornerRadius(25)
Button(action: {
self.CritBoard.toggle()
self.BackgroundColor = .white
}) {
Image(systemName: "xmark").foregroundColor(.black)
}.padding(25)
}
}
}
Here is possible solution - create array of index/value tuples and modify your data in original container by index:
ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
Button(action: {
ButtonsData[i].Selected = true
ButtonsData[i].Colour = .green
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(Data.Colour)
.cornerRadius(10)
}
Well, I don't think a lot of people would actually have the same/similar problem but this is my working code. The code uses both #Aspersi's answer as well as the code in a Hacking with Swift article. (it might not be the most simplified code, but it works right now at least)
ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
Button(action: {
self.AllData[i].Selected.toggle()
if self.AllData[i].Selected == true {
self.AllData[i].Colour = .green
} else {
self.AllData[i].Colour = Color(.systemGray4)
}
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(self.AllData[i].Colour)
.cornerRadius(10)
}
Full code below
struct Buttons: Hashable {
var Crit: String
var Selected: Bool = false
var Colour: Color
}
var ButtonsData = [
Buttons(Crit: "A", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "B", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "C", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "D", Selected: false, Colour: Color(.systemGray4))
]
struct CritView: View {
#Binding var CritBoard: Bool
#Binding var BackgroundColor: Color
#State private var AllData = ButtonsData
var body: some View {
ZStack(alignment: .topLeading) {
ScrollView(.vertical, showsIndicators: false) {
HStack(spacing: 15) {
ForEach(Array(ButtonsData.enumerated()), id: \.element) { I, Data in
Button(action: {
self.AllData[i].Selected.toggle()
if self.AllData[i].Selected == true {
self.AllData[i].Colour = .green
} else {
self.AllData[i].Colour = Color(.systemGray4)
}
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(self.AllData[i].Colour)
.cornerRadius(10)
}
}
.padding(.top, 50)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/8)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.background(Color(.white))
.cornerRadius(25)
Button(action: {
self.CritBoard.toggle()
self.BackgroundColor = .white
}) {
Image(systemName: "xmark").foregroundColor(.black)
}.padding(25)
}
}
}

Realm-js: Cannot access realm that has been closed

Realm keeps throwing this error in a simple use case:
Cannot access realm that has been closed
My files:
RealmExample.js
import Realm from 'realm';
class Item {}
Item.schema = {
name: 'Item',
properties: {
name: 'string',
date: 'date',
id: 'string'
},
};
export default new Realm({schema: [Item]});
app.js
//My imports
export default class App extends Component<{}> {
render() {
return (
<RealmProvider realm={realm}>
<ConnectedExample />
</RealmProvider>
);
}
}
ConnectedExample.js
import React, { Component } from 'react';
import {
Text,
ScrollView,
TouchableOpacity,
View,
StyleSheet,
} from 'react-native';
import uuid from 'uuid';
import { connectRealm } from 'react-native-realm';
import ConnectedExampleItem from './ConnectedExampleItem';
const styles = StyleSheet.create({
screen: {
paddingTop: 20,
paddingHorizontal: 10,
backgroundColor: '#2a2a2a',
flex: 1,
},
add: {
height: 44,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 10,
backgroundColor: '#1a1a1a',
},
addText: {
color: 'white',
},
});
class ConnectedExample extends Component {
count = 0;
onPressAddItem = () => {
const { realm } = this.props;
realm.write(() => {
realm.create('Item', {
name: this.count.toString(),
date: new Date(),
id: uuid.v4(),
});
this.count++;
});
};
render() {
return (
<View style={styles.screen}>
<TouchableOpacity onPress={this.onPressAddItem} style={styles.add}>
<Text style={styles.addText}>Add Item</Text>
</TouchableOpacity>
<ScrollView>
{this.props.items.map((item) => (
<View key={item.id}>
<ConnectedExampleItem id={item.id} />
</View>
))}
</ScrollView>
</View>
);
}
}
export default connectRealm(ConnectedExample, {
schemas: ['Item'],
mapToProps(results, realm) {
return {
realm,
items: results.items.sorted('date') || [],
};
},
});
ConnectedExampleItem.js
import React, {
Component,
PropTypes,
} from 'react';
import {
StyleSheet,
TouchableOpacity,
Text,
} from 'react-native';
import { connectRealm } from 'react-native-realm';
const styles = StyleSheet.create({
item: {
height: 44,
justifyContent: 'center',
paddingHorizontal: 10,
marginTop: 10,
backgroundColor: 'cyan',
},
});
class ConnectedExampleItem extends Component {
onPressRemoveItem = (item) => {
const { realm } = this.props;
realm.write(() => {
realm.delete(item);
});
};
render() {
return (
<TouchableOpacity
onPress={() => this.onPressRemoveItem(this.props.item)}
style={styles.item}
>
<Text>{this.props.item.name}</Text>
</TouchableOpacity>
);
}
}
export default connectRealm(ConnectedExampleItem, {
schemas: ['Item'],
mapToProps(results, realm, ownProps) {
return {
realm,
item: results.items.find(item => item.id === ownProps.id),
};
},
});
The strange thing is that when running this code on my project I run into the Cannot access realm that has been closed (I haven't instantiated Realm anywhere else), however, if I run the example in the react-native-realm repo, it runs fine.
Also, the introduction example on the Realm documentation page runs fine as well.
What could be the issue?
Thank you.
PS: Running on React-native 0.51, Android device 6.0.

Resources