Error fetching data from api and display it - api

I want to make a get request from my restApi and then display the data in a listView but for some reason it is not working.
The error I'm getting:
The getter 'length' was called on null.
Receiver: null
Tried calling: length
Api call (apiBaseHelper.dart)
Future<List<Post>> getAllPosts() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key) ?? 0;
final getPublishedPostUrl = "http://192.168.1.7:5000/post/all";
final response = await http.get(getPublishedPostUrl, headers: {
'Accept': 'application/json',
'Authorization': 'Bearer $value'
});
if (response.statusCode == 200) {
List jsonResponse = json.decode(response.body);
return jsonResponse.map((posts) => new Post.fromJson(posts)).toList();
} else {
throw "something ";
}
}
PostListView
class PostListView extends StatelessWidget {
final List<Post> posts;
PostListView({Key key, this.posts}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
Container(
constraints: BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
color: Colors.white10,
alignment: Alignment.center,
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
contentPadding: EdgeInsets.all(10.0),
title: new Text(posts[index].title),
leading: new Image.network(
posts[index].picture,
fit: BoxFit.cover,
height: 40.0,
width: 40.0,
),
subtitle: Text(posts[index].category),
),
],
),
),
),
],
);
},
));
}
}
homePage.dart
class HomePage extends StatefulWidget {
final ApiBaseHelper apiBaseHelper = ApiBaseHelper();
#override
State<StatefulWidget> createState() {
return _HomePageState();
}
}
class _HomePageState extends State<HomePage> {
Future<List<Post>> futurePost;
#override
void initState() {
super.initState();
futurePost = ApiBaseHelper().getAllPosts();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.teal,
body: new Padding(
padding: EdgeInsets.fromLTRB(1.0, 10.0, 1.0, 10.0),
child: FutureBuilder<List<Post>>(
future: ApiBaseHelper().getAllPosts(),
builder: (context, AsyncSnapshot<List<Post>> snapshot) {
if (snapshot.hasError) {
print(snapshot.error);
}
return snapshot.hasData
? PostListView()
: Center(child: CircularProgressIndicator());
},
),
),
);
}
}
I have been working on it for like 2 days and I don't know where the problem exactly
I'm sorry if it's too much code. thank you in advance

This code section here ,
return snapshot.hasData
? PostListView()
: Center(child: CircularProgressIndicator());
Add PostListView(posts:snapshot.data)
Tell me if it works.

Related

How to show list item to another page

From the code below, when I create user(student) data It will show up as a list. Each student information will be shown by a ListTile widget. When I slide and press the completed button on the ListTile, I want my ListTile to show on the 'Completed' page list view. I am currently working with sqlite. I am having a hard time trying to figure this out.
main.dart
import 'package:flutter/material.dart';
import '../database/db.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return (MaterialApp(
home: Scaffold(
body: PageView(children: <Widget>[Home(), Completed()]),
)));
}
}
//Uncompleted
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text("Students"),
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddInfo()),
).then((value) {
setState(() {});
});
},
icon: Icon(Icons.add),
)
],
),
body: userInfoBuilder(context),
);
}
Future<List<UserInfo>> loadUserInfo() async {
DBHelper sd = DBHelper();
return await sd.userInfo();
}
Future<void> deleteUserInfo(String id) async {
DBHelper sd = DBHelper();
sd.deleteUserInfo(id);
}
Widget userInfoBuilder(BuildContext parentContext) {
return FutureBuilder<List<UserInfo>>(
builder: (context, snap) {
if (snap.data == null || snap.data.isEmpty) {
return Container();
}
return ListView.builder(
itemCount: snap.data.length,
itemBuilder: (context, index) {
UserInfo userInfo = snap.data[index];
return Slidable(
actionPane: SlidableBehindActionPane(),
actions: <Widget>[
IconSlideAction(
caption: 'delete',
icon: Icons.delete,
color: Colors.red,
onTap: () {
setState(() {
deleteUserInfo(userInfo.id);
});
})
],
secondaryActions: <Widget>[
IconSlideAction(
caption: 'completed',
icon: Icons.check,
color: Colors.green,
onTap: () {}),
],
child: ListTile(
title: Text(
userInfo.name,
style: TextStyle(
fontSize: 18.0,
),
),
trailing: Text(
'${userInfo.grade}-${userInfo.classnum}-${userInfo.studentnum}',
style: TextStyle(color: Colors.grey),
),
),
);
},
);
},
future: loadUserInfo(),
);
}
}
//completed
class Completed extends StatefulWidget {
#override
_CompletedState createState() => _CompletedState();
}
class _CompletedState extends State<Completed> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text(
"Completed",
),
),
body: userInfoBuilder(context),
);
}
Widget userInfoBuilder(BuildContext parentContext) {
return FutureBuilder<List<UserInfo>>(
builder: (context, snap) {
if (snap.data == null || snap.data.isEmpty) {
return Container();
}
return ListView.builder();
},
future: loadUserInfo(),
);
}
Future<List<UserInfo>> loadUserInfo() async {
DBHelper sd = DBHelper();
return await sd.userInfo();
}
}
//Add user information
class AddInfo extends StatefulWidget {
#override
_AddInfoState createState() => _AddInfoState();
}
class _AddInfoState extends State<AddInfo> {
hideKeyboard() {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}
final formKey = GlobalKey<FormState>();
String _grade;
final List<String> _grades = ['1', '2', '3'];
String name = '';
String classNum = ' ';
String studentNum = ' ';
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
hideKeyboard();
},
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
hideKeyboard();
})),
body: Form(
key: formKey,
child: Column(
children: <Widget>[
usrNameField(),
Row(
children: <Widget>[
Expanded(child: usrGradeField()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
),
Expanded(child: usrClassField()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0),
),
Expanded(child: usrNumField()),
],
),
submitButton()
],
),
),
));
}
Widget usrNameField() {
return TextFormField(
keyboardType: TextInputType.name,
decoration: InputDecoration(
labelText: 'name',
),
onChanged: (String name) {
this.name = name;
},
validator: (input) => input.trim().isEmpty ? 'Enter name' : null);
}
Widget usrGradeField() {
return DropdownButtonFormField(
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 22.0,
items: _grades.map((String grade) {
return DropdownMenuItem(
value: grade,
child: Text(
grade,
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
);
}).toList(),
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Grade',
),
validator: (input) => input.trim().isEmpty ? 'Enter grade.' : null,
onChanged: (value) {
setState(() {
_grade = value;
});
},
value: _grade,
);
}
Widget usrClassField() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Class',
),
validator: (input) => input.trim().isEmpty ? 'Enter class.' : null,
onChanged: (String classNum) {
this.classNum = classNum;
},
);
}
Widget usrNumField() {
return TextFormField(
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Number',
),
validator: (input) => input.trim().isEmpty ? 'Enter number' : null,
onChanged: (String studentNum) {
this.studentNum = studentNum;
},
);
}
Widget submitButton() {
return MaterialButton(
color: Colors.blue,
child: Text(
'submit',
style: TextStyle(color: Colors.white),
),
onPressed: () {
hideKeyboard();
if (formKey.currentState.validate()) {
saveDB();
Navigator.pop(context);
}
},
);
}
Future<void> saveDB() async {
DBHelper sd = DBHelper();
var fido = UserInfo(
id: str2sha512(DateTime.now().toString()),
name: this.name,
grade: this._grade,
classnum: this.classNum,
studentnum: this.studentNum,
);
await sd.insertUserInfo(fido);
print(await sd.userInfo());
}
String str2sha512(String text) {
var bytes = utf8.encode(text);
var digest = sha512.convert(bytes);
return digest.toString();
}
}
db.dart
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class UserInfo {
final String id;
final String name;
final String grade;
final String classnum;
final String studentnum;
UserInfo({
this.id,
this.name,
this.grade,
this.classnum,
this.studentnum,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'grade': grade,
'classnum': classnum,
'studentnum': studentnum,
};
}
#override
String toString() {
return 'userInfo{id: $id, name: $name, grade: $grade, classnum: $classnum, studentnum: $studentnum}';
}
}
final String TableName = 'userInfo';
class DBHelper {
var _db;
Future<Database> get database async {
if (_db != null) return _db;
_db = openDatabase(
join(await getDatabasesPath(), 'userInfo.db'),
onCreate: (db, version) {
return db.execute(
"CREATE TABLE userInfo(id TEXT PRIMARY KEY, name TEXT, grade TEXT, classnum TEXT, studentnum TEXT, phonenumber TEXT, status INTEGER)",
);
},
version: 1,
);
return _db;
}
Future<void> insertUserInfo(UserInfo userInfo) async {
final db = await database;
await db.insert(
TableName,
userInfo.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<List<UserInfo>> userInfo() async {
final db = await database;
final List<Map<String, dynamic>> maps = await db.query('userInfo');
return List.generate(maps.length, (i) {
return UserInfo(
id: maps[i]['id'],
name: maps[i]['name'],
grade: maps[i]['grade'],
classnum: maps[i]['classnum'],
studentnum: maps[i]['studentnum'],
);
});
}
Future<void> updateUserInfo(UserInfo userInfo) async {
final db = await database;
await db.update(
TableName,
userInfo.toMap(),
where: "id = ?",
whereArgs: [userInfo.id],
);
}
Future<void> deleteUserInfo(String id) async {
final db = await database;
await db.delete(
TableName,
where: "id = ?",
whereArgs: [id],
);
}
}
You can use the Provider package to listen to changes on your app and notify any listeners and update the UI here's A link to an example from the flutter devs

My Content from API is not being shown in Flutter

I wrote my code in flutter, and used NewsAPI.org for getting content about news, such as heading, image, content etc. I made a class "News" and ArticleModel() for retrieving and using the information. I used Conditional Operator (? :) for checking if the data is received, then show it, else CircularProgressIndiactor() is shown. After running the app, CircularProgressIndiactor() shows up and no information is shown/loaded. Can anyone help me here??
No error or warning is shown, and code compiles successfully, but no information is shown up.
Here is the main file, home.dart -
import 'package:flutter/material.dart';
import 'package:news_app/helper/data.dart';
import 'package:news_app/helper/news.dart';
import 'package:news_app/models/article_model.dart';
import 'package:news_app/models/category_models.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<CategoryModel> categories = new List<CategoryModel>();
List<ArticleModel> articles = new List<ArticleModel>();
bool loading = true;
#override
void initState() {
// TODO: implement initState
super.initState();
categories = getCategories();
getNews();
}
getNews() async {
News newsClass = News();
await newsClass.getNews();
articles = newsClass.news;
setState(() {
loading = false;
print('Done');
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Flutter',
style: TextStyle(
color: Colors.black,
),
),
Text(
'News',
style: TextStyle(
color: Colors.blue,
),
),
],
),
//elevation: 2.0,
),
body: loading
? Center(
child: Container(
child: CircularProgressIndicator(),
),
)
: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
///Categories
Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
height: 70.0,
child: ListView.builder(
itemCount: categories.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (context, index) {
return CategoryTile(
imageUrl: categories[index].imageUrl,
categoryName: categories[index].categoryName,
);
},
),
),
///Blogs
Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: articles.length,
itemBuilder: (context, index) {
return BlogTile(
imageUrl: articles[index].urlToImage,
title: articles[index].title,
desc: articles[index].description,
);
},
),
),
],
),
),
),
),
);
}
}
class CategoryTile extends StatelessWidget {
final imageUrl, categoryName;
CategoryTile({this.imageUrl, this.categoryName});
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Container(
margin: EdgeInsets.only(right: 16.0),
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(6.0),
child: Image.network(
imageUrl,
width: 120.0,
height: 160.0,
fit: BoxFit.cover,
),
),
Container(
alignment: Alignment.center,
width: 120.0,
height: 60.0,
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(6.0)),
child: Text(
categoryName,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 14.0,
),
),
),
],
),
),
);
}
}
class BlogTile extends StatelessWidget {
final String imageUrl, title, desc;
BlogTile(
{#required this.imageUrl, #required this.desc, #required this.title});
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Image.network(imageUrl),
Text(title),
Text(desc),
],
),
);
}
}
Here is the News.dart file -
import 'dart:convert';
import 'package:news_app/models/article_model.dart';
import 'package:http/http.dart' as http;
class News {
List<ArticleModel> news = [];
Future<void> getNews() async{
String url="http://newsapi.org/v2/top-headlines?country=in&category=business&apiKey=xxxxxxxxxxxxxxxxxx";
var response = await http.get(url);
var jsonData = jsonDecode(response.body);
if(jsonData["status"] == "ok") {
jsonData["articles"].forEach((element){
if(element['urlToImage'] != null && element['description'] != null) {
ArticleModel articleModel = ArticleModel(
title: element['title'],
author: element['author'],
description: element['description'],
url: element['url'],
urlToImage: element['urlToImage'],
content: element['content'],
);
news.add(articleModel);
}
});
}
}
}
And at last, ArticleModel.dart -
class ArticleModel {
String author, title, description;
String url, urlToImage;
String content;
ArticleModel({this.title, this.description, this.author, this.content, this.url, this.urlToImage});
}
Updating your request URL from http to https will give you expected result.
Update URL to: "https://newsapi.org/v2/top-headlines?country=in&category=business&apiKey="
Note: Don't share your API key in any open platforms for security reasons.

Flutter Http Request is returning null

I am trying to make some http requests to an API. The first is to get data and display it in a list view and the second one is some more data but I want to display it on a new page. The code I have currently is returning null for the second Total request. If I run the total code separately it works fine and displays the data in a list view.
main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'Product.dart';
import 'Total.dart';
void main() => runApp(MyApp(
products: fetchProducts(),
total: fetchTotal(),
));
List<Product> parseProducts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) => Product.fromJson(json)).toList();
}
Future<List<Product>> fetchProducts() async {
final response =
await http.get('http://10.0.0.102:9000/all/aF63z0R0jlQR7sfOgBAgOCOsQgv1');
if (response.statusCode == 200) {
return parseProducts(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class MyApp extends StatelessWidget {
final Future<List<Product>> products;
final Future<List<Total>> total;
MyApp({Key key, this.products, this.total}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Product Navigation demo home page',
products: products,
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
final Future<List<Product>> products;
final Future<List<Total>> total;
MyHomePage({Key key, this.title, this.products, this.total})
: super(key: key);
// final items = Product.getProducts();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Product>>(
future: products,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ProductBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => TotalPage()));
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
);
}
}
class ProductBoxList extends StatelessWidget {
final List<Product> items;
ProductBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ProductBox(item: items[index]),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductPage(item: items[index]),
),
);
},
);
},
);
}
}
class ProductPage extends StatelessWidget {
ProductPage({Key key, this.item}) : super(key: key);
final Product item;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.item.pName),
),
body: Center(
child: Container(
padding: EdgeInsets.all(0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
),
),
);
}
}
class ProductBox extends StatelessWidget {
ProductBox({Key key, this.item}) : super(key: key);
final Product item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
));
}
}
List<Total> parseTotal(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Total>((json) => Total.fromJson(json)).toList();
}
Future<List<Total>> fetchTotal() async {
final response = await http.get('http://10.0.0.102:8000/testData.json');
if (response.statusCode == 200) {
return parseTotal(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class TotalPage extends StatelessWidget {
final String title;
final Future<List<Total>> total;
TotalPage({Key key, this.title, this.total}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Total>>(
future: total,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
print(snapshot.data);
return snapshot.hasData
? TotalBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
);
}
}
class TotalBoxList extends StatelessWidget {
final List<Total> items;
TotalBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: TotalDisplay(item: items[index]),
);
},
);
}
}
class TotalDisplay extends StatelessWidget {
TotalDisplay({Key key, this.item}) : super(key: key);
final Total item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.total.toString(),
style: TextStyle(fontWeight: FontWeight.bold)),
],
)))
]),
));
}
}
total.dart
import 'package:flutter/foundation.dart';
class Total {
final double total;
Total(this.total);
factory Total.fromJson(Map<String, dynamic> data) {
return Total(
data['total'],
);
}
}
You can copy paste run full code below
You forgot to pass total
Step 1: MyHomePage
MyHomePage(
title: 'Product Navigation demo home page',
products: products,
total: total, //here
),
Step 2: FloatingActionButton
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TotalPage(
total: total,
))); //here
},
working demo
full code
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp(
products: fetchProducts(),
total: fetchTotal(),
));
List<Product> parseProducts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) => Product.fromJson(json)).toList();
}
Future<List<Product>> fetchProducts() async {
/*final response =
await http.get('http://10.0.0.102:9000/all/aF63z0R0jlQR7sfOgBAgOCOsQgv1');*/
String jsonString = '''
[
{
"pName":"1",
"price":"2",
"barcode": 3
},
{
"pName":"4",
"price":"5",
"barcode": 6
}
]
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
return parseProducts(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class MyApp extends StatelessWidget {
final Future<List<Product>> products;
final Future<List<Total>> total;
MyApp({Key key, this.products, this.total}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
title: 'Product Navigation demo home page',
products: products,
total: total, //here
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
final Future<List<Product>> products;
final Future<List<Total>> total;
MyHomePage({Key key, this.title, this.products, this.total})
: super(key: key);
// final items = Product.getProducts();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Product>>(
future: products,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? ProductBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TotalPage(
total: total,
))); //here
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
),
);
}
}
class ProductBoxList extends StatelessWidget {
final List<Product> items;
ProductBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ProductBox(item: items[index]),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductPage(item: items[index]),
),
);
},
);
},
);
}
}
class ProductPage extends StatelessWidget {
ProductPage({Key key, this.item}) : super(key: key);
final Product item;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(this.item.pName),
),
body: Center(
child: Container(
padding: EdgeInsets.all(0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
),
),
);
}
}
class ProductBox extends StatelessWidget {
ProductBox({Key key, this.item}) : super(key: key);
final Product item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.pName,
style: TextStyle(fontWeight: FontWeight.bold)),
Text("Price: " + this.item.price),
Text("Barcode: " + this.item.barcode.toString()),
],
)))
]),
));
}
}
List<Total> parseTotal(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
List<Total> a = parsed.map<Total>((json) => Total.fromJson(json)).toList();
return a;
}
Future<List<Total>> fetchTotal() async {
print("fetchTotal");
//final response = await http.get('http://10.0.0.102:8000/testData.json');
String jsonString = '''
[
{
"total":124.4
},
{
"total":123.1
}
]
''';
final response = http.Response(jsonString, 200);
if (response.statusCode == 200) {
return parseTotal(response.body);
} else {
throw Exception("Unable to access Server.");
}
}
class TotalPage extends StatelessWidget {
final String title;
final Future<List<Total>> total;
TotalPage({Key key, this.title, this.total}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Total>>(
future: total,
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? TotalBoxList(items: snapshot.data)
// return the ListView widget :
: Center(child: CircularProgressIndicator());
},
),
),
);
}
}
class TotalBoxList extends StatelessWidget {
final List<Total> items;
TotalBoxList({Key key, this.items});
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: TotalDisplay(item: items[index]),
);
},
);
}
}
class TotalDisplay extends StatelessWidget {
TotalDisplay({Key key, this.item}) : super(key: key);
final Total item;
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(2),
height: 140,
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(this.item.total.toString(),
style: TextStyle(fontWeight: FontWeight.bold)),
],
)))
]),
));
}
}
class Total {
final double total;
Total(this.total);
factory Total.fromJson(Map<String, dynamic> data) {
return Total(
data['total'],
);
}
}
class Product {
String pName;
String price;
int barcode;
Product({this.pName, this.price, this.barcode});
factory Product.fromJson(Map<String, dynamic> data) {
return Product(
pName: data["pName"], price: data["price"], barcode: data["barcode"]);
}
}

Upload chosen image to the API in Flutter using image picker plugin

I want to upload the image into the API. I tried this code but I got an error
File not found
If I send an image file using Postman, it is working successfully. Here I attached the Postman screenshot, for upload the image I gave the image path and in addition for my document, I want to attach the user id please tell me a solution? thank you
This is my code
class _UserProfileEditState extends State<UserProfileEdit> {
// String imagepath='';
File _profileImage;
String base64Image;
DatabaseHelper databaseHelper = new DatabaseHelper();
int parentid;
_handleimagefromgallary() async {
File imagefile = await ImagePicker.pickImage(source: ImageSource.gallery);
if(imagefile!=null) {
setState(() {
_profileImage = imagefile;
});
}
}
_displayprofilephoto()
{
if(_profileImage==null)
{
if(widget.parentsInfo.data.photo==null)
{
return AssetImage('assets/images/parentimg.png');
}
else
{
return CachedNetworkImageProvider(widget.parentsInfo.data.photo);
}
}
else
{
return FileImage(_profileImage);
}
}
#override
Widget build(BuildContext context) {
parentid=widget.parentsInfo.data.id;
return Scaffold(
appBar: AppBar(
title: Center(
child: Text('Edit Profile'),
),
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height * 1.5,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Container(
height: 160.0,
width: 160.0, //MediaQuery.of(context).size.width,
child: new CircleAvatar(
radius: 50.0,
backgroundColor: Colors.green,
backgroundImage: _displayprofilephoto(),
),
),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(''),
InkWell(
child: Icon(Icons.add_photo_alternate),
onTap:_handleimagefromgallary,
),
],
),
),
showpdatebutton(),
This is the method to upload:
Future _updateprofilepicture() async{
// _profileImage=await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
// var path = await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
// var path =await FlutterAbsolutePath.getAbsolutePath(_profileImage.absolute.path);
var path=await FlutterAbsolutePath.getAbsolutePath(_profileImage.path);
if(path==null)
{
}
else
{
// call controller
print(path);
String id=parentid.toString();
databaseHelper.parentprofileupdate(path, id);
// databaseHelper.parentprofileupdate(_profileImage, id);
}
}
Widget showpdatebutton() {
if(_profileImage!=null)
{
return OutlineButton(
child: Text('Update Profile Picture'),
onPressed: (){
_updateprofilepicture();
}
);
}
else
{
return Container();
}
}
}
My database helper class:
Future<ParentProfileUpdate> parentprofileupdate(String path,String id) async
{
Map mapValue;
var data;
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
String myUrl = "$serverUrl/api/v1/upload_parent_image";
await http.post(myUrl,
headers: {
// 'Accept':'application/json',
"HttpHeaders.contentTypeHeader": "application/json",
'Authorization' : 'Bearer $value'
},
body: {
"photo" :path,
"id":id,
}).then((response) {
status = response.body.contains('error');
mapValue=json.decode(response.body);
var data = json.decode(response.body);
print(data);
});
}

How do I deal with logins on different devices based on API response in flutter?

I'm confused about how to deal with multiple logins with different devices, and I want to give the function back to the login layout when there are other devices that have just logged in to the same user
Future<EventArticleList> getEventArticleList(String token) async {
BuildContext context;
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer $token"
};
var response = await client.get('$endpoint/', headers: headers);
if (response.statusCode == 200) {
print("Masuk Data");
return EventArticleList.fromJson(
json.decode(response.body),
);
} else if (response.statusCode == 401) {
print("401");
return Navigator.of(context)
.pushNamedAndRemoveUntil(RoutePaths.Login, (_) => false);
} else {
throw Exception("ini Eror apa ?");
}
}
the compilation appears I try to add the navigator back to status.code == 401
NoSuchMethodError: The method 'ancestorStateOfType' was called on null
Try this code
Your main class
import 'package:flutter/material.dart';
import 'package:flutterapitut/view/adddata.dart';
import 'package:flutterapitut/view/dashboard.dart';
import 'package:flutterapitut/view/login.dart';
import 'package:flutterapitut/view/register.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final String title='';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter CRUD API',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(title: 'Flutter CRUD API'),
routes: <String,WidgetBuilder>{
'/dashboard' : (BuildContext context) => new Dashboard(title:title),
'/login' : (BuildContext context) => new LoginPage(title:title),
},
);
}
}
Your Database Helper class
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class DatabaseHelper{
String serverUrl = "http://flutterapitutorial.codeforiraq.org/api";
var status ;
var token ;
loginData(String email , String password) async{
String myUrl = "$serverUrl/login1";
final response = await http.post(myUrl,
headers: {
'Accept':'application/json'
},
body: {
"email": "$email",
"password" : "$password"
} ) ;
status = response.body.contains('error');
var data = json.decode(response.body);
if(status){
print('data : ${data["error"]}');
}else{
print('data : ${data["token"]}');
_save(data["token"]);
}
}
_save(String token) async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = token;
prefs.setString(key, value);
}
read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
print('read : $value');
}
}
Your login class
import 'package:flutter/material.dart';
import 'package:flutterapitut/Controllers/databasehelper.dart';
import 'package:flutterapitut/view/dashboard.dart';
import 'package:flutterapitut/view/register.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginPage extends StatefulWidget{
LoginPage({Key key , this.title}) : super(key : key);
final String title;
#override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> {
read() async {
final prefs = await SharedPreferences.getInstance();
final key = 'token';
final value = prefs.get(key ) ?? 0;
if(value != '0'){
Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) => new Dashboard(),
)
);
}
}
#override
initState(){
read();
}
DatabaseHelper databaseHelper = new DatabaseHelper();
String msgStatus = '';
final TextEditingController _emailController = new TextEditingController();
final TextEditingController _passwordController = new TextEditingController();
_onPressed(){
setState(() {
if(_emailController.text.trim().toLowerCase().isNotEmpty &&
_passwordController.text.trim().isNotEmpty ){
databaseHelper.loginData(_emailController.text.trim().toLowerCase(),
_passwordController.text.trim()).whenComplete((){
if(databaseHelper.status){
_showDialog();
msgStatus = 'Check email or password';
}else{
Navigator.pushReplacementNamed(context, '/dashboard');
}
});
}
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Login',
home: Scaffold(
appBar: AppBar(
title: Text('Login'),
),
body: Container(
child: ListView(
padding: const EdgeInsets.only(top: 62,left: 12.0,right: 12.0,bottom: 12.0),
children: <Widget>[
Container(
height: 50,
child: new TextField(
controller: _emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Place your email',
icon: new Icon(Icons.email),
),
),
),
Container(
height: 50,
child: new TextField(
controller: _passwordController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Place your password',
icon: new Icon(Icons.vpn_key),
),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new RaisedButton(
onPressed: _onPressed,
color: Colors.blue,
child: new Text(
'Login',
style: new TextStyle(
color: Colors.white,
backgroundColor: Colors.blue),),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new Text(
'$msgStatus',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
new Padding(padding: new EdgeInsets.only(top: 44.0),),
Container(
height: 50,
child: new FlatButton(
onPressed: ()=>Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext context) => new RegisterPage(),
)
)
,
color: Colors.blue,
child: new Text(
'Register',
style: new TextStyle(
color: Colors.white,
),),
),
),
],
),
),
),
);
}
void _showDialog(){
showDialog(
context:context ,
builder:(BuildContext context){
return AlertDialog(
title: new Text('Failed'),
content: new Text('Check your email or password'),
actions: <Widget>[
new RaisedButton(
child: new Text(
'Close',
),
onPressed: (){
Navigator.of(context).pop();
},
),
],
);
}
);
}
}
Here Dashboard is the class you expected to navigate after successfully login
Want more code visite here I hope this work correctly