Related
I am trying to pass JSON data from Scryfall from my results.dart to display on my wishlist.dart after clicking the shopping bag button. I have no clue how to go about it. I mainly just want to display the name of the card, and the price. If i could get some help in the next hour, that'd be great! Here is the code:
RESULTS.DART:
import 'dart:async';
import 'package:demo_1/model/constant.dart';
import 'package:demo_1/viewscreen/wishlist_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:demo_1/model/scryfall_1.dart';
import 'package:demo_1/model/tokens.dart';
import 'package:flutter/material.dart';
class GetProjectScreen extends StatefulWidget {
static const routeName = '/GetProjectScreen';
const GetProjectScreen({required this.user, Key? key}) : super(key: key);
final User user;
#override
State<StatefulWidget> createState() {
return _GetProjectState();
}
}
class _GetProjectState extends State<GetProjectScreen> {
late _Controller con;
#override
void initState() {
super.initState();
con = _Controller(this);
}
void render(fn) => setState(fn);
bool checked1 = true;
#override
Widget build(BuildContext context) {
final searchCard = ModalRoute.of(context)!.settings.arguments as Future<Scryfall>;
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
leading: BackButton(
color: Colors.white,
onPressed: () {
curToken = '';
Navigator.of(context).pop();
},
),
title: const Text('Showing Results For...'),
),
// body: Center(child: buildFutureBuilder(searchCard)),
body: Center(
child: FutureBuilder<Scryfall>(
future: searchCard,
builder: (context, snapshot) {
if (snapshot.hasData) {
List<String> prices = [
'\$' + snapshot.data!.prices.usd.toString(),
];
prices.removeWhere((item) => item.contains('null'));
for (int index = 0; index < prices.length; index++) {
if (prices[index].contains('\$') && !checked1) {
prices.removeAt(index);
}
}
return ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
width: 1000,
height: 500,
color: Colors.white,
child: Center(
child: Image(
image: NetworkImage(snapshot.data!.imageUris.borderCrop!),
),
),
),
ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: prices.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
tileColor: Colors.white,
title: Text(prices[index]),
onTap: () {
launchURL(
(prices[index].contains('\$')
? snapshot.data!.purchaseUris.tcgplayer
: (prices[index].contains('\€')
? snapshot.data!.purchaseUris.cardmarket
: snapshot.data!.purchaseUris.cardhoarder)),
);
},
trailing: Wrap(spacing: 10, children: <Widget>[
new IconButton(
icon: Icon(Icons.shopping_bag_sharp),
onPressed: () {
con.goToWishlist();
},
),
]),
);
},
),
],
);
//return cardFutureBuilder();
} else if (snapshot.hasError) {
return const Text('Either card does not exist or search is too vague');
}
return const CircularProgressIndicator();
},
),
),
endDrawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text('Drawer Header'),
),
CheckboxListTile(
title: const Text("USD"),
value: checked1,
onChanged: (bool? value) {
setState(
() {
checked1 = value!;
},
);
},
),
),
],
),
),
),
);
}
void launchURL(String url) async {
if (!await launch(url)) throw 'Could not launch $url';
}
}
class _Controller {
_GetProjectState state;
_Controller(this.state) {
user = state.widget.user;
}
late User _user;
User get user => _user;
set user(User user) {
_user = user;
}
void goToWishlist() async {
await Navigator.pushNamed(
state.context,
WishlistScreen.routeName,
arguments: {
ArgKey.user: user,
},
);
state.render(() {});
}
}
WISHLIST.DART
import 'package:demo_1/model/constant.dart';
import 'package:demo_1/model/scryfall_1.dart';
import 'package:demo_1/viewscreen/confirmation_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'results.dart';
import 'home_screen.dart';
class WishlistScreen extends StatefulWidget {
static const routeName = '/WishlistScreen';
const WishlistScreen({required this.user, Key? key}) : super(key: key);
final User user;
#override
State<StatefulWidget> createState() {
return _WishlistState();
}
}
class _WishlistState extends State<WishlistScreen> {
late _Controller con;
late String profilePicture;
Future<Scryfall>? searchCard;
final TextEditingController _controller = TextEditingController();
#override
void initState() {
super.initState();
con = _Controller(this);
profilePicture = widget.user.photoURL ?? 'No profile picture';
}
void render(fn) => setState(fn);
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.cyan[400],
onPressed: () => con.searchDialog(),
child: const Icon(Icons.search),
),
appBar: AppBar(
title: const Text('Wish List'),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 18.0),
const CartItem(),
const CartItem(),
const CartItem(),
const SizedBox(height: 21.0),
MaterialButton(
onPressed: () {
setState(
() {
/*Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ConfirmationScreen(),
));*/
con.confirmationScreen();
},
);
},
color: Colors.cyan,
height: 30.0,
minWidth: double.infinity,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: const Text(
"CHECKOUT",
style: TextStyle(
color: Colors.white,
fontSize: 14.0,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 18.0),
],
)));
}
}
class CartItem extends StatelessWidget {
const CartItem({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
color: const Color.fromARGB(255, 209, 206, 206),
margin: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
children: <Widget>[
Container(
width: 80.0,
height: 80.0,
child: Center(
child: Container(
width: 60.0,
height: 60.0,
decoration: BoxDecoration(
image: const DecorationImage(
fit: BoxFit.scaleDown,
image: NetworkImage(
"https://c1.scryfall.com/file/scryfall-cards/large/front/b/e/be524227-8adc-4b01-808f-5ec4ab9dc09c.jpg?1568004322",
),
),
borderRadius: BorderRadius.circular(15.0),
)))),
const SizedBox(width: 12.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
width: 100.0,
child: const Text(
"Default Card Name",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(height: 8.0),
Row(
children: <Widget>[
Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 146, 143, 143),
borderRadius: BorderRadius.circular(4.0),
),
child: const Icon(
Icons.add,
color: Colors.white,
size: 15.0,
),
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
"1",
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
),
Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
color: const Color.fromARGB(255, 37, 114, 177),
borderRadius: BorderRadius.circular(4.0),
),
child: const Icon(
Icons.add,
color: Colors.white,
size: 15.0,
),
),
const Spacer(),
const Text(
"000.00",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
),
],
),
);
}
}
class _Controller {
_WishlistState state;
_Controller(this.state) {
user = state.widget.user;
}
late User _user;
User get user => _user;
set user(User user) {
_user = user;
}
void confirmationScreen() async {
await Navigator.pushNamed(
state.context,
ConfirmationScreen.routeName,
arguments: {
ArgKey.user: user,
},
);
state.render(() {});
}
Future? searchDialog() {
return showDialog(
context: state.context,
builder: (BuildContext context) => AlertDialog(
title: const Text('Search'),
content: Container(
height: 180,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('Search for a card:'),
TextField(
controller: state._controller,
decoration: const InputDecoration(hintText: 'Enter Title'),
),
OutlinedButton(
onPressed: () {
state.setState(
() {
state.searchCard =
scryfallGet(state._controller.text.replaceAll(' ', '+'));
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
GetProjectScreen(user: state.widget.user),
settings: RouteSettings(arguments: state.searchCard)));
},
);
},
child: const Text('Search'),
),
],
),
),
),
);
}
}
SCRYFALL_1.DART
/*
* parsed with Nicol Bolas
*/
class Scryfall {
Scryfall({
required this.object,
required this.id,
required this.oracleId,
required this.multiverseIds,
required this.mtgoId,
required this.mtgoFoilId,
required this.tcgplayerId,
required this.cardmarketId,
required this.arenaId,
required this.name,
required this.lang,
required this.releasedAt,
required this.uri,
required this.scryfallUri,
required this.layout,
required this.highresImage,
required this.imageStatus,
required this.imageUris,
required this.manaCost,
required this.cmc,
required this.typeLine,
required this.oracleText,
required this.power,
required this.toughness,
required this.colors,
required this.colorIdentity,
required this.keywords,
required this.producedMana,
required this.legalities,
required this.games,
required this.reserved,
required this.foil,
required this.nonfoil,
required this.finishes,
required this.oversized,
required this.promo,
required this.reprint,
required this.variation,
required this.setId,
required this.scryfallSet,
required this.setName,
required this.setType,
required this.setUri,
required this.setSearchUri,
required this.scryfallSetUri,
required this.rulingsUri,
required this.printsSearchUri,
required this.collectorNumber,
required this.digital,
required this.rarity,
required this.watermark,
required this.flavorText,
required this.cardBackId,
required this.artist,
required this.artistIds,
required this.illustrationId,
required this.borderColor,
required this.frame,
required this.securityStamp,
required this.fullArt,
required this.textless,
required this.booster,
required this.storySpotlight,
required this.edhrecRank,
required this.prices,
required this.relatedUris,
required this.purchaseUris,
});
String object;
String id;
String? oracleId;
List<num> multiverseIds;
num? mtgoId;
num? mtgoFoilId;
num? tcgplayerId;
num? cardmarketId;
num? arenaId;
String name;
String lang;
DateTime releasedAt;
String uri;
String scryfallUri;
String? layout;
bool highresImage;
String imageStatus;
ImageUris imageUris;
String? manaCost;
num? cmc;
String? typeLine;
String? oracleText;
String? power;
String? toughness;
List<String> colors;
List<String> colorIdentity;
List<String> keywords;
List<String> producedMana;
Legalities legalities;
List<String> games;
bool reserved;
bool foil;
bool nonfoil;
List<String> finishes;
bool oversized;
bool promo;
bool reprint;
bool variation;
String setId;
String? scryfallSet;
String setName;
String setType;
String setUri;
String setSearchUri;
String scryfallSetUri;
String rulingsUri;
String printsSearchUri;
String collectorNumber;
bool digital;
String rarity;
String? watermark;
String? flavorText;
String cardBackId;
String artist;
List<String> artistIds;
String? illustrationId;
String borderColor;
String frame;
String? securityStamp;
bool fullArt;
bool textless;
bool booster;
bool storySpotlight;
num? edhrecRank;
Prices prices;
RelatedUris relatedUris;
PurchaseUris purchaseUris;
factory Scryfall.fromJson(Map<String, dynamic> json) => Scryfall(
object: json["object"],
id: json["id"],
oracleId: json["oracle_id"],
multiverseIds: json["multiverse_ids"] != null
? List<int>.from(json["multiverse_ids"].map((x) => x))
: [],
arenaId: json["arena_id"],
mtgoId: json["mtgo_id"],
mtgoFoilId: json["mtgo_foil_id"],
tcgplayerId: json["tcgplayer_id"],
cardmarketId: json["cardmarket_id"],
name: json["name"],
lang: json["lang"],
releasedAt: DateTime.parse(json["released_at"]),
uri: json["uri"],
scryfallUri: json["scryfall_uri"],
layout: json["layout"],
highresImage: json["highres_image"],
imageStatus: json["image_status"],
imageUris: ImageUris.fromJson(json["image_uris"]),
manaCost: json["mana_cost"],
cmc: json["cmc"],
typeLine: json["type_line"],
oracleText: json["oracle_text"],
power: json["power"],
toughness: json["toughness"],
colors: json["colors"] != null
? List<String>.from(json["colors"].map((x) => x))
: [],
colorIdentity: List<String>.from(json["color_identity"].map((x) => x)),
keywords: List<String>.from(json["keywords"].map((x) => x)),
producedMana: json["produced_mana"] != null
? List<String>.from(json["produced_mana"].map((x) => x))
: [],
legalities: Legalities.fromJson(json["legalities"]),
games: List<String>.from(json["games"].map((x) => x)),
reserved: json["reserved"],
foil: json["foil"],
nonfoil: json["nonfoil"],
finishes: List<String>.from(json["finishes"].map((x) => x)),
oversized: json["oversized"],
promo: json["promo"],
reprint: json["reprint"],
variation: json["variation"],
setId: json["set_id"],
scryfallSet: json["set"],
setName: json["set_name"],
setType: json["set_type"],
setUri: json["set_uri"],
setSearchUri: json["set_search_uri"],
scryfallSetUri: json["scryfall_set_uri"],
rulingsUri: json["rulings_uri"],
printsSearchUri: json["prints_search_uri"],
collectorNumber: json["collector_number"],
digital: json["digital"],
rarity: json["rarity"],
watermark: json["watermark"],
flavorText: json["flavor_text"],
cardBackId: json["card_back_id"],
artist: json["artist"],
artistIds: List<String>.from(json["artist_ids"].map((x) => x)),
illustrationId: json["illustration_id"],
borderColor: json["border_color"],
frame: json["frame"],
securityStamp: json["security_stamp"],
fullArt: json["full_art"],
textless: json["textless"],
booster: json["booster"],
storySpotlight: json["story_spotlight"],
edhrecRank: json["edhrec_rank"],
prices: Prices.fromJson(json["prices"]),
relatedUris: json["related_uris"] != null
? RelatedUris.fromJson(json["related_uris"])
: RelatedUris(
gatherer: "",
tcgplayerInfiniteArticles: "",
tcgplayerInfiniteDecks: "",
edhrec: "",
mtgtop8: ""),
purchaseUris: json["purchase_uris"] != null
? PurchaseUris.fromJson(json["purchase_uris"])
: PurchaseUris(tcgplayer: "", cardmarket: "", cardhoarder: ""),
);
Map<String, dynamic> toJson() => {
"object": object,
"id": id,
"oracle_id": oracleId,
"multiverse_ids": List<dynamic>.from(multiverseIds.map((x) => x)),
"mtgo_id": mtgoId,
"mtgo_foil_id": mtgoFoilId,
"tcgplayer_id": tcgplayerId,
"cardmarket_id": cardmarketId,
"name": name,
"lang": lang,
"released_at":
"${releasedAt.year.toString().padLeft(4, '0')}-${releasedAt.month.toString().padLeft(2, '0')}-${releasedAt.day.toString().padLeft(2, '0')}",
"uri": uri,
"scryfall_uri": scryfallUri,
"layout": layout,
"highres_image": highresImage,
"image_status": imageStatus,
"image_uris": imageUris.toJson(),
"mana_cost": manaCost,
"cmc": cmc,
"type_line": typeLine,
"oracle_text": oracleText,
"power": power,
"toughness": toughness,
"colors": List<dynamic>.from(colors.map((x) => x)),
"color_identity": List<dynamic>.from(colorIdentity.map((x) => x)),
"keywords": List<dynamic>.from(keywords.map((x) => x)),
"legalities": legalities.toJson(),
"games": List<dynamic>.from(games.map((x) => x)),
"reserved": reserved,
"foil": foil,
"nonfoil": nonfoil,
"finishes": List<dynamic>.from(finishes.map((x) => x)),
"oversized": oversized,
"promo": promo,
"reprint": reprint,
"variation": variation,
"set_id": setId,
"set": scryfallSet,
"set_name": setName,
"set_type": setType,
"set_uri": setUri,
"set_search_uri": setSearchUri,
"scryfall_set_uri": scryfallSetUri,
"rulings_uri": rulingsUri,
"prints_search_uri": printsSearchUri,
"collector_number": collectorNumber,
"digital": digital,
"rarity": rarity,
"watermark": watermark,
"flavor_text": flavorText,
"card_back_id": cardBackId,
"artist": artist,
"artist_ids": List<dynamic>.from(artistIds.map((x) => x)),
"illustration_id": illustrationId,
"border_color": borderColor,
"frame": frame,
"security_stamp": securityStamp,
"full_art": fullArt,
"textless": textless,
"booster": booster,
"story_spotlight": storySpotlight,
"edhrec_rank": edhrecRank,
"prices": prices.toJson(),
"related_uris": relatedUris.toJson(),
"purchase_uris": purchaseUris.toJson(),
};
}
class ImageUris {
ImageUris({
required this.small,
required this.normal,
required this.large,
required this.png,
required this.artCrop,
required this.borderCrop,
});
String? small;
String? normal;
String? large;
String? png;
String? artCrop;
String? borderCrop;
factory ImageUris.fromJson(Map<String, dynamic> json) => ImageUris(
small: json["small"],
normal: json["normal"],
large: json["large"],
png: json["png"],
artCrop: json["art_crop"],
borderCrop: json["border_crop"],
);
Map<String, dynamic> toJson() => {
"small": small,
"normal": normal,
"large": large,
"png": png,
"art_crop": artCrop,
"border_crop": borderCrop,
};
}
class Legalities {
Legalities({
required this.standard,
required this.future,
required this.historic,
required this.gladiator,
required this.pioneer,
required this.modern,
required this.legacy,
required this.pauper,
required this.vintage,
required this.penny,
required this.commander,
required this.brawl,
required this.historicbrawl,
required this.alchemy,
required this.paupercommander,
required this.duel,
required this.oldschool,
required this.premodern,
});
String? standard;
String? future;
String? historic;
String? gladiator;
String? pioneer;
String? modern;
String? legacy;
String? pauper;
String? vintage;
String? penny;
String? commander;
String? brawl;
String? historicbrawl;
String? alchemy;
String? paupercommander;
String? duel;
String? oldschool;
String? premodern;
factory Legalities.fromJson(Map<String, dynamic> json) => Legalities(
standard: json["standard"],
future: json["future"],
historic: json["historic"],
gladiator: json["gladiator"],
pioneer: json["pioneer"],
modern: json["modern"],
legacy: json["legacy"],
pauper: json["pauper"],
vintage: json["vintage"],
penny: json["penny"],
commander: json["commander"],
brawl: json["brawl"],
historicbrawl: json["historicbrawl"],
alchemy: json["alchemy"],
paupercommander: json["paupercommander"],
duel: json["duel"],
oldschool: json["oldschool"],
premodern: json["premodern"],
);
Map<String, dynamic> toJson() => {
"standard": standard,
"future": future,
"historic": historic,
"gladiator": gladiator,
"pioneer": pioneer,
"modern": modern,
"legacy": legacy,
"pauper": pauper,
"vintage": vintage,
"penny": penny,
"commander": commander,
"brawl": brawl,
"historicbrawl": historicbrawl,
"alchemy": alchemy,
"paupercommander": paupercommander,
"duel": duel,
"oldschool": oldschool,
"premodern": premodern,
};
}
class Prices {
Prices({
required this.usd,
required this.usdFoil,
required this.usdEtched,
required this.eur,
required this.eurFoil,
required this.tix,
});
String? usd;
String? usdFoil;
dynamic usdEtched;
String? eur;
String? eurFoil;
String? tix;
factory Prices.fromJson(Map<String, dynamic> json) => Prices(
usd: json["usd"],
usdFoil: json["usd_foil"],
usdEtched: json["usd_etched"],
eur: json["eur"],
eurFoil: json["eur_foil"],
tix: json["tix"],
);
Map<String, dynamic> toJson() => {
"usd": usd,
"usd_foil": usdFoil,
"usd_etched": usdEtched,
"eur": eur,
"eur_foil": eurFoil,
"tix": tix,
};
}
class PurchaseUris {
PurchaseUris({
required this.tcgplayer,
required this.cardmarket,
required this.cardhoarder,
});
String tcgplayer;
String cardmarket;
String cardhoarder;
factory PurchaseUris.fromJson(Map<String, dynamic> json) => PurchaseUris(
tcgplayer: json["tcgplayer"],
cardmarket: json["cardmarket"],
cardhoarder: json["cardhoarder"],
);
Map<String, dynamic> toJson() => {
"tcgplayer": tcgplayer,
"cardmarket": cardmarket,
"cardhoarder": cardhoarder,
};
}
class RelatedUris {
RelatedUris({
required this.gatherer,
required this.tcgplayerInfiniteArticles,
required this.tcgplayerInfiniteDecks,
required this.edhrec,
required this.mtgtop8,
});
String gatherer;
String tcgplayerInfiniteArticles;
String tcgplayerInfiniteDecks;
String edhrec;
String mtgtop8;
factory RelatedUris.fromJson(Map<String, dynamic> json) => RelatedUris(
gatherer: json["gatherer"],
tcgplayerInfiniteArticles: json["tcgplayer_infinite_articles"],
tcgplayerInfiniteDecks: json["tcgplayer_infinite_decks"],
edhrec: json["edhrec"],
mtgtop8: json["mtgtop8"],
);
Map<String, dynamic> toJson() => {
"gatherer": gatherer,
"tcgplayer_infinite_articles": tcgplayerInfiniteArticles,
"tcgplayer_infinite_decks": tcgplayerInfiniteDecks,
"edhrec": edhrec,
"mtgtop8": mtgtop8,
};
}
I'm studying flutter by myself.
trying to make doto Calendar with carousel calendar.
I want to make date number big when there's event
-> it's done
the problem is
# line 238
if I put code like below, the calendar is keep refreshing whenever I press date button.
return snapshot.hasData && _markedDateMap.events.length > 0 ...
if I put code like below, my lovely big big date buttons becomes small!!
return snapshot.hasData ...
is there any solution for this problem?
please help me to stop the future builder is keep building!
TT
enter image description here
import 'package:flutter/material.dart';
import 'package:flutter_calendar_carousel/flutter_calendar_carousel.dart'
show CalendarCarousel;
import 'package:flutter_calendar_carousel/classes/event.dart';
import 'package:flutter_calendar_carousel/classes/event_list.dart';
import 'package:intl/intl.dart' show DateFormat;
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';
Future<List<ipoData>> fetchIPODatas(http.Client client) async {
final response = await client.get('http://realchord.net/ipo/getIPOData.php');
// Use the compute function to run parseIpoData in a separate isolate.
return compute(parseIpoData, response.body);
}
// A function that converts a response body into a List<Photo>.
List<ipoData> parseIpoData(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<ipoData>((json) => ipoData.fromJson(json)).toList();
}
// ignore: camel_case_types
class ipoData {
final String ipoDate;
final String company;
ipoData({this.ipoDate, this.company});
factory ipoData.fromJson(Map<String, dynamic> json) => ipoData(
ipoDate: json['date'],
company: json['company'],
);
}
// factory Model.fromJson(Map<String, dynamic> json) => Model(
// value1: json['key1'],
// value2: json['key2'],
// value3: json['key3'],
// value4: json['key4'],
// );
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'IPO calendar',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'IPO calendar'));
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DateTime _currentDate = new DateTime.now();
DateTime _currentDate2 = new DateTime.now();
String _currentMonth = DateFormat.MMMM().format(new DateTime.now());
DateTime _next = new DateTime(
DateTime.now().year, DateTime.now().month + 1, DateTime.now().day);
DateTime _prev = new DateTime(
DateTime.now().year, DateTime.now().month - 1, DateTime.now().day);
String _nextMonth;
String _prevMonth;
DateTime _targetDateTime = new DateTime.now();
// List<DateTime> _markedDate = [DateTime(2018, 9, 20), DateTime(2018, 10, 11)];
EventList<Event> _markedDateMap = new EventList<Event>();
// ignore: unused_field
CalendarCarousel _calendarCarouselNoHeader;
// load data
#override
void initState() {
super.initState();
}
// List response = await fetchIPODatas(http.Client());
#override
Widget build(BuildContext context) {
/// Example Calendar Carousel without header and custom prev & next button
_calendarCarouselNoHeader = CalendarCarousel<Event>(
onDayPressed: (DateTime date, List<Event> events) {
this.setState(() => _currentDate2 = date);
// events.forEach((event) => print(event.title));
},
//달력 기본 설정
daysHaveCircularBorder: true,
showOnlyCurrentMonthDate: false,
showHeader: false,
customGridViewPhysics: NeverScrollableScrollPhysics(),
height: 500.0,
daysTextStyle: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.white, //weekend day font color
),
weekendTextStyle: TextStyle(
fontWeight: FontWeight.w600,
color: Colors.white, //weekend day font color
),
weekdayTextStyle: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
// thisMonthDayBorderColor: Colors.grey, // border color of each day
weekFormat: false,
// firstDayOfWeek: 4,
markedDatesMap: _markedDateMap,
selectedDateTime: _currentDate2,
targetDateTime: _targetDateTime,
minSelectedDate: _currentDate.subtract(Duration(days: 360)),
maxSelectedDate: _currentDate.add(Duration(days: 360)),
// //이벤트가 있는 날에 대한 설정
// markedDateCustomShapeBorder:
// CircleBorder(side: BorderSide(color: Colors.yellow)),
markedDateCustomTextStyle: TextStyle(
fontSize: 30,
color: Colors.white,
),
// markedDateIconBorderColor: Colors.white,
// markedDateMoreShowTotal: true,
//오늘에 대한 설정
todayTextStyle: TextStyle(
color: Colors.white,
),
todayButtonColor: Colors.white24,
todayBorderColor: null,
// 선택한 날에 대한 설정
selectedDayTextStyle: TextStyle(
color: Colors.black,
),
selectedDayButtonColor: Colors.white,
// selectedDayBorderColor: Colors.white,
// 지난 달에 대한 설정
prevDaysTextStyle: TextStyle(
fontSize: 16,
color: Colors.white38,
),
// 다음 달에 대한 설정
nextDaysTextStyle: TextStyle(
fontSize: 16,
color: Colors.white38,
),
inactiveDaysTextStyle: TextStyle(
color: Colors.white38,
fontSize: 16,
),
onCalendarChanged: (DateTime date) {
this.setState(() {
_targetDateTime = date;
_currentMonth = DateFormat.MMMM().format(_targetDateTime);
_next = new DateTime(_targetDateTime.year, _targetDateTime.month + 1,
_targetDateTime.day);
_nextMonth = DateFormat.MMMM().format(_next);
_prev = new DateTime(_targetDateTime.year, _targetDateTime.month - 1,
_targetDateTime.day);
_prevMonth = DateFormat.M().format(_prev);
});
},
onDayLongPressed: (DateTime date) {
print('long pressed date $date');
},
);
_markedDateMap.clear();
_nextMonth = DateFormat.MMMM().format(_next);
_prevMonth = DateFormat.M().format(_prev);
// dotColorList.add(Colors.white);
return new Scaffold(
body: FutureBuilder<List<ipoData>>(
future: fetchIPODatas(http.Client()),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData &&
snapshot.data != null) {
final List<ipoData> ipoDataList = snapshot.data;
for (var i = 0; i < snapshot.data.length; i++) {
DateTime dt = DateTime.parse(ipoDataList[i].ipoDate.toString());
_markedDateMap.add(
dt,
new Event(
date: dt,
title: ipoDataList[i].company,
dot: Container(
margin: EdgeInsets.symmetric(horizontal: 1.0),
color: Colors.red.shade300,
height: 5.0,
width: 5.0,
),
));
}
}
return snapshot.hasData && _markedDateMap.events.length > 0
? SingleChildScrollView(
child: Stack(children: [
Container(
padding: EdgeInsets.only(top: 50),
color: Colors.blue,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
//custom icon without header
Container(
//display Month
margin: EdgeInsets.only(
top: 20.0,
bottom: 16.0,
left: 0.0,
right: 0.0,
),
padding: EdgeInsets.all(0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
FlatButton(
padding: EdgeInsets.all(0),
child: Text(_prevMonth,
// softWrap: false,
maxLines: 1,
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.white12,
fontSize: 48,
fontWeight: FontWeight.bold,
)),
onPressed: () {
setState(() {
_targetDateTime = DateTime(
_targetDateTime.year,
_targetDateTime.month - 1);
_currentMonth = DateFormat.MMMM()
.format(_targetDateTime);
});
},
),
Text(
_currentMonth,
maxLines: 1,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 48.0,
),
),
FlatButton(
child: Text(
_nextMonth,
softWrap: true,
maxLines: 1,
style: TextStyle(
color: Colors.white12,
fontSize: 48,
fontWeight: FontWeight.bold,
),
),
onPressed: () {
setState(() {
_targetDateTime = DateTime(
_targetDateTime.year,
_targetDateTime.month + 1);
_currentMonth = DateFormat.MMMM()
.format(_targetDateTime);
_next = new DateTime(
_targetDateTime.year,
_targetDateTime.month + 1,
_targetDateTime.day);
_nextMonth =
DateFormat.MMMM().format(_next);
_prev = new DateTime(
_targetDateTime.year,
_targetDateTime.month - 1,
_targetDateTime.day);
_prevMonth = DateFormat.M().format(_prev);
});
},
)
],
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 16.0),
child: _calendarCarouselNoHeader,
)
],
),
),
Container(
height: MediaQuery.of(context).size.height - 500,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.only(top: 500),
padding: const EdgeInsets.only(
top: 40,
left: 15,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white,
),
child: Column(
children: [
EventItem(
company: "LGENSol",
)
],
),
)
]),
)
: Center(child: CircularProgressIndicator());
},
));
}
}
class EventItem extends StatefulWidget {
// final Icon icon;
final String company;
// final Text category;
// final Function() notifyParent;
EventItem(
{
// #required this.icon,
#required this.company}); //#required this.notifyParent
#override
_EventItemState createState() => _EventItemState();
}
class _EventItemState extends State<EventItem> {
get futureAlbum => null;
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
children: [
Icon(
Icons.favorite,
color: Colors.pink,
size: 24.0,
),
Padding(
padding: EdgeInsets.all(12.0),
child: Text(widget.company,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
)),
),
Padding(
padding: EdgeInsets.all(5.0),
child: Text("(청약)",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
)),
),
],
),
Row(
children: [
Padding(
padding: EdgeInsets.only(left: 37),
child: Text("공모가:20,000원 | 상장:8/20 | 주관:키움",
style: TextStyle(
fontSize: 20,
)),
),
],
)
],
);
}
}
Every time you call setState in your stateful widget, you're calling that widget's build method, and since your FutureBuilder is part of it then it will get called. It doesn't seem like you're changing the future so I'd suggest you could bring the FutureBuilder a level higher and put your stateful widget inside the FutureBuilder
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: fetchIPODatas(http.Client()),
builder: (context, snapshot) {
//... (add your extracted stateful widget in here..)
},
),
);
}
}
I have logged in from a api . Then i got a response of json . I can fetch data from login to homepage . For that i created a constructor in homepage and pass it in Login page where i made navigator for the homepage . But i know it's not good practice to fetch data like it. using model class is more smart way. I added my code here of login, homepage and model . Now my data can only communicate between these two page . But i need to fetch data to another pages too.
login.dart
import 'package:api_login/model/response_model.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '../sharePreference.dart';
import 'homepage.dart';
class Login extends StatefulWidget {
UserDetails userDetails = new UserDetails();
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
var notification ;
bool isprocesscomplete = false;
TextEditingController _userController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
final _scaffoldKey = GlobalKey<ScaffoldState>();
String BaseUrl = "my url";
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SingleChildScrollView(
child: Center(
child: Container(
height: 770,
color: Colors. lightBlue,
padding: EdgeInsets.fromLTRB(20, 100, 20, 20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Login",
style: TextStyle(fontSize: 32),
),
SizedBox(
height: 30,
),
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
child: Container(
height: 220,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(30),
child: TextField(
controller: _userController,
decoration: InputDecoration(hintText: "Username"),
),
),
Padding(
padding: const EdgeInsets.all(30),
child: TextField(
controller: _passwordController,
obscureText: true,
decoration: InputDecoration(hintText: "Password"),
),
),
],
),
),
),
SizedBox(
height: 60,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.blue,
onPressed: () {
if (_userController.text == "" ||
_passwordController.text == "") {
final snackBar = SnackBar(
content: Text("Enter Username and Password"));
_scaffoldKey.currentState.showSnackBar(snackBar);
} else {
signIn(_userController.text, _passwordController.text);
}
},
child: ProgressButton(),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(16),
),
),
),
SizedBox(
height: 20,
),
FlatButton(
child: Text("Forgot password"),
onPressed: () {},
),
],
),
),
),
),
);
}
Widget ProgressButton() {
if (isprocesscomplete != false) {
return CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white));
} else {
return new Text(
"Sign In",
style: const TextStyle(
color: Colors.white,
fontSize: 15.0,
),
);
}
}
void signIn(String username, String password) async {
setState(() {
isprocesscomplete = true;
});
var response = await http.post(BaseUrl,
headers: {"Content-Type": "application/json"},
body: json.encode({
"username": username,
"password": password,
}));
Map<String, dynamic> value = json.decode(response.body);
notification = value["notifications"];
// print('Response ${response.body}');
if (response.statusCode == 200) {
try {
///You don't need it but it will be cool for show progress dialgo for 4 second then redirect even if we get reslut
Future.delayed(Duration(seconds: 4), () {
// 5s over make it false
setState(() {
isprocesscomplete = true;
});
});
Map<String, dynamic> value = json.decode(response.body);
print('Response ${response.body}');
SharedPrefrence().setToken(value['api_token'].toString());
SharedPrefrence().setName(value['user_name']);
SharedPrefrence().setUserId(value['user_id'].toString());
///This is used when user loged in you can set this true,
///next time you open you need to check loginc in main.dart or splashscreen if this is true if it is true then
///redirect to home page it is false then redirect to Login page
///When you logout the app make sure you set this as false like "SharedPrefrence().setLoggedIn(false);"
SharedPrefrence().setLoggedIn(true);
///Redirect to Home page
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => HomePage(
user_name: value['user_name'],
api_token: value['api_token'],
notification: notification,
// payment: payment ,
)),
ModalRoute.withName("/login"));
} catch (e) {
e.toString();
final snackBar =
SnackBar(
content: Text("something wrong,Try again 😑"),
behavior: SnackBarBehavior.floating,
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} else {
var message = value['error'];
final snackBar = SnackBar( backgroundColor: Colors.redAccent[700],
content: Text(message.toString()),
behavior: SnackBarBehavior.floating, );
_scaffoldKey.currentState.showSnackBar(snackBar);
}
}
}
homepage.dart
import 'package:api_login/model/response_model.dart';
import 'package:api_login/pages/details.dart';
import 'package:api_login/pages/settingPage.dart';
import 'package:api_login/widget/neumorphsm.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../sharePreference.dart';
import 'login.dart';
import 'login.dart';
class HomePage extends StatefulWidget {
final payment;
final count ;
String user_name;
final api_token;
final user_id ;
final payment_id;
final List<dynamic> notification ;
// List data ;
HomePage({ this.user_name, this.api_token , this.user_id, #required this.notification ,
this.count, this.payment, this.payment_id});
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String arrayLength ;
String nametoprint;
String tokentoprint;
#override
void initState() {
super.initState();
Future name = SharedPrefrence().getName();
name.then((data) async {
nametoprint = data;
print(nametoprint);
});
Future token= SharedPrefrence().getToken();
token.then((data) async {
tokentoprint= data;
print(tokentoprint);
});
}
int counter ;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Cash-Management"),
backgroundColor: Colors.blue,
actions: [
new Stack(
children: <Widget>[
new IconButton(icon: Icon(Icons.notifications), onPressed: () {
setState(() {
counter = 0;
});
}),
counter != 0 ? new Positioned(
right: 11,
top: 11,
child: new Container(
padding: EdgeInsets.all(2),
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 14,
minHeight: 14,
),
child: Text(
" ${widget.notification.length} ",
style: TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
) : new Container()
],
),
IconButton(
icon: Icon(Icons.exit_to_app),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Login()),
);
}),
],
),
body: ListView(
children: <Widget>[
Card(
color: Colors.lightBlue,
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new SettingPage()));
},
child: Container(
height: 120,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Profile",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
Text(
"Name:${widget.user_name}",
// " ${widget.username} ",
style: TextStyle(fontSize: 16),
),
// Text(
// " ${widget.notification.length} ",),
// Text(" ${nametoprint} "),
],
),
),
),
),
Container(
color: Colors.lightBlue,
height: 400,
child: ListView.builder(
itemCount: widget.notification == null ? 0 : widget.notification.length,
itemBuilder: (context, index){
final count = widget.notification ;
print(count.length);
return Card(
color: Colors.blue,
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetailPage()));
},
child: Column(
children:<Widget>[
Text('Amount'),
ListTile(
title: Text(widget.notification[index] ["data"]["amount"].toString()),
subtitle: Text(widget.notification[index]["data"]["message"].toString()),
) ,
Text('Created at '),
ListTile(
title: Text(widget.notification[index] ["created_at"].toString()),
),
Text('updated at'),
ListTile(
title: Text(widget.notification[index] ["updated_at"].toString()),
),
],
),
),
);
}),
),
Container(
color: Colors.blue,
height: 130,
child: Button()
),
],
),
// floatingActionButton: FloatingActionButton(onPressed: () {
// print("Increment Counter");
// setState(() {
// counter++;
// });
// }, child: Icon(Icons.add),),
),
);
}
}
response_model.dart
class UserDetails {
int userId;
String userName;
String apiToken;
List<Notifications> notifications;
UserDetails({this.userId, this.userName, this.apiToken, this.notifications});
UserDetails.fromJson(Map<String, dynamic> json) {
userId = json['user_id'];
userName = json['user_name'];
apiToken = json['api_token'];
if (json['notifications'] != null) {
notifications = new List<Notifications>();
json['notifications'].forEach((v) {
notifications.add(new Notifications.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['user_id'] = this.userId;
data['user_name'] = this.userName;
data['api_token'] = this.apiToken;
if (this.notifications != null) {
data['notifications'] =
this.notifications.map((v) => v.toJson()).toList();
}
return data;
}
}
class Notifications {
String id;
String type;
int notifiableId;
String notifiableType;
Data data;
Null readAt;
String createdAt;
String updatedAt;
Notifications(
{this.id,
this.type,
this.notifiableId,
this.notifiableType,
this.data,
this.readAt,
this.createdAt,
this.updatedAt});
Notifications.fromJson(Map<String, dynamic> json) {
id = json['id'];
type = json['type'];
notifiableId = json['notifiable_id'];
notifiableType = json['notifiable_type'];
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
readAt = json['read_at'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['type'] = this.type;
data['notifiable_id'] = this.notifiableId;
data['notifiable_type'] = this.notifiableType;
if (this.data != null) {
data['data'] = this.data.toJson();
}
data['read_at'] = this.readAt;
data['created_at'] = this.createdAt;
data['updated_at'] = this.updatedAt;
return data;
}
}
class Data {
int paymentId;
String generatePaymentId;
String message;
int amount;
Data({this.paymentId, this.generatePaymentId, this.message, this.amount});
Data.fromJson(Map<String, dynamic> json) {
paymentId = json['payment_id'];
generatePaymentId = json['generate_payment_id'];
message = json['message'];
amount = json['amount'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['payment_id'] = this.paymentId;
data['generate_payment_id'] = this.generatePaymentId;
data['message'] = this.message;
data['amount'] = this.amount;
return data;
}
}
It will be helpful if anyone let e know how to show detail page from this section.
ListView.builder(
itemCount: widget.notification == null ? 0 : widget.notification.length,
itemBuilder: (context, index){
final count = widget.notification ;
print(count.length);
return Card(
color: Colors.blue,
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetailPage()));
},
You can use widget.user_name, widget.api_token in HomePage, and pass it to Details Page.
Home Page
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetailPage(userName :widget.user_name, apiToken: widget.api_token)));
If you want the data to be used globally in your application, perhaps you can fetch your data from API before MaterialApp() so that your data can be used globally.
Other way is you can pass your UserDetails() data to next page by calling them inside your Navigator.push(). You can read more detail example here
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
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.