Skip to content

Instantly share code, notes, and snippets.

@esDotDev
Created December 8, 2022 19:51
Show Gist options
  • Save esDotDev/5dc21f50511188e89193f431397339d2 to your computer and use it in GitHub Desktop.
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.
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