New to flutter and unsure how to solve this error: Exception has occurred. LateError - flutter

Getting the error message: 'Exception has occurred.
LateError (LateInitializationError: Field 'selectedImage' has not been initialized'
Anyone know how I can solve this?
Been following a tutorial to build an app that I can add photos to but got a bit stuck on this part.
using firebase storage to store the photos, as far as I can tell thats been set up correctly.
thanks.
class CreateBlog extends StatefulWidget {
const CreateBlog({Key? key}) : super(key: key);
#override
State<CreateBlog> createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
String? authorName, title, desc;
File? selectedImage;
CrudMethods crudMethods = CrudMethods();
Future getImage() async {
var image = await ImagePicker().pickImage(source: ImageSource.camera);
setState(() {
selectedImage = image as File;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Travel',
style: TextStyle(fontSize: 22),
),
Text('Blog', style: TextStyle(fontSize: 22, color: Colors.green))
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
width: MediaQuery.of(context).size.width,
child: Image.file(selectedImage),
margin: const EdgeInsets.symmetric(horizontal: 16),
)
: Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
child: const Icon(Icons.add))),
],
),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
children: <Widget>[
const SizedBox(height: 12),
Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6),
),
width: MediaQuery.of(context).size.width,
child: const Icon(Icons.add_a_photo, color: Colors.black45)),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: <Widget>[
TextField(
decoration: const InputDecoration(hintText: 'Author Name'),
onChanged: (val) {
authorName = val;
},
),
TextField(
decoration: const InputDecoration(hintText: 'Title'),
onChanged: (val) {
title = val;
},
),
TextField(
decoration:
const InputDecoration(hintText: 'Description'),
onChanged: (val) {
desc = val;
}),
],
),
)
],
),
),
);
}
}

It is possible to get null value from pickedImage, Try accepting null value.
Future getImage() async {
XFile? image = await ImagePicker().pickImage(source: ImageSource.camera);
if (image != null) {
setState(() {
selectedImage = image;
});
}
}
And use
child: selectedImage != null
? Container(
height: 150,
width: MediaQuery.of(context).size.width,
child: Image.file(File(selectedImage!.path)),
margin: const EdgeInsets.symmetric(horizontal: 16),
)

The error really implies that you wrote
late File? selectedImage;
instead of
File? selectedImage;
so I think you showed us the wrong code. Leaving out late should solve this.

Let me know whether it is working for you.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class CreateBlog extends StatefulWidget {
const CreateBlog({Key? key}) : super(key: key);
#override
State<CreateBlog> createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
String? authorName, title, desc;
XFile? selectedImage;
getImage() async {
try {
final XFile? pickedImage =
await ImagePicker().pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
setState(() {
selectedImage = pickedImage;
});
}
} catch (e) {
debugPrint(e.toString());
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Travel',
style: TextStyle(fontSize: 22),
),
Text('Blog', style: TextStyle(fontSize: 22, color: Colors.black))
],
),
backgroundColor: Colors.grey,
elevation: 0.0,
),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
children: <Widget>[
const SizedBox(height: 12),
GestureDetector(
onTap: () {
getImage();
},
child: selectedImage != null
? Container(
height: 150,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(horizontal: 16),
child: Image.file(File(selectedImage!.path)),
)
: Container(
height: 150,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6),
),
width: MediaQuery.of(context).size.width,
child:
const Icon(Icons.add_a_photo, color: Colors.black45)),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: <Widget>[
TextField(
decoration: const InputDecoration(hintText: 'Author Name'),
onChanged: (val) {
authorName = val;
},
),
TextField(
decoration: const InputDecoration(hintText: 'Title'),
onChanged: (val) {
title = val;
},
),
TextField(
decoration:
const InputDecoration(hintText: 'Description'),
onChanged: (val) {
desc = val;
}),
],
),
)
],
),
),
);
}
}

Related

Flutter default profile picture for signup with u8intlist

The code below is my signup code, it has everything that I need but I got a problem with the default image. I made the connection with firebase but now I need to insert a default picture if the person doesn't chose a profile picture. What is the best way to tackle this?
I use de imagepicker to pick a picture from your own gallery, that is used in a async function called selectimage()
Then the async signup function is the function where the authmethods().signUpUser takes place. In this function it will then say that _image is null and that I can't use the ! operator.
import 'dart:typed_data';
import 'package:event_app/pages/Login_Page.dart';
import 'package:event_app/resources/auth_methods.dart';
import 'package:event_app/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
import '../utils/colors.dart';
import '../widgets/text_field_input.dart';
import '../widgets/password_field_input.dart';
import 'Verify_Email_Page.dart';
class SignupPage extends StatefulWidget {
const SignupPage({Key? key}) : super(key: key);
#override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _usernameController = TextEditingController();
bool _isLoading = false;
Uint8List? _image;
#override
void dispose() {
super.dispose();
_emailController.dispose();
_passwordController.dispose();
_usernameController.dispose();
}
void selectImage() async {
Uint8List im = await pickImage(ImageSource.gallery);
setState(() {
_image = im;
});
}
void signUpUser() async {
setState(() {
_isLoading = true;
});
String res = await AuthMethods().signUpUser(
email: _emailController.text,
password: _passwordController.text,
username: _usernameController.text,
file: _image!);
if (res == "Success") {
setState(() {
_isLoading = false;
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const VerifyEmailPage()));
} else {
setState(() {
_isLoading = false;
});
showSnackBar(res, context);
}
}
void navigateToLogin() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const LoginPage()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 32),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Container(),
flex: 2,
),
SvgPicture.asset(
'assets/ic_instagram.svg',
color: textColor,
height: 64,
),
const SizedBox(
height: 64,
),
Stack(
children: [
_image != null
? CircleAvatar(
radius: 64,
backgroundImage: MemoryImage(_image!),
backgroundColor: Colors.grey,
)
: const CircleAvatar(
radius: 64,
backgroundImage: NetworkImage(
'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png'),
backgroundColor: Colors.grey,
),
Positioned(
bottom: -10,
left: 80,
child: IconButton(
onPressed: selectImage,
icon: const Icon(Icons.add_a_photo)))
],
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your username',
textInputType: TextInputType.text,
textEditingController: _usernameController,
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your email',
textInputType: TextInputType.emailAddress,
textEditingController: _emailController,
),
const SizedBox(
height: 24,
),
PasswordFieldInput(
hintText: 'Enter your password',
textInputType: TextInputType.text,
textEditingController: _passwordController,
),
const SizedBox(
height: 24,
),
InkWell(
child: Container(
child: !_isLoading
? const Text('Sign up')
: const Center(
child: CircularProgressIndicator(
color: textColor,
),
),
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
color: accentColor,
),
),
onTap: signUpUser,
),
SizedBox(
height: 12,
),
Flexible(
child: Container(),
flex: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: const Text("Already have an account?"),
padding: const EdgeInsets.symmetric(vertical: 8),
),
GestureDetector(
onTap: navigateToLogin,
child: Container(
child: const Text(
"Login.",
style: TextStyle(fontWeight: FontWeight.bold),
),
padding: const EdgeInsets.symmetric(vertical: 8),
),
)
],
),
],
),
)),
);
}
}
What if you change the selectImage function from async to sync function to prevent api call before _image is set.
void selectImage(){
pickImage(ImageSource.gallery).then(
(im){
setState(() {
_image = im;
});
});
}

How to make image fit box in Flutter?

New to flutter and had some great help with this project so far.
Little stuck on how to make the image i add from gallery fit the widget box.
Also, is there a simple way to move the add image icon into the widget, if you look at the first image the icon is to the top right of the screen and would prefer it in the icon, so you click that to add the photo.
here's the code
import 'dart:io' show File;
import 'package:image_picker/image_picker.dart';
import 'package:blog/services/crud.dart';
import 'package:flutter/material.dart';
class CreateBlog extends StatefulWidget {
const CreateBlog({Key? key}) : super(key: key);
#override
State<CreateBlog> createState() => _CreateBlogState();
}
class _CreateBlogState extends State<CreateBlog> {
File? image2;
final _picker = ImagePicker();
String? authorName, title, desc;
File? selectedImage;
CrudMethods crudMethods = CrudMethods();
Future getImage() async {
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
// final File? image2 = File(image!.path);
if (image != null) {
setState(() {
selectedImage = File(image.path);
// File? image2 = File(image!.path);
// selectedImage!(image2);
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text(
'Travel',
style: TextStyle(fontSize: 22),
),
Text('Blog', style: TextStyle(fontSize: 22, color: Colors.green))
],
),
backgroundColor: Colors.transparent,
elevation: 0.0,
actions: <Widget>[
GestureDetector(
onTap: () {
getImage();
},
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
child: const Icon(Icons.add_a_photo)))
],
),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Column(
children: <Widget>[
const SizedBox(height: 12),
Container(
alignment: Alignment.center,
width: double.infinity,
height: 300,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(6),
),
//width: MediaQuery.of(context).size.width,
child: selectedImage != null
? Image.file(selectedImage!, fit: BoxFit.cover)
: const Text(
'Image will appear here',
style: TextStyle(color: Colors.black),
)),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Column(
children: <Widget>[
TextField(
decoration: const InputDecoration(hintText: 'Author Name'),
onChanged: (val) {
authorName = val;
},
),
TextField(
decoration: const InputDecoration(hintText: 'Title'),
onChanged: (val) {
title = val;
},
),
TextField(
decoration:
const InputDecoration(hintText: 'Description'),
onChanged: (val) {
desc = val;
}),
],
),
)
],
),
),
);
}
}
added result photo

only when use iphone simulator

I have this error:
The following FileSystemException was thrown resolving an image codec:
Cannot open file, path = '/Users/todo/Library/Developer/CoreSimulator/Devices/82205CEC-3D83-4A29-BF17-01C5B0515F71/data/Containers/Data/Application/035B9913-BEC5-46BA-84A5-8C1FE3C4E671/tmp/image_picker_B8D488A3-2790-4D53-A5D8-52E57E2C4108-76094-000003172DF085D2.jpg' (OS Error: No such file or directory, errno = 2)
When the exception was thrown, this was the stack
only when use iphone simulator while android emulator no problem
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../app/utility.dart';
import '../db/aql_db.dart';
import '../globals.dart';
import '../menu_page.dart';
import '../model/aql_model.dart';
import '../widget/input_text.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
var _current = resultsFld[0];
class AqlPg extends StatefulWidget {
const AqlPg({Key? key}) : super(key: key);
#override
State<AqlPg> createState() => _AqlPgState();
}
class _AqlPgState extends State<AqlPg> {
final List<TextEditingController> _criticalController = [];
final List<TextEditingController> _majorController = [];
final List<TextEditingController> _minorController = [];
final List<TextEditingController> _imgCommintControllers = [];
final _irController = TextEditingController();
bool clickedCentreFAB =
false; //boolean used to handle container animation which expands from the FAB
int selectedIndex =
0; //to handle which item is currently selected in the bottom app bar
//call this method on click of each bottom app bar item to update the screen
void updateTabSelection(int index, String buttonText) {
setState(() {
selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
//
_irController.text = aqltbl.ir ?? '';
String _current = aqltbl.result ?? resultsFld[0];
//
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
//---- stack for FloatingActionButton
Stack(
children: <Widget>[
//this is the code for the widget container that comes from behind the floating action button (FAB)
Align(
alignment: FractionalOffset.bottomCenter,
child: AnimatedContainer(
child: const Text(
'Hello',
style: TextStyle(fontSize: 18, color: whiteColor),
),
duration: const Duration(milliseconds: 250),
//if clickedCentreFAB == true, the first parameter is used. If it's false, the second.
height: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
width: clickedCentreFAB
? MediaQuery.of(context).size.height
: 10.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
clickedCentreFAB ? 0.0 : 300.0),
color: Colors.blue),
),
),
],
),
// --- Top Page Title
const SizedBox(
height: 50,
),
const Center(
child: Text(
'Aql page',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
color: medBlueColor),
),
),
Text(
'Shipment no:$shipmentId',
style: const TextStyle(color: medBlueColor),
),
//--- input container
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
Container(
height: 270,
width: 300,
margin: const EdgeInsets.only(top: 5),
child: ListView.builder(
itemCount: (aqltbl.aql ?? []).length,
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
//here
var _aqlList = aqltbl.aql![index];
//
if (aqltbl.aql!.length > _criticalController.length) {
_criticalController.add(TextEditingController());
_majorController.add(TextEditingController());
_minorController.add(TextEditingController());
}
//
_criticalController[index].text =
_aqlList.critical ?? '';
_majorController[index].text = _aqlList.major ?? '';
_minorController[index].text = _aqlList.minor ?? '';
//
return Column(
children: [
Container(
height: 260,
width: 200,
margin: const EdgeInsets.only(left: 10),
padding: const EdgeInsets.all(10),
// ignore: prefer_const_constructors
decoration: BoxDecoration(
color: lightBlue,
borderRadius: BorderRadius.circular(10),
),
child: Column(
children: [
Text(
(_aqlList.name ?? '').toString(),
style: const TextStyle(
color: medBlueColor,
fontSize: 13,
),
),
// ignore: prefer_const_constructors
MyInputField(
title: 'critical',
hint: 'write critical ',
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _criticalController[index],
onSubmit: (value) {
setState(() {
aqltbl.aql![index].critical = value;
_save();
});
},
),
MyInputField(
title: 'majority',
hint: 'write majority ',
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _majorController[index],
onSubmit: (value) {
setState(() {
aqltbl.aql![index].major = value;
_save();
});
},
),
MyInputField(
title: 'minority',
hint: 'write minority ',
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _minorController[index],
onSubmit: (value) {
setState(() {
aqltbl.aql![index].minor = value;
_save();
});
},
),
],
),
),
],
);
}),
),
Container(
height: 270,
width: 300,
margin: const EdgeInsets.only(right: 10, left: 20),
padding: const EdgeInsets.only(
left: 10, bottom: 3, right: 10, top: 5),
decoration: const BoxDecoration(
color: lightBlue,
),
child: Column(
children: [
const Text(
'Summery results',
style: TextStyle(color: medBlueColor),
),
Container(
margin: const EdgeInsets.only(top: 10, bottom: 5),
alignment: Alignment.centerLeft,
child: const Text(
'Results',
style: TextStyle(color: medBlueColor),
),
),
Container(
padding: const EdgeInsets.only(right: 5, left: 5),
decoration: BoxDecoration(
color: whiteColor,
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: borderColor,
)),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
focusColor: whiteColor,
value: aqltbl.result,
hint: const Text('select result'),
isExpanded: true,
iconSize: 36,
icon: const Icon(Icons.arrow_drop_down),
items: resultsFld.map((res) {
return DropdownMenuItem<String>(
value: res,
child: Text(
res,
style: const TextStyle(
fontFamily: 'tajawal',
fontSize: 15,
color: medBlueColor),
),
);
}).toList(),
onChanged: (val) {
setState(() {
aqltbl.result = val;
});
_save();
},
),
),
),
// aqltbl.result = selRes;
MyInputField(
width: 300,
title: 'information remarks (ir)',
hint: '',
maxLines: 3,
borderColor: borderColor,
textColor: textColor,
hintColor: hintColor,
controller: _irController,
onSubmit: (value) {
aqltbl.ir = value;
_save();
},
),
],
),
),
],
),
),
//Images Container
Container(
height: 400,
padding: const EdgeInsets.all(0),
margin: const EdgeInsets.only(bottom: 10, left: 10),
decoration: const BoxDecoration(color: lightGrey),
child: (aqltbl.images ?? []).isEmpty
? Column(
children: [
Image.asset(
'images/empty-photo.jpg',
height: 300,
),
Container(
margin: const EdgeInsets.only(top: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('Click'),
Text(
'Camera button',
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(' to add new photo'),
],
)),
],
)
: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: (aqltbl.images ?? []).length,
itemBuilder: (context, imgIndex) {
String? _image =
(aqltbl.images ?? [])[imgIndex].name.toString();
inspect('aql image file');
File(_image).exists() == true
? inspect('image exist')
: inspect('not exist: ' + _image);
inspect('_image: ' + _image);
if (aqltbl.images!.length >
_imgCommintControllers.length) {
_imgCommintControllers.add(TextEditingController());
}
_imgCommintControllers[imgIndex].text =
aqltbl.images![imgIndex].imgComment!;
inspect(_imgCommintControllers.length);
return Container(
margin: const EdgeInsets.only(left: 5),
height: 300,
child: Column(
children: [
Stack(
children: [
Image.file(
File(_image),
height: 300,
),
Container(
decoration: const BoxDecoration(
color: medBlueColor,
),
child: IconButton(
onPressed: () {
inspect('clear');
String imgName =
aqltbl.images![imgIndex].name ??
'';
aqltbl.images!.removeAt(imgIndex);
// aqltbl.images!.removeWhere(
// (item) => item.name == imgName);
_imgCommintControllers
.removeAt(imgIndex);
setState(() {});
},
color: whiteColor,
icon: const Icon(Icons.clear)),
)
],
),
MyInputField(
title: 'Write remarks about image',
hint: '',
controller: _imgCommintControllers[imgIndex],
onSubmit: (value) {
aqltbl.images![imgIndex].imgComment = value;
aqltbl.images![imgIndex].name = _image;
_save();
},
),
],
));
}),
),
],
),
),
// --- FloatingActionButton
floatingActionButtonLocation: FloatingActionButtonLocation
.centerDocked, //specify the location of the FAB
floatingActionButton: FloatingActionButton(
backgroundColor: medBlueColor,
onPressed: () {
inspect(aqltbl);
setState(() {
clickedCentreFAB =
!clickedCentreFAB; //to update the animated container
});
},
tooltip: "Centre FAB",
child: Container(
margin: const EdgeInsets.all(15.0),
child: const Icon(Icons.send),
),
elevation: 4.0,
),
// --- bottom action bar
bottomNavigationBar: BottomAppBar(
child: Container(
margin: const EdgeInsets.only(left: 12.0, right: 12.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
//to leave space in between the bottom app bar items and below the FAB
IconButton(
//update the bottom app bar view each time an item is clicked
onPressed: () {
// updateTabSelection(0, "Home");
Get.to(const MainMenu());
},
iconSize: 27.0,
icon: Image.asset(
'images/logo.png',
color: medBlueColor,
),
),
const SizedBox(
width: 50.0,
),
IconButton(
onPressed: () async {
// updateTabSelection(2, "Incoming");
await _takeImage('gallery');
},
iconSize: 27.0,
icon: const Icon(
Icons.image_outlined,
color: medBlueColor,
),
),
IconButton(
onPressed: () async {
// updateTabSelection(1, "Outgoing");
await _takeImage('camera');
},
iconSize: 27.0,
icon: const Icon(
Icons.camera_alt,
color: medBlueColor,
),
),
],
),
),
//to add a space between the FAB and BottomAppBar
shape: const CircularNotchedRectangle(),
//color of the BottomAppBar
color: Colors.white,
),
);
}
_save() {
inspect('submit');
saveAql(shipmentId, aqltbl);
box.write('aql'+shipmentId.toString(), aqltbl);
}
_takeImage(method) async {
String _imgPath = await imageFromDevice(method);
if (_imgPath != empty) {
ImagesModel imgMdl = ImagesModel();
imgMdl.name = _imgPath;
imgMdl.imgComment = '';
if (aqltbl.images != null) {
// _saveLocaly(close: 0);
setState(() {
aqltbl.images!.add(imgMdl);
_save();
});
}
}
}
Future _sendAqlToServer() async {
try {
var response = await http.post(urlSendProductPhoto, body: {
'aql': json.encode(aqltbl).toString(),
'id': shipmentId.toString(),
});
if (response.statusCode == 200) {
Get.snackbar('Success', 'Image successfully uploaded');
return response.body;
} else {
Get.snackbar('Fail', 'Image not uploaded');
inspect('Request failed with status: ${response.statusCode}.');
return 'empty';
}
} catch (socketException) {
Get.snackbar('warning', 'Image not uploaded');
return 'empty';
}
}
}
Try following the path that it is saying it cannot find in your computer, I had a similar issue, I tried opening an Iphone 12 instead of an Iphone 13 and it worked out the issue, my problem was I inadvertently deleted a few files I shouldn't have.

Dart Null safety error : Null check operator used on a null value [duplicate]

This question already has answers here:
Null check operator used on a null value
(12 answers)
Closed last year.
I got this error, i understood it but i don't know how to fix it
This error occurs when I try to use the variables of the profilPicker class.
class MyDrawerPages extends StatefulWidget {
final ValueChanged<DrawerItem> onSelectedItem;
final VoidCallback? onClick;
const MyDrawerPages({
Key? key,
required this.onSelectedItem,
this.onClick,
}) : super(key: key);
#override
_MyDrawerPagesState createState() => _MyDrawerPagesState();
}
class _MyDrawerPagesState extends State<MyDrawerPages> {
final signUpKey = GlobalKey<_ProfilPickerState>();
var stringName = '';
var stringTeam = '';
#override
Widget build(BuildContext context) {
final name = signUpKey.currentState!.name;
final team = signUpKey.currentState!.team;
final bool isSignin = signUpKey.currentState!.isSignin;
return Scaffold(
body: Container(
color: const Color(0xFFE26A2C),
child: Column(
children: [
Padding(
key: signUpKey,
padding: const EdgeInsets.only(top: 20, bottom: 10),
child: ListTile(
leading: GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/profil_picker');
},
child: const CircleAvatar(
backgroundColor: Color(0xFF463E3E),
child: Icon(
Icons.person,
size: 40,
color: Colors.white,
),
radius: 22,
),
),
title: Text(
isSignin ? name.toString().toUpperCase() : stringName,
style: const TextStyle(color: Colors.white),
),
subtitle: Text(
isSignin
? team.toString()
: stringTeam,
style: const TextStyle(color: Colors.white)),
),
),
SingleChildScrollView(
child: Column(children: [listTileDrawer(context)]),
),
],
),
),
);
}
here is the ProfilPicker class
class _ProfilPickerState extends State<ProfilPicker> {
bool visible = false;
File? image;
late String name;
late String team;
TextEditingController nameController = TextEditingController();
TextEditingController teamController = TextEditingController();
var isSignin = true;
Future pickeImage(ImageSource source) async {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
final saveImage = await saveImagepermanently(image.path);
try {
setState(() {
this.image = saveImage;
});
} on Exception catch (e) {
// ignore: avoid_print
print('failed to pick image $e');
}
}
bool signUp = true;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
iconTheme: const IconThemeData(color: Colors.black),
backgroundColor: Colors.transparent,
elevation: 0,
),
backgroundColor: const Color(0xFFFFFFFF),
body: Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Column(
children: [
Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: Colors.blueGrey[200],
borderRadius: BorderRadius.circular(200)),
child: image != null
? ClipOval(
child: Image.file(
image!,
width: 150,
height: 150,
fit: BoxFit.cover,
),
)
: const Icon(
Icons.add_a_photo,
size: 30,
),
),
],
),
const SizedBox(
height: 100,
),
signUp
? Column(
children: [
Card(
margin:
const EdgeInsets.symmetric(horizontal: 40),
child: ListTile(
onTap: () {
setState(() {
pickeImage(ImageSource.gallery);
signUp = false;
});
},
leading: const Icon(Icons.image_outlined),
title: const Text("Gallery"),
),
color: Colors.blue[100]),
const SizedBox(
height: 10,
),
Card(
color: Colors.blue[100],
margin: const EdgeInsets.symmetric(horizontal: 40),
child: ListTile(
onTap: () {
setState(() {
pickeImage(ImageSource.camera);
signUp = false;
});
},
leading: const Icon(Icons.camera),
title: const Text("Camera"),
),
),
],
)
: Column(
children: [
_listTileBuilder(),
const SizedBox(
height: 30,
)
],
)
],
),
),
),
),
);
}
_listTileBuilder() {
return SingleChildScrollView(
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 4),
child: const Text('Profil')),
const Padding(
padding: EdgeInsets.only(right: 50),
child: Divider(
indent: 4,
color: Colors.black,
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: [
TextField(
controller: nameController,
maxLines: 1,
keyboardType: TextInputType.name,
style: const TextStyle(fontSize: 14),
decoration: InputDecoration(
filled: true,
fillColor: Colors.blue[100],
border: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(10))),
label: const Text('name',
style: TextStyle(fontStyle: FontStyle.italic)),
),
),
const Padding(padding: EdgeInsets.all(4)),
TextField(
controller: teamController,
maxLines: 1,
keyboardType: TextInputType.name,
style: const TextStyle(fontSize: 14),
decoration: InputDecoration(
filled: true,
fillColor: Colors.blue[100],
border: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(10))),
label: const Text(
'Team',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
)
],
),
),
const Padding(
padding: EdgeInsets.all(20),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
// Navigator.pop();
},
child: Text(
'cancel'.toUpperCase(),
style: const TextStyle(fontWeight: FontWeight.bold),
)),
TextButton(
onPressed: () {
setState(() {
isSignin;
name = nameController.text;
team = teamController.text;
});
},
child: Text('ok'.toUpperCase(),
style: const TextStyle(fontWeight: FontWeight.bold)))
],
)
],
),
);
}
}
I don't have more details
thanks in advance!
I am listening to you,
be indulgent I am a beginner thank you!
error code
════════ Exception caught by widgets library ═══════════════════════════════════
The following _CastError was thrown building MyDrawerPages(dirty, state: _MyDrawerPagesState#a6f02):
Null check operator used on a null value
the problem is here
final name = signUpKey.currentState!.name;
final team = signUpKey.currentState!.team;
you're trying to access name and team where they are supposed to be not null, because they are marked late, but you don't assign them a value until you click on the ok button, which in the build method above they are null.
so you should make them nullable and check wether they are null or not instead. like this:
String? name;
String? team;
...
final name = signUpKey.currentState!.name ?? '';
final team = signUpKey.currentState!.team ?? '';
try this and tell me if it worked!
This error is caused When Null check operator (!) is used on variable with a null value.
You must track all the variable and find this null value or use other operator to solve the problem or check if the value is not null.
You can use ?? operator and give an alternative value if null like this
Text(name ?? 'Not Found')
You can find every thing you need about null aware operators in this article Go To Article

Why is Flutter BloC UI not updating after app restart despite state change in observer?

I concede that there are many questions similar to mine, but I have not found a satisfactory answer from those questions. So I decided to make my own question specifying my problem. I have 3 BloCs in my program each with different purposes. They all share similar problems, as such I will ask on one of those BloCs with the hope that one solution will fix all of the BloCs.
The problem is this, if I just started the application and have logged in, the BloC will update the UI. If I have logged in, exited the app, and restarted it, the Bloc will not update the UI. The Bloc in question is called DetailpersonilBloc with 1 event called Detail and 2 states called DetailpersonilInitial and Loaded. At the event of Detail, the state Loaded should be emitted.
I called Detail at LoginPage and at GajiPage at initState. This works when I just opened the app, but does not work when I restart the app. I also have equatable thinking that it will help me but apparently it changes nothing.
Note: The "..." at the GajiPage is just some code that I believe is not necessary for reproduction.
DetailpersonilBloc
part 'detailpersonil_event.dart';
part 'detailpersonil_state.dart';
class DetailpersonilBloc
extends Bloc<DetailpersonilEvent, DetailpersonilState> {
DetailpersonilBloc() : super(const DetailpersonilInitial()) {
on<Detail>((event, emit) async {
SharedPreferences pref = await SharedPreferences.getInstance();
String name = pref.getString('nama');
String nrp = pref.getString('NRP');
String pangkat = pref.getString('pangkat');
String jabatan = pref.getString('jabatan');
String satker = pref.getString('satker');
String polda = pref.getString('polda');
String npwp = pref.getString('NPWP');
String rekening = pref.getString('rekening');
String bank = pref.getString('bank');
emit(Loaded(
name,
nrp,
pangkat,
jabatan,
satker,
polda,
npwp,
rekening,
bank,
));
});
}
}
DetailpersonilEvent
part of 'detailpersonil_bloc.dart';
#immutable
abstract class DetailpersonilEvent extends Equatable {}
class Detail extends DetailpersonilEvent {
#override
List<Object> get props => [];
}
DetailpersonilState
part of 'detailpersonil_bloc.dart';
#immutable
abstract class DetailpersonilState extends Equatable {
final String nama;
final String nrp;
final String pangkat;
final String jabatan;
final String satker;
final String polda;
final String npwp;
final String rekening;
final String bank;
const DetailpersonilState(
{this.nama,
this.nrp,
this.pangkat,
this.jabatan,
this.satker,
this.polda,
this.npwp,
this.rekening,
this.bank});
}
class DetailpersonilInitial extends DetailpersonilState {
const DetailpersonilInitial()
: super(
nama: 'Nama',
nrp: 'NRP',
pangkat: 'Pangkat',
jabatan: 'Jabatan',
satker: 'Satker',
polda: 'Polda',
npwp: 'NPWP',
rekening: 'No Rekening',
bank: 'Nama Bank',
);
#override
List<Object> get props =>
[nama, nrp, pangkat, jabatan, satker, polda, npwp, rekening, bank];
}
class Loaded extends DetailpersonilState {
const Loaded(
String nama,
String nrp,
String pangkat,
String jabatan,
String satker,
String polda,
String npwp,
String rekening,
String bank,
) : super(
nama: nama,
nrp: nrp,
pangkat: pangkat,
jabatan: jabatan,
satker: satker,
polda: polda,
npwp: npwp,
rekening: rekening,
bank: bank);
#override
List<Object> get props =>
[nama, nrp, pangkat, jabatan, satker, polda, npwp, rekening, bank];
}
LoginPage
class LoginPage extends StatefulWidget {
const LoginPage({Key key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
double width = 0;
double height = 0;
TextEditingController nrpController = TextEditingController();
TextEditingController sandiController = TextEditingController();
final formKey = GlobalKey<FormState>();
DetailpersonilBloc detailPersonilBloc;
GajiBloc gajiBloc;
TunkinBloc tunkinBloc;
bool passwordVisible = false;
#override
void initState() {
super.initState();
checkToken();
}
void checkToken() async {
SharedPreferences pref = await SharedPreferences.getInstance();
if (pref.getString('token') != null) {
detailPersonilBloc = DetailpersonilBloc();
gajiBloc = GajiBloc();
tunkinBloc = TunkinBloc();
detailPersonilBloc.add(Detail());
gajiBloc.add(Gaji());
tunkinBloc.add(Tunkin());
Navigator.push(
context, MaterialPageRoute(builder: (context) => const MainPage()));
}
}
onLogin(DetailpersonilBloc detailPersonilBloc) async {
if (formKey.currentState.validate()) {
var token = await APIService.generateToken(
nrpController.text, sandiController.text);
if (token != null) {
SharedPreferences pref = await SharedPreferences.getInstance();
await pref.setString('token', token.token);
var detail = await APIService.getDetailPersonil(token.token);
await pref.setString('nama', detail.nMPEG);
await pref.setString('NRP', detail.nRP);
await pref.setString('pangkat', detail.nMGOL1);
await pref.setString('jabatan', detail.sEBUTJAB);
await pref.setString('satker', detail.nMSATKER);
await pref.setString('polda', detail.nMUAPPAW);
await pref.setString('NPWP', detail.nPWP);
await pref.setString('rekening', detail.rEKENING);
await pref.setString('bank', detail.nMBANK);
nrpController.clear();
sandiController.clear();
detailPersonilBloc.add(Detail());
Navigator.push(
context, MaterialPageRoute(builder: (context) => const MainPage()));
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Error'),
content: Text('Login Gagal'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('Tutup'),
),
],
);
},
);
}
}
}
#override
Widget build(BuildContext context) {
var detailPersonilBloc = BlocProvider.of<DetailpersonilBloc>(context);
width = MediaQuery.of(context).size.width;
height = MediaQuery.of(context).size.height;
return Scaffold(
body: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: const [
Opacity(
opacity: 0.5,
child: Image(
image: AssetImage('images/bg-map-min.png'),
),
),
],
),
SingleChildScrollView(
padding: EdgeInsets.only(top: 100),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 100,
width: width,
child: const Image(
image: AssetImage('images/login-logo.png'),
alignment: Alignment.center,
),
),
Container(
padding: const EdgeInsets.all(15),
child: const Text(
'GAJI DAN TUNKIN',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
),
Form(
key: formKey,
child: Column(
children: [
Container(
margin: const EdgeInsets.all(20 - 2.6),
child: Card(
elevation: 10,
child: Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.only(bottom: 20),
child: const Text(
'LOGIN',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
Container(
padding: const EdgeInsets.only(bottom: 25),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan NRP/NIP';
}
return null;
},
controller: nrpController,
decoration: InputDecoration(
labelText: 'NRP/NIP',
hintText: 'Masukkan NRP/NIP',
prefixIcon: Icon(Icons.person,
color: Colors.blue.shade700),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
TextFormField(
obscureText: !passwordVisible,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan Kata Sandi';
}
return null;
},
controller: sandiController,
decoration: InputDecoration(
labelText: 'Kata Sandi',
hintText: 'Masukkan Kata Sandi',
prefixIcon: Icon(Icons.lock,
color: Colors.blue.shade700),
suffixIcon: IconButton(
onPressed: () {
setState(() {
passwordVisible = !passwordVisible;
});
},
icon: Icon(
passwordVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.blue.shade700,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
)
],
),
),
),
),
ElevatedButton(
onPressed: () async {
await onLogin(detailPersonilBloc);
},
child: const Text('LOGIN'),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade700,
minimumSize: const Size(200, 40),
),
)
],
),
),
],
),
),
],
),
);
}
}
GajiPage
class GajiPage extends StatefulWidget {
const GajiPage({Key key}) : super(key: key);
#override
_GajiPageState createState() => _GajiPageState();
}
class _GajiPageState extends State<GajiPage> {
double width = 0;
double height = 0;
var currentYear = DateTime.now().year;
var currentMonth = DateTime.now().month;
DetailpersonilBloc detailPersonilBloc;
GajiBloc gajiBloc;
#override
void initState() {
setState(() {
detailPersonilBloc = DetailpersonilBloc();
detailPersonilBloc.add(Detail());
setMonth();
setYear();
gajiBloc = GajiBloc();
gajiBloc.add(Gaji());
});
super.initState();
}
#override
Widget build(BuildContext context) {
var detailPersonilBloc = BlocProvider.of<DetailpersonilBloc>(context);
width = MediaQuery.of(context).size.width;
height = MediaQuery.of(context).size.height;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Image(
image: const AssetImage('images/header-logo.png'),
width: width / 2,
),
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromARGB(255, 170, 177, 175),
Color.fromARGB(255, 197, 217, 212)
],
),
),
),
),
body: Stack(
children: [
BlocBuilder<GajiBloc, GajiState>(
builder: (context, state) {
return state is GajiLoaded
? ListView(
children: [
Container(
height: 100,
),
Card(
color: const Color.fromARGB(255, 74, 50, 152),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.all(10),
child: const Text(
'Gaji Bersih',
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
Container(
margin: const EdgeInsets.all(10),
child: Text(
NumberFormat.currency(
locale: 'en',
symbol: 'RP ',
decimalDigits: 0)
.format(state.bersih),
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 40,
color: Colors.white,
),
),
),
],
),
),
Card(
child: Column(
children: [
Container(
color: const Color.fromARGB(255, 238, 238, 238),
width: width,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Container(
margin: const EdgeInsets.fromLTRB(
10, 10, 0, 10),
width: (width / 2) - 25,
child: const Text(
'Detail Gaji',
textAlign: TextAlign.start,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
),
Container(
margin: const EdgeInsets.fromLTRB(
5, 10, 20, 10),
width: (width / 2) - 18,
child: Text(
'${state.bulan} - ${state.tahun}',
textAlign: TextAlign.end,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 20,
),
),
)
],
),
),
...
],
),
),
Container(
height: 50,
),
],
)
: Center(
child: Text(
'Tidak ada data. Data gaji bulan ${state.bulan} belum diproses'),
);
},
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(
child: BlocBuilder<DetailpersonilBloc, DetailpersonilState>(
builder: (context, state) {
return Card(
child: Row(
children: [
Container(
margin: const EdgeInsets.all(10),
child: const CircleAvatar(
backgroundImage: AssetImage('images/Profpic.PNG'),
radius: 30,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 250,
padding: const EdgeInsets.all(5),
child: Text(
state.nama,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
)),
Container(
padding: const EdgeInsets.all(5),
child: Text(
state.nrp,
style: const TextStyle(fontSize: 15),
)),
],
),
GestureDetector(
onTap: () {
detailPersonilBloc.add(Detail());
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) => detailsBottomSheet(),
);
},
child: const Text(
'DETAILS',
style: TextStyle(color: Colors.blue),
),
)
],
),
);
},
),
),
GestureDetector(
onTap: () {
showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, StateSetter setState) {
return filterBottomSheet();
},
);
},
);
},
child: Container(
height: 50,
width: width,
decoration: const BoxDecoration(
color: Color.fromARGB(255, 244, 244, 244),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: const EdgeInsets.only(right: 3),
child: const Icon(
Icons.tune,
color: Color.fromARGB(255, 45, 165, 217),
),
),
const Text(
'Filter',
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 20,
color: Color.fromARGB(255, 45, 165, 217),
),
),
],
),
),
)
],
)
],
),
);
}
}
Note 2: The "..." is a bunch of code not needed for reproduction.
The answer is surprisingly simple as I would learn from my internship. The reason the Bloc is not updating is because I was not using the context of the application. So when I generated a new Bloc inside my pages, it was "empty". So the solution is to use context.read().add(BlocEvent()) or create a new bloc with BlocProvider.of(context) then add the event. Basically the bloc has to be provided with the original context of the application.