im tring to view tasks on alone screen from data using rest api dart django with project_id its one-to-many relationship project has many tasks so i want to dispay the tasks when i click on project widget using future builder
Edit :i found the problem check my answer below here is usage of future builder and task list
import 'package:flutter/material.dart';
import 'package:project/model/task_model.dart';
import 'package:project/project_dtetailForTest.dart';
import 'package:provider/provider.dart';
import 'new_project.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
class TaskById extends StatefulWidget {
//const TaskById({ Key? key }) : super(key: key);
final int project_id;
//final Task task =Task();
TaskById({required this.project_id}):super();
@override
State<TaskById> createState() => _TaskByIdState();
}
class _TaskByIdState extends State<TaskById> {
@override
Widget build(BuildContext context) {
final taskP= Provider.of<TaskProvider>(context);
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
bottom: PreferredSize(
child: Container(
color: const Color(0xff94adb4),
height: 2,
width: 320,
),
preferredSize: const Size.fromHeight(4.0)),
centerTitle: true,
backgroundColor:const Color(0xff076792),
title: const Text(
'Project1',
style: TextStyle(color: Colors.white,
fontSize: 35,
fontWeight:FontWeight.w700,
shadows: [
Shadow(
color: Color(0xa6A2B6D4),
blurRadius:20),
] ),
),
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back,
size: 44,
),
),
actions:[Container(padding: const EdgeInsets.fromLTRB(0, 0, 6, 3),
child: IconButton(
color:Colors.white ,
icon: const Icon(
Icons.search,
size: 44,
),
onPressed: () {},
),
),]
),
//TaskProvider(){
// this.fetchTask();
// }
body: FutureBuilder(
future: TaskProvider().fetchTask(widget.project_id),
builder: (context, snapshot){
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData && snapshot is List<Task>
?TaskList(task:snapshot.data as List<Task>)
:Center(child: CircularProgressIndicator());
}),
// FutureProvider(
// create: (context) => TaskProvider().fetchTask() ,
// initialData: [CircularProgressIndicator()],
// child:Center(child: Consumer<Task>(
// builder: (context, task, widget) {
// return (taskP !=null) ? Column(
// children: [
// Row(
// children: const [
// Padding(padding: EdgeInsets.all(7),
// child: Padding(
// padding: EdgeInsets.fromLTRB(24,10,10,8),
// child: Text('Project1',
// style: TextStyle(
// color: Color(0xff076792),
// fontSize: 40,
// fontWeight: FontWeight.w600
// ),
// ),
// ),
// ),
// ],
// ),
// // dynamic list
// Expanded(
// child: ListView.builder(
// itemCount: taskP.task.length ,
// itemBuilder: (BuildContext context, int index) {
// return Padding(
// padding: const EdgeInsets.fromLTRB(28, 12, 28, 0),
// child: GestureDetector(
// onTap: () {
// Navigator.push(context, MaterialPageRoute(builder: (context) => projectDetails()));
// },
// child: Card(child:Container(padding: const EdgeInsets.fromLTRB(18,8,9,4),
// width: 100,
// height: 100,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(19.0),
// color: const Color(0xff076792),
// boxShadow: const [
// BoxShadow(color: Colors.black, spreadRadius: 1),
// BoxShadow(color: Color(0xa6A2B6D4),
// offset: Offset(7,5),
// blurRadius:20),
// ],
// ),
// child: Column(children: [
// Row(mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Text('Starting ' taskP.task[index].start.toString(),style:
// const TextStyle(color: Color.fromARGB(255, 133, 186, 202),fontSize: 18,),
// ),
// ],
// ),
// const Spacer(),
// Row(mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Text(taskP.task[index].title??'',style:
// const TextStyle(color: Colors.white,fontSize: 34,)),
// ],
// ),
// const Spacer(),
// Row(mainAxisAlignment: MainAxisAlignment.end,
// children: [
// Text('Ending ' taskP.task[index].end.toString(),style:
// const TextStyle(color: Color.fromARGB(255, 133, 186, 202),
// fontSize: 18,
// )),
// ],
// ),
// ]),
// ),),
// ),
// );
// }),
// )
// ],
// )
// : CircularProgressIndicator();
// },
// ) ,
// )
// // widget.project_id),
// // builder: (context, snapshot){
// // if (snapshot.hasError) print(snapshot.error);
// // return snapshot.hasData
// // ? TaskList(taskP: snapshot.data)
// // : Center(child: CircularProgressIndicator());
// // }),
// )
);
}
}
class TaskList extends StatelessWidget {
final List <Task> task;
TaskList({Key? key, required this.task}) : super(key: key);
@override
Widget build(BuildContext context) {
final taskP= Provider.of<TaskProvider>(context );
// TODO: implement build
return Column(
children: [
Row(
children: const [
Padding(padding: EdgeInsets.all(7),
child: Padding(
padding: EdgeInsets.fromLTRB(24,10,10,8),
child: Text('Project1',
style: TextStyle(
color: Color(0xff076792),
fontSize: 40,
fontWeight: FontWeight.w600
),
),
),
),
],
),
// dynamic list
Expanded(
child: ListView.builder(
itemCount: taskP.task.length ,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.fromLTRB(28, 12, 28, 0),
child: GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => projectDetails()));
},
child: Card(child:Container(padding: const EdgeInsets.fromLTRB(18,8,9,4),
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(19.0),
color: const Color(0xff076792),
boxShadow: const [
BoxShadow(color: Colors.black, spreadRadius: 1),
BoxShadow(color: Color(0xa6A2B6D4),
offset: Offset(7,5),
blurRadius:20),
],
),
child: Column(children: [
Row(mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Starting ' taskP.task[index].start.toString(),style:
const TextStyle(color: Color.fromARGB(255, 133, 186, 202),fontSize: 18,),
),
],
),
const Spacer(),
Row(mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(taskP.task[index].title??'',style:
const TextStyle(color: Colors.white,fontSize: 34,)),
],
),
const Spacer(),
Row(mainAxisAlignment: MainAxisAlignment.end,
children: [
Text('Ending ' taskP.task[index].end.toString(),style:
const TextStyle(color: Color.fromARGB(255, 133, 186, 202),
fontSize: 18,
)),
],
),
]),
),),
),
);
}),
)
],
);
}
}
here the api and model of task
// To parse this JSON data, do
//
// final task = taskFromJson(jsonString);
import 'dart:collection';
import 'dart:core';
import 'package:flutter/foundation.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
//List<Task> taskFromJson(String str) => List<Task>.from(json.decode(str).map((x) => Task.fromJson(x)));
//String taskToJson(List<Task> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Task {
String? url;
int? id;
String? owner;
String? project;
String? title;
DateTime? start;
DateTime? end;
String? desc;
int? project_id;
Task(
{this.url,
this.id,
this.owner,
this.project,
this.title,
this.start,
this.end,
this.desc,
this.project_id});
factory Task.fromJson(Map<String, dynamic> json) => Task(
url :json["url"],
id: json["id"],
owner: json["owner"],
project: json["project"],
title: json["title"],
start: DateTime.parse(json["start"]),
end: DateTime.parse(json["end"]),
desc: json["desc"],
project_id: json["project_id"],
);
Map<String, dynamic> toJson() => {
"url": url,
"id": id,
"owner": owner,
"project": project,
"title": title,
"start": start?.toIso8601String(),
"end": end?.toIso8601String(),
"desc": desc,
"project_id": project_id,
};
}
class TaskProvider with ChangeNotifier{
TaskProvider(){
this.fetchTask();
}
List<Task> _task = [];
List<Task> get task {
return [..._task];
}
void addTask(Task task) async {
final response = await http.post(Uri.parse('http://mostafahamed.pythonanywhere.com/project/task'),
headers: {"Content-Type": "application/json"}, body: json.encode(task));
if (response.statusCode == 201) {
task.id = json.decode(response.body)['id'];
_task.add(task);
notifyListeners();
print('suceeed add ed task');
print(response.body);
}else{
print(response.body);
print('failed add ed task');
}
}
void deleteTask(Task task) async {
final response =
await http.delete(Uri.parse('http://mostafahamed.pythonanywhere.com/project/task${task.id}/'));
if (response.statusCode == 204) {
_task.remove(task);
notifyListeners();
}
}
Future<List<Task>> fetchTask([project_id]) async{
final response = await http
.get(Uri.parse('http://mostafahamed.pythonanywhere.com/tasks/?format=json'));
if (response.statusCode==200){
var data = json.decode(response.body)as List;
_task=data.map<Task>((json) => Task.fromJson(json)).toList();
notifyListeners();
print('sucess view task list');
print(response.body);
return _task;
}
else {
print(response.body);
print(response.statusCode);
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load tasks');
}
}
}
when i click on project wiget the screen keeps loading
CodePudding user response:
I removed a condition && snapshot is List from future builder and it works perfectly but make sure to prevent the use of future builder if you have changeable values as future builder fetch data once I'm right now working to convert future builder into stream builder
if u have the same problem make sure all the types are the same good luck to you all : )