API Key not working in Flutter Weather API App (Android) - json

I'm learning Flutter and trying to build an Android Application. Basically a weather app where it fetches the API Key from a site. I keep getting the error " The argument type 'String' can't be assigned to the parameter type 'Uri'. ". What does this even mean and how do I get this to work?
main.dart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() => runApp(
MaterialApp(
title: "Weather App",
home: Home(),
)
);
class Home extends StatefulWidget {
#override
State<StatefulWidget> createState(){
return _HomeState();
}
}
class _HomeState extends State<Home> {
var temp;
var description;
var currently;
var humidity;
var windSpeed;
Future getWeather () async {
http.Response response = await http.get("http://api.weatherapi.com/v1/current.json?key=e5bd00e528e346ff8a840254213009&q=Chatham Ontario&aqi=no");
var results = jsonDecode(response.body);
setState((){
this.temp = results['current']['temp_c'];
this.description = results['current'][0]['last_updated'];
this.currently = results['current'][0]['condition']['text'];
this.humidity = results['current']['humidity'];
this.windSpeed = results['current']['wind_kph'];
});
}
#override
void initState() {
super.initState();
this.getWeather();
}
#override
Widget build (BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 3,
width: MediaQuery.of(context).size.width,
color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding:EdgeInsets.only(bottom: 10.0),
child: Text(
"Currently in Chatham-Kent",
style: TextStyle(
color: Colors.white,
fontSize: 14.0,
fontWeight: FontWeight.w600
),
),
),
Text(
temp != null ? temp.toString() + "\u00B0" : "Loading",
style: TextStyle(
color: Colors.white,
fontSize: 40.0,
fontWeight: FontWeight.w600
),
),
Padding(
padding:EdgeInsets.only(top: 10.0),
child: Text(
currently != null ? currently.toString() : "Loading",
style: TextStyle(
color: Colors.white,
fontSize: 14.0,
fontWeight: FontWeight.w600
),
),
),
],
),
),
Expanded(
child: Padding(
padding: EdgeInsets.all(20.0),
child: ListView(
children: <Widget>[
ListTile(
leading: FaIcon(FontAwesomeIcons.thermometerHalf),
title: Text("Temperature"),
trailing: Text(temp != null ? temp.toString() + "\u00B0" : "Loading"),
),
ListTile(
leading: FaIcon(FontAwesomeIcons.cloud),
title: Text("Weather"),
trailing: Text(description != null ? description.toString() : "Loading"),
),
ListTile(
leading: FaIcon(FontAwesomeIcons.sun),
title: Text("Humidity"),
trailing: Text(humidity != null ? humidity.toString() : "Loading"),
),
ListTile(
leading: FaIcon(FontAwesomeIcons.wind),
title: Text("Wind Speed"),
trailing: Text(windSpeed != null ? windSpeed.toString() : "Loading"),
)
],
)
)
)
],
),
);
}
}
pubspec.yaml
version: 1.0.0+1
environment:
sdk: '>=2.10.0 <3.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
font_awesome_flutter: ^8.0.0
http: ^0.13.3
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^1.0.0
flutter:
uses-material-design: true

Well, Your error clearly saying The argument type 'String' can't be assigned to the parameter type 'Uri' so, you have to convert url string to Uri.
LIKE THIS:
var uri = Uri.parse("http://api.weatherapi.com/v1/current.json?key=e5bd00e528e346ff8a840254213009&q=Chatham Ontario&aqi=no");
http.Response response = await http.get(uri);

Change this line of code
http.Response response = await http.get("http://api.weatherapi.com/v1/current.json?key=e5bd00e528e346ff8a840254213009&q=Chatham Ontario&aqi=no");
to
http.Response response = await http.get(Uri.parse("http://api.weatherapi.com/v1/current.json?key=e5bd00e528e346ff8a840254213009&q=Chatham Ontario&aqi=no"));

Based on HTTP package docs here.
As of 0.13.0-nullsafety.0 version All APIs which previously allowed a String or Uri to be passed now require a Uri.
so what happening here is that you need to parse(convert) your string to uri first before the call.
So your weather function will be like this:
Future getWeather () async {
http.Response response = await http.get(Uri.parse("http://api.weatherapi.com/v1/current.json?key=e5bd00e528e346ff8a840254213009&q=Chatham Ontario&aqi=no"));
var results = jsonDecode(response.body);
setState((){
this.temp = results['current']['temp_c'];
this.description = results['current'][0]['last_updated'];
this.currently = results['current'][0]['condition']['text'];
this.humidity = results['current']['humidity'];
this.windSpeed = results['current']['wind_kph'];
});
}

Related

How to generate a List to the second screen in flutter from a JSON?

I am trying to create a list from the value inside a JSON. I can get the length but not for the data. My main goal is to create a list of items based on their popularity.
child: Row(
children: [
...List.generate(
"items"[0].length,
(index) {
if (["items"][index].isPopular) { // here I want to generate a list for the value isPopular
return BreakfastCard(breakfast: ('items'[0] as Map<String, dynamic>[index]); // Here I want to call the function from other screen
}
And when I tried to change the code to this
"items"[0].length,
(index) {
if (["items"][index][isPopular]) { // the error here is *Conditions must have a static type of 'bool'.*
return BreakfastCard(breakfast: ['items'][0][index]); // the error here is *The argument type 'String' can't be assigned to the parameter type 'Breakfast'.*
The JSON data is like this
{
"items":[{
"id": 1,
"rating": "0.0",
"images": [
"assets/images/cilantro.png"
],
"title": "Cilantro and Kale Pesto Toast with a Fried Egg",
"time": 15,
"description": "Sliced bread is the perfect blank canvas, ready to be loaded up with virtuous ingredients.",
" rating": "4.8",
"isFavorite": false,
"isPopular": true,
}]
}
Here is my code for the card. In this part, there were no error and it show what I want.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fema/models/Breakfast.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../constants.dart';
import '../size_config.dart';
class BreakfastCard extends StatefulWidget {
BreakfastCard({
Key? key,
this.width = 140,
this.aspectRetio = 1.02,
required this.breakfast,
}) : super(key: key);
final double width, aspectRetio;
Breakfast breakfast;
#override
_BreakfastCardState createState() => _BreakfastCardState();
}
class _BreakfastCardState extends State<BreakfastCard> {
#override
Widget build(BuildContext context) {
Future<String> _loadloadBreakfastAsset() async {
return await rootBundle.loadString('assets/breakfast.json');
}
Future<BreakfastCard> loadBreakfast() async {
String jsonAddress = await _loadloadBreakfastAsset();
final jsonResponse = json.decode(jsonAddress);
// This now updates the breakfast property in the main class.
widget.breakfast = Breakfast.fromJson(jsonResponse);
// This return value is thrown away, but this line is necessary to
// resolve the Future call that FutureBuilder is waiting on.
return Future<BreakfastCard>.value();
}
SizeConfig().init(context);
return FutureBuilder(
future: loadBreakfast(),
builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
return Padding(
padding: EdgeInsets.only(left: getProportionateScreenWidth(20)),
child: SizedBox(
width: getProportionateScreenWidth(140),
child: GestureDetector(
onTap: (){},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 1.02,
child: Container(
padding: EdgeInsets.all(getProportionateScreenWidth(20)),
decoration: BoxDecoration(
color: kSecondaryColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(15),
),
child: Hero(
tag: widget.breakfast.id.toString(),
child: Image.asset(widget.breakfast.images[0]),
),
),
),
const SizedBox(height: 10),
Text(
widget.breakfast.title,
style: const TextStyle(color: Colors.black),
maxLines: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${widget.breakfast.calories} cal |",
style: TextStyle(
fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
Text(
"${widget.breakfast.time} min",
style: TextStyle(
fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.w600,
color: kPrimaryColor,
),
),
InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () { widget.breakfast.isFavorite = !widget.breakfast.isFavorite;},
child: Container(
padding: EdgeInsets.all(getProportionateScreenWidth(8)),
height: getProportionateScreenWidth(28),
width: getProportionateScreenWidth(28),
child: SvgPicture.asset(
"assets/icons/Heart Icon_2.svg",
color: widget.breakfast.isFavorite
? const Color(0xFFFF4848)
: const Color(0xFFDBDEE4),
),
),
),
],
)
],
),
),
),
);
}
);
}
}
And my problem is in here. Where the list will be generated. I am new to flutter and I have difficulties to solve the problem. In here I can correctly create a function to fetch the data from the BreakfastCard.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fema/components/breakfast_card.dart';
import 'package:fema/models/Breakfast.dart';
import 'package:flutter/services.dart';
import '../../../size_config.dart';
import 'section_title.dart';
class Breakfast extends StatelessWidget {
const Breakfast({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
Future<String> _loadloadBreakfastAsset() async {
return await rootBundle.loadString('assets/breakfast.json');
}
Future<Breakfast> loadBreakfast() async {
String jsonAddress = await _loadloadBreakfastAsset();
Map<String,dynamic> map = json.decode(jsonAddress);
List<dynamic> items = map["items"];
// This return value is thrown away, but this line is necessary to
// resolve the Future call that FutureBuilder is waiting on.
return Future<Breakfast>.value();
}
return FutureBuilder(
future: loadBreakfast(),
builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
return Column(
children: [
Padding(
padding:
EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)),
child: SectionTitle(title: "BREAKFAST", press: () {}),
),
SizedBox(height: getProportionateScreenWidth(20)),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
...List.generate(
items[0].length,
(index) {
if (items[index].isPopular) {
return BreakfastCard(breakfast: );
}
return const SizedBox
.shrink(); // here by default width and height is 0
},
),
SizedBox(width: getProportionateScreenWidth(20)),
],
),
)
],
);
});
}
}
You need to put "items" into a Map first. You are trying to use the String object "items" to populate your list. You want the data from the json to populate it.
Get the data into a usable object first.
Map<String, dynamic> map = jsonDecode(data);
List<dynamic> items = map["items"];
Then you can populate your list from that data.
child: Row(
children: [
...List.generate(
items.length,
(index) {
if (items[index].isPopular) {
return BreakfastCard(breakfast: (items[0]));
}
Your errors are from trying to use json data improperly as the conditional for an if statement.
The other error is because you are trying to send a String as an argument for a Breakfast object when it needs something else (I don't know what that is. You didn't post what a BreakfastCard class looks like at the time I wrote this.)
Dart and Flutter documentation is very good. Try this out https://flutter.dev/docs/development/data-and-backend/json

How to call Future Function to another class in flutter?

I am new in flutter. I created Drawer and loaded its header data from server by creating a future function. I want to recall this future function again from another class, so how can i do that.
I also tried to call by creating its class object like -
Drawersetting object = new Drawersetting();
then - > object.function_name
But that function is not visible.
How to do that? Following whole class - >
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mera_interest_flutter/Activity/BottomNavBar.dart';
import 'package:mera_interest_flutter/Activity/Login.dart';
import 'package:mera_interest_flutter/Custom/CustomClass.dart';
import 'package:mera_interest_flutter/Fragments/AppHistoryTabScreen.dart';
import 'package:mera_interest_flutter/Fragments/NotificationFragment.dart';
import 'package:mera_interest_flutter/Fragments/PartnersScreen.dart';
import 'package:mera_interest_flutter/Network/BaseURLHeaders.dart';
import 'package:mera_interest_flutter/model/UserInfoDataModel.dart';
import 'package:mera_interest_flutter/model/UserInfoModel.dart';
import 'package:mera_interest_flutter/routes/Routes.dart';
import '../Fragments/DiscoverScreen.dart';
import 'package:flutter_session/flutter_session.dart';
import 'package:mera_interest_flutter/Activity/UserProfileScreen.dart';
import 'package:mera_interest_flutter/Fragments/AddManualFragment.dart';
import 'package:mera_interest_flutter/Fragments/ContactUsScreen.dart';
import 'package:mera_interest_flutter/Fragments/FAQFragment.dart';
import 'package:mera_interest_flutter/Fragments/MessageFragment.dart';
import '../Fragments/HomeFragment.dart';
import '../Fragments/ZeroBalancePortFolioScreen.dart';
import '../Fragments/SupportFragment.dart';
import 'package:flutter_session/flutter_session.dart';
import 'package:http/http.dart' as http;
//for setting title name of side bar items
class DrawerItem {
String title;
IconData icon;
DrawerItem(this.title, this.icon);
}
//for setting title name of bottom bar items
// class widgetBottomItems{
// String title;
// IconData icon;
// widgetBottomItems(this.title, this.icon);
// }
class DrawerSetting extends StatefulWidget {
final drawerItems = [
new DrawerItem("Portfolio", Icons.add),
new DrawerItem("Zero Balance Portfolio", Icons.alarm),
new DrawerItem("Message", Icons.message),
new DrawerItem("My Info & Setting", Icons.settings),
new DrawerItem("Support", Icons.help),
new DrawerItem("FAQ", Icons.book_outlined),
new DrawerItem("Contact Us", Icons.contact_phone_outlined),
new DrawerItem("Logout", Icons.logout)
];
#override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<DrawerSetting> {
String _title;
var session = FlutterSession();
#override
void initState() {
// TODO: implement initState
super.initState();
getUserData();
_title ="Discover";
}
void didUpdateWidget(covariant DrawerSetting oldWidget) {
// TODO: implement didUpdateWidget
super.didUpdateWidget(oldWidget);
setState(() {
getUserData();
getNewProfile();
});
}
bool is_new_profile = false;
void getNewProfile()async{
is_new_profile = await session.get("is_new_profile");
print("sessionvalue = " + is_new_profile.toString());
if(is_new_profile == true){
setState(() {
getUserData();
});
}
}
final Color myColor = Color(0xFF15A2EB);
final Color myColorLightGray = Color(0xFF989E9E);
final Color text_Semi_Black_Color = Color(0xFF414B51);
final Color text_gray_color = Color(0xFF70787C);
UserInfoDataModel _userInfoDataModel;
String url = BaseURLHeaders().getBaseURl() + "";
Map headers = BaseURLHeaders().getHeader();
//bottom navigation
int _selectedIndex = 0;
var _screens = [
DiscoverScreen(),
HomeFragment(),
PartnersScreen(),
// HistoryScreen(),
AppHistoryTabScreen(),
NotificationFragment(),
];
static const TextStyle optionStyle = TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.red,
fontFamily: "verdana_regular",
);
//for bottom items
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
switch(index) {
case 0: { _title = 'Discover'; }
break;
case 1: { _title = 'Portfolio'; }
break;
case 2: { _title = 'Partners'; }
break;
case 3: { _title = 'History'; }
break;
}
});
}
int _selectedDrawerIndex = 0;
String currentProfilePic =
"https://service2home.in/wp-content/uploads/2021/01/rakesh.jpg";
_getDrawerItemWidget(int pos) {
switch (pos) {
case 0:
return new AddManualFdFragment();
break;
case 1:
return new ZeroBalancePortFolioScreen();
break;
case 2:
return MessageFragment();
break;
case 3:
return new UserProfileScreen("drawer");
break;
case 4:
return new SupportFragment();
break;
case 5:
return new FAQFragment();
break;
case 6:
return new ContactUsScreen();
break;
case 7:
SystemNavigator.pop();
//exit(0);
break;
}
}
//for drawer items
_onSelectItem(int index) {
setState(() => _selectedDrawerIndex = index);
Navigator.of(context).pop(); // close the drawer
}
#override
Widget build(BuildContext context) {
//set portrait by default
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
List<Widget> drawerOptions = [];
for (var i = 0; i < widget.drawerItems.length; i++) {
var d = widget.drawerItems[i];
drawerOptions.add(new ListTile(
leading: new Icon(
d.icon,
),
title: new Text(
d.title,
style: TextStyle(
fontSize: 16,
color: myColorLightGray,
fontFamily: "verdana_regular",
),
),
selected: i == _selectedDrawerIndex,
onTap: () => _onSelectItem(i),
));
}
//on backpress return to home screen , you can use it for drawer items
return WillPopScope(
onWillPop: () {
if (_selectedIndex != 0 || _selectedDrawerIndex != 0) {
setState(() {
_selectedIndex = 0;
});
// _getDrawerItemWidget(_selectedIndex);
} else {
Navigator.pop(context, true);
}
return;
},
child: Scaffold(
appBar: new AppBar(
title: Row(
children: [
Expanded(
child: new Text(
_title,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontFamily: "verdana_regular"),
),
),
Expanded(
flex: 0,
child: Container(
margin: EdgeInsets.only(left: 80),
// width: MediaQuery.of(context).size.width * 0.25,
child: IconButton(
alignment: Alignment.centerRight,
icon: Icon(Icons.notifications_none),
onPressed: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
NotificationFragment())),
}),
),
),
],
),
),
drawer: new Drawer(
child: SingleChildScrollView(
child: new Column(
children: [
//header
UserAccountsDrawerHeader(
currentAccountPicture: Container(
child: new GestureDetector(
child: new Container(
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: _userInfoDataModel != null
? new DecorationImage(
fit: BoxFit.cover,
image: new NetworkImage(
_userInfoDataModel
.profile_url)) :
new DecorationImage(
fit: BoxFit.cover,
image: new AssetImage("assets/images/user.png"),
),
)
),
onTap: () => {
Navigator.of(context).pop(),
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
UserProfileScreen("header")),
),
}),
),
accountName: _userInfoDataModel !=null ? new Text(
_userInfoDataModel.first_name + " " + _userInfoDataModel.last_name,
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontFamily: "verdana_regular",
),
) : null,
accountEmail: _userInfoDataModel !=null ? new Text(
_userInfoDataModel.email,
style: TextStyle(
fontSize: 15,
color: Colors.white,
fontFamily: "verdana_regular",
),
) : null,
),
Column(children: [
ListTile(
leading: Icon(Icons.add),
title: Text(
'Add Manual FD',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
// Navigator.pushReplacementNamed(context, Routes.addFd);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddManualFdFragment()));
}),
ListTile(
leading: Icon(Icons.alarm),
title: Text(
'Zero Balance Portfolio',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ZeroBalancePortFolioScreen()));
}),
ListTile(
leading: Icon(Icons.message),
title: Text(
'Message',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MessageFragment()));
}),
ListTile(
leading: Icon(Icons.settings),
title: Text(
'MY Info & Setting',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
UserProfileScreen("header")));
}),
ListTile(
leading: Icon(Icons.help),
title: Text(
'Support',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SupportFragment()));
}),
ListTile(
leading: Icon(Icons.bookmarks_outlined),
title: Text(
'FAQ',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FAQFragment()));
}),
ListTile(
leading: Icon(Icons.contact_phone_outlined),
title: Text(
'Contact Us',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
Navigator.of(context).pop();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ContactUsScreen()));
}),
ListTile(
leading: Icon(Icons.logout),
title: Text(
'Logout',
style: TextStyle(
color: myColorLightGray,
fontSize: 15,
fontFamily: "verdana_regular",
),
),
onTap: () {
goToLogin();
}),
])
],
),
),
),
body: _screens[_selectedIndex],
/*_getDrawerItemWidget(_selectedDrawerIndex),*/
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
backgroundColor: myColor,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Discover',
),
BottomNavigationBarItem(
icon: ImageIcon(
AssetImage("assets/images/briefcase.png"),
// color: Colors.grey,
),
label: 'Portfolio',
),
BottomNavigationBarItem(
icon: ImageIcon(
AssetImage("assets/images/partner.png"),
// color: Colors.grey,
),
label: 'Partners',
),
BottomNavigationBarItem(
icon: Icon(Icons.history),
label: 'History',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.white,
onTap: _onItemTapped,
),
// bottomNavigationBar: BottomNavigationBar(),
),
);
}
//go to news detail page
void goToProfile_Screen(BuildContext ctx) {
Navigator.of(ctx).push(
MaterialPageRoute(
builder: (_) {
return UserProfileScreen("drawer");
},
),
);
}
//logout
Future<void> goToLogin() async {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (BuildContext context) => Login()));
await FlutterSession().set("isLogin", false);
await FlutterSession().set("user_id", "");
await FlutterSession().set("user_name", "");
await FlutterSession().set("email", "");
await FlutterSession().set("phone", "");
await FlutterSession().set("account_status", "");
await FlutterSession().set("isNewData", false);
}
//api get user info
Future<UserInfoModel> getUserData() async {
String user_id = "1";
var mapData = new Map<String, dynamic>();
mapData['user_id'] = user_id;
// mapData['first_name'] = firstName;
var response = await http.post(
url,
headers: headers,
body: mapData,
);
if (response.statusCode == 200) {
var res = json.decode(response.body);
UserInfoModel _userInfoModel = UserInfoModel.fromJson(res);
if (_userInfoModel.success == 1) {
var data = res["data"];
_userInfoDataModel = UserInfoDataModel.fromJson(data);
// Toast.show("User Data Fetched", context,
// duration: Toast.LENGTH_SHORT, gravity: Toast.TOP);
// CustomClass().makeToast("message", context);
setState(() {
print("responseBody: ${res}");
print("responseData: ${data}");
print("userInfoSuccess: ${_userInfoModel.success}");
print("dataVaalue: ${data["email"]}");
print("urlBelow: ${url}");
print("headersBelow: ${headers}");
});
}
}
}
}
A solution to your problem could be a static function inside a Drawer class. You could use this function in another file without initializing a new instance of a Drawer class by calling Drawer.function(). This function though can access only static variables of the parent class.
Also check this explanation: Class variables and methods - dart.dev
But:
Consider using top-level functions, instead of static methods, for common or widely used utilities and functionality.
You will need to create a function inside the calling class to call the Future function of another class. See the example below:
class ClassName {
Future<void> functionName {
something
}
}
class CallingClassName {
Final ClassName objName = ClassName();
void callingFunciton {
objName.functionName();
}
}
in main.dart write the future method globally (outside any widget or class):
Future<Database> initializeDatabase() async {
var databasesPath = await getDatabasesPath();
var path = join(databasesPath, "tafheemul_quran.db");
// Check if the database exists
var exists = await databaseExists(path);
if (!exists) {
// Should happen only the first time you launch your application
print("Creating new copy from asset");
// Make sure the parent directory exists
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "tafheemul_quran.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Write and flush the bytes written
await File(path).writeAsBytes(bytes, flush: true);
} else {
print("Opening existing database");
}
// open the database
var bomDataTable = await openDatabase(path, readOnly: true);
return bomDataTable;
}
then in Another dart, import the main.dart :
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'main.dart';
then in that dart in any class, call the function :
class TokenExplActivity_Main extends State<TokenExplPassDataClass> {
//const TokenExplActivity_Main({Key? key}) : super(key: key);
String rowId = "";
String name = "";
String email = "";
String address = "";
Future<Database> get database async {
Database _database = await initializeDatabase();
if (_database == null) {
_database = await initializeDatabase();
}
return _database;
}
Actually the summary is, make the function globally and call the dart file in import first.

Access function from another class

Hello guys I'm trying to access function from another class becuse this function establish call and navigat to call page so for sure there will be setState function to update the UI but here is the problem whene the UI got updated from another class the app will go out of the widget tree so i have to use callBack function which is i dont know how pleass help
this is the perant class:
import 'dart:async';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:flutter_social_messenger/src/modules/auth/domain/entities/user.dart';
import 'package:flutter_social_messenger/src/modules/auth/export.dart';
import 'package:flutter_social_messenger/src/modules/notifications/domain/entities/call_msg.dart';
import 'package:flutter_social_messenger/src/modules/notifications/domain/entities/notification.dart';
import 'package:flutter_social_messenger/src/modules/notifications/domain/repository/repo.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../export.dart';
import './call.dart';
class IndexPage extends StatefulWidget {
String userId;
IndexPage(String this.userId);
#override
State<StatefulWidget> createState() => IndexState();
}
class IndexState extends State<IndexPage> {
/// create a channelController to retrieve text value
final _channelController = TextEditingController();
/// if channel textField is validated to have error
bool _validateError = false;
ClientRole _role = ClientRole.Broadcaster;
User currentUser = Modular.get<AuthController>().currentUser;
#override
void dispose() {
// dispose input controller
_channelController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
print("target : " + widget.userId.toString() ) ;
return Scaffold(
appBar: AppBar(
title: Text('Make a Call'),
),
body: Center(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20),
height: 400,
child: Column(
children: <Widget>[
/*
Row(
children: <Widget>[
Expanded(
child: TextField(
controller: _channelController..text = 'call-' + currentUser.id + "-" + widget.userId ,
decoration: InputDecoration(
errorText:
_validateError ? 'Channel name is mandatory' : null,
border: UnderlineInputBorder(
borderSide: BorderSide(width: 1),
),
hintText: 'call-' + widget.userId + "-" + currentUser.id ,
),
))
],
),
Column(
children: [
ListTile(
title: Text(ClientRole.Broadcaster.toString()),
leading: Radio(
value: ClientRole.Broadcaster,
groupValue: _role,
onChanged: (ClientRole value) {
setState(() {
_role = value;
});
},
),
),
ListTile(
title: Text(ClientRole.Audience.toString()),
leading: Radio(
value: ClientRole.Audience,
groupValue: _role,
onChanged: (ClientRole value) {
setState(() {
_role = value;
});
},
),
)
],
),
*/
Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child:
Row( children: <Widget>[
// Expanded(child: Text('call-' + currentUser.id + "-" + widget.userId ) ),
Expanded( child:
RawMaterialButton(
onPressed: () => onJoin(widget.userId,context,currentUser.id) ,
child: Icon(
Icons.call_end,
color: Colors.white,
size: 35.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: Colors.green,
padding: const EdgeInsets.all(15.0),
)
// RaisedButton(
// onPressed: onJoin,
// child: Text('Dial'),
// color: Colors.blueAccent,
// textColor: Colors.white,
// ),
) ], ),
)
],
),
),
),
);
}
DateTime get now => DateTime.now().toUtc();
Future<void> sendFollowNotification() {
String sendToId = widget.userId;
final followerId = currentUser.id;
print("trying to send call notification Id : " + "call-$followerId-$sendToId") ;
final not = CallNotification(
id: "call-$followerId-$sendToId",
sendTo: followerId,
senderId: sendToId,
senderName: currentUser.name,
time: now,
);
return repository.sendNotificaion(not);
}
Future<void> sendCallAlert() async {
String sendToId = widget.userId;
final followerId = currentUser.id;
print("trying to send call notification Id : " + "call-$followerId-$sendToId") ;
final not = CallNotification(
id: "call-$followerId-$sendToId",
sendTo: followerId,
senderId: sendToId,
senderName: currentUser.name,
time: now,
);
await Modular.get<NotificationsHelper>()
.registerNotification(followerId, true);
_callDocument("call-$followerId-$sendToId").setData(not.toJson());
// return _callCollection.document(currentUser.id).setData(not.toJson()) ;
// return repository.sendNotificaion(not);
}
final repository = Modular.get<NotificationReposity>();
final appStore = Modular.get<AppStore>();
final _firestore = Firestore.instance;
DocumentReference _callDocument(String callId) =>
_callCollection.document(callId);
CollectionReference get _callCollection => _firestore.collection("calls");
Future<void> onJoin(String userId,BuildContext context,final _followerId) async {
// print("qqqq") ;
String sendToId = userId;
final followerId = _followerId;
// print(userId+" i'm");
// print(_followerId+" his");
_channelController.text = "call-$followerId-$sendToId" ;
print("diallllll : " + _channelController.text ) ;
// /*
// update input validation
setState(() {
_channelController.text.isEmpty
? _validateError = true
: _validateError = false;
});
sendFollowNotification();
sendCallAlert();
if (_channelController.text.isNotEmpty) {
print('hiiiiissss');
// await for camera and mic permissions before pushing video page
await _handleCameraAndMic();
// push video page with given channel name
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CallPage(
channelName: _channelController.text,
role: _role,
),
),
);
}
// */
}
Future<void> _handleCameraAndMic() async {
// if (kIsWeb || !Platform.isAndroid) return true;
if (!await Permission.camera.isGranted && !await Permission.microphone.isGranted) {
var rr = ((await Permission.camera.request()).isGranted && (await Permission.microphone.request()).isGranted) ;
print("rr : " + rr.toString()) ;
}
}
// Future<bool> checkStoragePermission() async {
// if (kIsWeb || !Platform.isAndroid) return true;
// if (!await Permission.storage.isGranted) {
// return (await Permission.storage.request()).isGranted;
// }
// return true;
// }
}
and this is the child:
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:styled_widget/styled_widget.dart';
import '../../../../../chat/presentation/calling/index.dart';
import '../../../../../chat/presentation/calling/index.dart';
import '../../../../../chat/presentation/calling/index.dart';
import '../../../../../chat/presentation/calling/index.dart';
import '../../../../../chat/presentation/calling/index.dart';
import '../../../../export.dart';
import '../controller.dart';
import '../../widgets/profile_avatar.dart';
import 'package:flutter_social_messenger/src/modules/chat/presentation/calling/index.dart';
import 'package:flutter_social_messenger/src/modules/chat/presentation/calling/call.dart';
class OProfileHeader extends StatelessWidget implements PreferredSizeWidget {
final OtherUserProfileController controller;
OProfileHeader({Key key, #required this.controller}) : super(key: key);
User get user => controller.otherUser;
#override
Widget build(BuildContext context) {
final theme = Theme.of(context);
print("OProfileHeader : " + controller.isFollowing.toString() ) ;
return Stack(
children: <Widget>[
Positioned(
bottom: 200,
left: 0,
right: 0,
child: SizedBox(height: 200)
.decorated(gradient: AppTheme.primaryGradient),
),
Positioned(
bottom: 150,
left: 1,
right: 1,
child: Center(
child: Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5.0,
color: theme.scaffoldBackgroundColor,
child: Column(
children: <Widget>[
Observer(
builder: (_) => Text(
user.name ?? "",
style: GoogleFonts.basic().copyWith(fontSize: 28),
maxLines: 1,
),
).padding(top: 40),
Text(user.status ?? "").padding(bottom: 10),
],
),
).width(MediaQuery.of(context).size.width * 4 / 5),
),
),
Positioned(
left: 0,
right: 0,
bottom: 300,
child: AppBar(
backgroundColor: Colors.transparent,
iconTheme: IconThemeData(),
elevation: 0,
),
),
Positioned(
left: 0,
right: 0,
bottom: 210,
child: Center(
child: Material(
elevation: 5.0,
shape: CircleBorder(),
child: Observer(
builder: (_) => ProfileAvatarWidget(
photoUrl: user.photoUrl,
// isLoading: state is LoadingProfilePic,
),
),
),
),
),
Positioned(
right: 200,
left: 0,
bottom: 60,
child: Center(
child: Observer(
builder: (_) {
controller.currentUser.following;
return RaisedButton(
color: controller.isFollowing
? Colors.black
: theme.primaryColor,
onPressed: () => controller.followUser(user.id),
child: Text(
controller.isFollowing ? "UnFollow" : "Follow",
style: GoogleFonts.alike().copyWith(
fontSize: 16,
color: Colors.white,
),
textAlign: TextAlign.center,
).width(70),
);
},
),
),
),
Positioned(
right: 0,
left: 200,
bottom: 60,
child: Center(
child: Observer(
builder: (_) {
controller.currentUser.following;
return RaisedButton(
color: Colors.green,
onPressed: ()=> {
IndexState().onJoin(user.id,context,controller.currentUser.id),
print(controller.currentUser.id+" "+controller.currentUser.phoneNumber),
print(user.id+" "+user.phoneNumber)
},
child: Text(
"Call",
style: GoogleFonts.alike().copyWith(
fontSize: 16,
color: Colors.white,
),
textAlign: TextAlign.center,
).width(70),
);
},
),
),
),
],
).height(500).backgroundColor(theme.scaffoldBackgroundColor);
}
#override
Size get preferredSize => Size.fromHeight(400);
//----------------------------------------------------
// */
}
I dont understand exactly what you want, but if its how to call a method from a parent widget, if would be something like this:
class ParentWidget extends StatelessWidget{
#override
Widget build(BuildContext context) {
return ChildWidget(onAction: (resultValue){
//Do something with the value
});
}
}
class ChildWidget extends StatelessWidget{
final Function onAction;
ChildWidget({Key key, #required this.onAction}) : super(key: key);
#override
Widget build(BuildContext context) {
return Inkwell(
onTap: (){
onAction(someValue);
}
child: AnyOtherWidget
);
}
}

Exception has occurred. _TypeError (type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>')

I have problem with getruangfasiliti method. Is there any way to fix this error? I have been working this for weeks.
Tried this but it is not what i want. I want to get the every data of the object
Future<List> getruangfasiliti() async {
final response = await http.get(BaseUrl.lihatruangfasiliti(widget.barcode));
return jsonDecode(response.body);
}
So, below is my code and how i can fix the error. I do not know where my wrong is
modelAduan.dart
class Aduan {
final String aduan_id;
final String tarikhaduan;
final String ruang_id;
final String fasiliti_id;
final String maklumat;
final String gambaraduan;
final String status;
final String idpengguna;
final String namaruang;
final String namafasiliti;
Aduan({
this.aduan_id,
this.tarikhaduan,
this.ruang_id,
this.fasiliti_id,
this.maklumat,
this.gambaraduan,
this.status,
this.idpengguna,
this.namaruang,
this.namafasiliti
});
factory Aduan.fromJson(Map<String, dynamic> json) {
return Aduan(
aduan_id: json['aduan_id'],
tarikhaduan: json['tarikhaduan'],
ruang_id: json['ruang_id'],
fasiliti_id: json['fasiliti_id'],
maklumat: json['maklumat'],
gambaraduan: json['gambaraduan'],
status: json['status'],
idpengguna: json['idpengguna'],
namaruang: json['namaruang'],
namafasiliti: json['namafasiliti'],
);
}
}
aduan.dart
import 'dart:convert';
import 'package:eaduanfsktm/api.dart';
import 'package:eaduanfsktm/sejarahaduan.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:eaduanfsktm/model/modelRuangFasiliti.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'dart:math' as Math;
import 'package:image/image.dart' as Img;
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'package:async/async.dart';
import 'package:path/path.dart';
class BorangAduan extends StatefulWidget {
final String idpengguna, barcode;
BorangAduan(this.idpengguna, this.barcode);
#override
_BorangAduanState createState() => _BorangAduanState();
}
class _BorangAduanState extends State<BorangAduan> {
final _key = new GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
RuangFasiliti ruangfasiliti;
TextEditingController controllerruang_id;
TextEditingController controllerfasiliti_id;
TextEditingController controller_namaruang;
TextEditingController controller_namafasiliti;
TextEditingController controllermaklumat = new TextEditingController();
File _image;
Future<RuangFasiliti> getruangfasiliti() async {
final response = await http.get(BaseUrl.lihatruangfasiliti(widget.barcode));
if (response.statusCode == 200) {
setState(() {
ruangfasiliti = RuangFasiliti.fromJson(jsonDecode(response.body));
});
setState(() {
controllerruang_id =
new TextEditingController(text: "${ruangfasiliti.ruang_id}");
controllerfasiliti_id =
new TextEditingController(text: "${ruangfasiliti.fasiliti_id}");
controller_namaruang =
new TextEditingController(text: " ${ruangfasiliti.namaruang}");
controller_namafasiliti =
new TextEditingController(text: " ${ruangfasiliti.namafasiliti}");
});
return ruangfasiliti;
}
}
// #override
// void dispose() {
// controllerruang_id.dispose();
// controllerfasiliti_id.dispose();
// controller_namaruang.dispose();
// controllerruang_id.dispose();
// controller_namafasiliti.dispose();
// super.dispose();
// }
#override
void initState() {
getruangfasiliti();
super.initState();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("Borang Aduan"),
),
body: ListView(
padding: EdgeInsets.all(2.0),
children: <Widget>[
FutureBuilder<RuangFasiliti>(
future: getruangfasiliti(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return aduanbox();
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Center(child: CircularProgressIndicator());
},
),
SizedBox(height: 10.0),
],
),
),
);
}
Widget aduanbox() {
return Center(
child: Form(
key: _key,
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
child: new TextFormField(
controller: controllerfasiliti_id,
readOnly: true,
decoration: InputDecoration(
labelText: "KOD FASILITI",
),
),
),
flex: 2,
),
SizedBox(width: 10.0),
Expanded(
child: Container(
child: new TextFormField(
controller: controller_namafasiliti,
readOnly: true,
decoration: InputDecoration(
labelText: "NAMA FASILITI",
),
),
),
flex: 2,
),
],
),
new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
child: new TextFormField(
controller: controllerruang_id,
readOnly: true,
decoration: InputDecoration(
labelText: "KOD LOKASI",
),
),
),
flex: 2,
),
SizedBox(width: 10.0),
Expanded(
child: Container(
child: new TextFormField(
controller: controller_namaruang,
readOnly: true,
decoration: InputDecoration(
labelText: "LOKASI",
),
),
),
flex: 2,
),
],
),
TextFormField(
controller: controllermaklumat,
validator: (value) {
if (value.isEmpty) {
return 'Masukkan Maklumat Kerosakan';
}
return null;
},
decoration: InputDecoration(
labelText: "MAKLUMAT",
hintText: "Masukkan maklumat kerosakan"),
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
RaisedButton(
child: Icon(Icons.image),
onPressed: getImageGallery,
),
SizedBox(width: 5.0),
RaisedButton(
child: Icon(Icons.camera_alt),
onPressed: getImageCamera,
),
],
),
SizedBox(height: 10.0),
Container(
alignment: Alignment.centerLeft,
child: _image == null
? new Text("Tiada imej !")
: new Image.file(_image),
),
SizedBox(height: 10.0),
Container(
height: 45.0,
child: GestureDetector(
onTap: () {
if (_key.currentState.validate()) {
tambahaduan(_image);
}
},
child: Material(
borderRadius: BorderRadius.circular(10.0),
color: Colors.blueAccent,
elevation: 7.0,
child: Center(
child: Text(
'HANTAR',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat'),
),
),
),
),
),
],
),
),
),
),
);
}
Future getImageGallery() async {
var imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
final tempDir = await getTemporaryDirectory();
final path = tempDir.path;
int rand = new Math.Random().nextInt(100000);
Img.Image image = Img.decodeImage(imageFile.readAsBytesSync());
Img.Image smallerImg = Img.copyResize(image, width: 500);
var compressImg = new File("$path/image_$rand.jpg")
..writeAsBytesSync(Img.encodeJpg(smallerImg, quality: 85));
setState(() {
_image = compressImg;
});
}
Future getImageCamera() async {
var imageFile = await ImagePicker.pickImage(source: ImageSource.camera);
final tempDir = await getTemporaryDirectory();
final path = tempDir.path;
int rand = new Math.Random().nextInt(100000);
Img.Image image = Img.decodeImage(imageFile.readAsBytesSync());
Img.Image smallerImg = Img.copyResize(image, width: 500);
var compressImg = new File("$path/image_$rand.jpg")
..writeAsBytesSync(Img.encodeJpg(smallerImg, quality: 85));
setState(() {
_image = compressImg;
});
}
Future tambahaduan(File _image) async {
var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
var length = await _image.length();
var uri = Uri.parse((BaseUrl.tambahaduan()));
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile("aduanimages", stream, length,
filename: basename(_image.path));
request.fields['fasiliti_id'] = controllerfasiliti_id.text;
request.fields['ruang_id'] = controllerruang_id.text;
request.fields['maklumat'] = controllermaklumat.text;
request.fields['idpengguna'] = widget.idpengguna;
request.files.add(multipartFile);
var response = await request.send();
if (response.statusCode == 200) {
print("Image Uploaded");
setState(
() {
Fluttertoast.showToast(
msg: "Aduan Berjaya",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
backgroundColor: Colors.black,
textColor: Colors.white,
fontSize: 18.0,
);
Navigator.of(this.context).push(CupertinoPageRoute(
builder: (BuildContext context) => SejarahAduan()));
},
);
} else {
print("Upload Failed");
}
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
}
this is my error
List<RuangFasiliti> ruangfasiliti;
Future<RuangFasiliti> getruangfasiliti() async {
final response = await http.get(BaseUrl.lihatruangfasiliti(widget.barcode));
if (response.statusCode == 200) {
var body = jsonDecode(response.body);
setState(() {
if(body is List) //check if it's a List
ruangfasiliti = List<RuangFasiliti>.from(body.map(map) => RuangFasiliti.fromJson(map));
if(body is Map) //check if it's a Map
ruangfasiliti = [RuangFasiliti.fromJson(body)];
controllerruang_id =
new TextEditingController(text: "${ruangfasiliti.ruang_id}");
controllerfasiliti_id =
new TextEditingController(text: "${ruangfasiliti.fasiliti_id}");
controller_namaruang =
new TextEditingController(text: " ${ruangfasiliti.namaruang}");
controller_namafasiliti =
new TextEditingController(text: " ${ruangfasiliti.namafasiliti}");
});
return ruangfasiliti;
}
}
This code allows you to save a List ruangfasiliti, checks if the decoded json is a map or a list and saves it accordingly, but as the other comments said, you should provide and check the form of your JSON file to avoid this types of problems. If your JSON always returns a list it will be easy to just create a List body variable without checking the type of object

How to fix " [ERROR: The method '[]' was called on null. E/flutter (18386): Receiver: null"flutter

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'Models/UserData.dart';
class LoginScreen extends StatefulWidget {
static const String id = '/login_screen';
#override
State<StatefulWidget> createState() {
return _LoginPageState();
}
}
class _LoginPageState extends State<LoginScreen> {
static var url = "url";
static BaseOptions options = BaseOptions(
baseUrl: url,
responseType: ResponseType.plain,
connectTimeout: 30000,
receiveTimeout: 30000,
validateStatus: (code) {
if (code >= 200) {
return true;
}
});
static Dio dio = Dio(options);
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
UserData userData;
#override
void initState() {
SystemChrome.setEnabledSystemUIOverlays([]);
userData = UserData();
super.initState();
}
Future<Map<String, dynamic>> _loginUser(String email, String password, String version) async {
try {
Options options = Options(
contentType: ContentType.parse('application/json'),
);
final Response response = await dio.post<Map<String, dynamic>>(url + '/users/login',
data: {'login': _emailController, 'pwd': _passwordController, 'version' :'2.0'}, options: options);
print(url + '/users/login');
if (response.statusCode == 200 || response.statusCode == 201) {
return json.decode(response.data);
} else if (response.statusCode == 401) {
throw Exception("Incorrect Email/Password");
} else
throw Exception('Authentication Error');
} on DioError catch (exception) {
if (exception == null ||
exception.toString().contains('SocketException')) {
throw Exception("Network Error");
} else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
exception.type == DioErrorType.CONNECT_TIMEOUT) {
throw Exception(
"Could'nt connect, please ensure you have a stable network.");
} else {
return null;
}
}
}
#override
Widget build(BuildContext context) {
bool _isLoading = false;
String version = '2.0';
bool _obscureText = true;
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
width: MediaQuery
.of(context)
.size
.width,
height: MediaQuery
.of(context)
.size
.height / 2.5,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Colors.white, Colors.white],
),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(90),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Spacer(),
Align(
alignment: Alignment.center,
child: Image.asset('assets/logo.png'),
),
Spacer(),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(bottom: 32, right: 32),
child: Text(
'Customer App',
style: TextStyle(color: Colors.red, fontSize: 18),
),
),
),
],
),
),
Container(
color: Colors.white,
height: MediaQuery
.of(context)
.size
.height / 1,
width: MediaQuery
.of(context)
.size
.width,
padding: EdgeInsets.only(top: 20),
child: Column(
children: <Widget>[
Container(
width: MediaQuery
.of(context)
.size
.width / 1.2,
height: 45,
padding:
EdgeInsets.only(top: 2, left: 16, right: 16, bottom: 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.red, blurRadius: 5)
]),
child: TextField(
controller: _emailController,
decoration: InputDecoration(
errorText: _isLoading ? 'Value Can\'t Be Empty' : null,
border: InputBorder.none,
icon: Icon(
Icons.email,
color: Colors.red,
),
hintText: 'Email',
),
keyboardType: TextInputType.emailAddress,
),
),
const SizedBox(
width: 42.0,
height: 20.0,
),
Container(
width: MediaQuery
.of(context)
.size
.width / 1.2,
height: 45,
padding:
EdgeInsets.only(top: 2, left: 16, right: 16, bottom: 2),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.red, blurRadius: 8)
]),
child: TextField(
obscureText: _obscureText,
controller: _passwordController,
inputFormatters: [LengthLimitingTextInputFormatter(10)],
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(
Icons.lock_open,
color: Colors.red,
),
hintText: 'Password',
),
keyboardType: TextInputType.text,
),
),
Container(
height: 45,
margin: EdgeInsets.only(top: 22),
width: MediaQuery
.of(context)
.size
.width / 1.2,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.all(Radius.circular(50))),
child: Center(
child: InkWell(
onTap: () async {
FocusScope.of(context).requestFocus(new FocusNode());
setState(() => _isLoading = true,);
Navigator.of(context)
.pushReplacementNamed('/home_screen');
var res = await _loginUser(
_emailController.text, _passwordController.text,version);
final UserData users = UserData.fromJson(res);
List<Map> items = json.decode("response.body");
List<UserData> listOfDesig = items.map((json) => UserData.fromJson(json)).toList();
if (listOfDesig != null) {
Navigator.of(context)
.pushReplacementNamed('/home_screen');
} else {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text("Wrong email")));
}
},
child: Text(
'Login'.toUpperCase(),
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
),
),
),
],
),
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(top: 20, right: 0),
child: Text(
'Forgot Password ?',
style: TextStyle(color: Colors.grey),
),
),
),
],
),
),
);
}
}
class UserData {
String customerid;
String profileid;
String branch;
String bookername;
String emailid;
String mobileno;
int cutofftime;
String ppnames;
String paymenttype;
String usertype;
int ptopCutoffTime;
String designation;
String designationid;
UserData({
this.customerid,
this.profileid,
this.branch,
this.bookername,
this.emailid,
this.mobileno,
this.cutofftime,
this.ppnames,
this.paymenttype,
this.usertype,
this.ptopCutoffTime,
this.designation,
this.designationid,
});
factory UserData.fromJson(Map<String, dynamic> json) => UserData(
customerid: json["customerid"],
profileid: json["profileid"],
branch: json["branch"],
bookername: json["bookername"],
emailid: json["emailid"],
mobileno: json["mobileno"],
cutofftime: json["cutofftime"],
ppnames: json["ppnames"],
paymenttype: json["paymenttype"],
usertype: json["usertype"],
ptopCutoffTime: json["ptopCutoffTime"],
designation: json["designation"],
designationid: json["designationid"],
);
}
This is my flutter code and I'm new to flutter.
Error Message -
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception:
NoSuchMethodError: The method '[]' was called on null. E/flutter
(18386): Receiver: null E/flutter (18386): Tried calling:
E/flutter (18386): #0 Object.noSuchMethod
(dart:core-patch/object_patch.dart:50:5) E/flutter (18386): #1
new UserData.fromJson
(package:/Models/UserData.dart:33:21)
The way I see your code the Error is from this
#override
void initState() {
SystemChrome.setEnabledSystemUIOverlays([]);
userData = UserData(); //What cause the error.
super.initState();
}
Why? Because You haven't put value into your UserData class after getting it from the Server. Try to collect your data from the server if the authentication is valid. with UserData.fromJson(json.decode(response.body));
Am using http not Dio here, But try to convert it to Dio by your previous code.
Future<UserData> getUserData() async{
final SharedPreferences prefs = await SharedPreferences.getInstance();
String email = prefs.getString('Email');
String session = prefs.getString('session');
var map = new Map<String, String>();
map["email"] = email;
map["sesscode"] = session;
var response = await http.post(new API().userdata, body: map);
var convertDataToJson = json.decode(response.body);
UserData usdata = UserData .fromJson(convertDataToJson); //THis solve your error
return usdata ;
}
It seems that you send null when you call UserData.fromJson(Map<String, dynamic> json). Check if json != null before calling UserData.fromJson
In case if you are using google APIs you should not restrict the API keys. That was my mistake. Happy coding
This error happens, if you are using a class variable without initializing.
Check weather you have initialized all the variables before using it.