Created
December 8, 2022 19:51
-
-
Save esDotDev/5dc21f50511188e89193f431397339d2 to your computer and use it in GitHub Desktop.
Write a TODO app in FLutter using a Rest API to read and write data. Encapsulate business logic in a dedicated controller class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Write a TODO app in FLutter using a Rest API to read and write data. Encapsulate business logic in a dedicated controller class. | |
//Imports | |
import 'package:flutter/material.dart'; | |
import 'package:http/http.dart' as http; | |
import 'dart:convert'; | |
//Todo Controller class | |
class TodoController { | |
//Get all todos | |
Future<List> getTodos() async { | |
final response = await http.get('https://my-json-server.typicode.com/user/todos'); | |
if (response.statusCode == 200) { | |
List todos = json.decode(response.body); | |
return todos; | |
} else { | |
throw Exception('Failed to load todos'); | |
} | |
} | |
//Create a new todo | |
Future<bool> createTodo(String title) async { | |
Map<String, String> body = {'title': title}; | |
final response = await http.post('https://my-json-server.typicode.com/user/todos', body: body); | |
if (response.statusCode == 201) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
//Update a todo | |
Future<bool> updateTodo(int id, String title) async { | |
Map<String, String> body = {'title': title}; | |
final response = await http.put('https://my-json-server.typicode.com/user/todos/$id', body: body); | |
if (response.statusCode == 200) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
//Delete a todo | |
Future<bool> deleteTodo(int id) async { | |
final response = await http.delete('https://my-json-server.typicode.com/user/todos/$id'); | |
if (response.statusCode == 200) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
} | |
//Todo Model class | |
class Todo { | |
int id; | |
String title; | |
bool completed; | |
Todo({this.id, this.title, this.completed}); | |
factory Todo.fromJson(Map<String, dynamic> json) { | |
return Todo( | |
id: json['id'], | |
title: json['title'], | |
completed: json['completed'], | |
); | |
} | |
} | |
//Todo App class | |
class TodoApp extends StatefulWidget { | |
@override | |
_TodoAppState createState() => _TodoAppState(); | |
} | |
class _TodoAppState extends State<TodoApp> { | |
List<Todo> _todos = []; | |
TextEditingController _textController = TextEditingController(); | |
TodoController _todoController = TodoController(); | |
@override | |
void initState() { | |
super.initState(); | |
_loadTodos(); | |
} | |
_loadTodos() async { | |
List todos = await _todoController.getTodos(); | |
setState(() { | |
_todos = todos.map((todo) => Todo.fromJson(todo)).toList(); | |
}); | |
} | |
_createTodo() async { | |
String title = _textController.text; | |
bool success = await _todoController.createTodo(title); | |
if (success) { | |
_textController.clear(); | |
_loadTodos(); | |
} | |
} | |
_updateTodo(int id, String title) async { | |
bool success = await _todoController.updateTodo(id, title); | |
if (success) { | |
_loadTodos(); | |
} | |
} | |
_deleteTodo(int id) async { | |
bool success = await _todoController.deleteTodo(id); | |
if (success) { | |
_loadTodos(); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text('Todo App'), | |
), | |
body: Column( | |
children: <Widget>[ | |
Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: TextField( | |
controller: _textController, | |
decoration: InputDecoration( | |
hintText: 'Enter a todo...' | |
), | |
), | |
), | |
RaisedButton( | |
onPressed: _createTodo, | |
child: Text('Add Todo'), | |
), | |
Expanded( | |
child: ListView.builder( | |
itemCount: _todos.length, | |
itemBuilder: (BuildContext context, int index) { | |
Todo todo = _todos[index]; | |
return ListTile( | |
title: Text(todo.title), | |
trailing: Row( | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
IconButton( | |
icon: Icon(Icons.edit), | |
onPressed: () { | |
_showEditDialog(todo); | |
}, | |
), | |
IconButton( | |
icon: Icon(Icons.delete), | |
onPressed: () { | |
_deleteTodo(todo.id); | |
}, | |
), | |
], | |
), | |
); | |
}, | |
), | |
), | |
], | |
), | |
); | |
} | |
_showEditDialog(Todo todo) { | |
TextEditingController controller = TextEditingController(text: todo.title); | |
showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
return AlertDialog( | |
title: Text('Edit Todo'), | |
content: TextField( | |
controller: controller, | |
decoration: InputDecoration( | |
hintText: 'Enter a todo...' | |
), | |
), | |
actions: <Widget>[ | |
FlatButton( | |
child: Text('Cancel'), | |
onPressed: () { | |
Navigator.of(context).pop(); | |
}, | |
), | |
FlatButton( | |
child: Text('Save'), | |
onPressed: () { | |
_updateTodo(todo.id, controller.text); | |
Navigator.of(context).pop(); | |
}, | |
), | |
], | |
); | |
} | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment