Networking & http in flutter

6 mins

6 mins

Ashutosh

Published on Oct 11, 2024

Networking & http in flutter: Deleting Data from the Internet in Flutter

Learn how to effectively delete data from a server in Flutter and update your UI to reflect those changes. This comprehensive guide covers adding the HTTP package, performing delete operations, and handling responses to ensure seamless user experiences
Learn how to effectively delete data from a server in Flutter and update your UI to reflect those changes. This comprehensive guide covers adding the HTTP package, performing delete operations, and handling responses to ensure seamless user experiences

Introduction

In modern applications, the ability to delete data is as crucial as any other CRUD operation. Flutter provides an efficient way to handle data deletion through HTTP requests. In this blog post, we'll guide you through the process of deleting data from a server and reflecting those changes in your Flutter UI.

This recipe covers how to delete data over the internet using the http package.

This recipe uses the following steps:

  1. Add the http package.

  2. Delete data on the server.

  3. Update the screen.

Adding the HTTP Package

Before we begin, ensure you have the http package installed in your Flutter project. If you haven’t added it yet, run the following command:

flutter pub add http

Then, import the package in your Dart file:

import 'package:http/http.dart' as http;

Permissions

Make sure to have the necessary permissions for internet access in your AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />

With the http package and permissions in place, you're ready to make HTTP requests.

Deleting Data from the Server

To delete data from a server, you will use the http.delete() method. For demonstration purposes, we'll use the JSONPlaceholder API to delete an album.

Here’s how you can define a function to perform a delete request:

Future<http.Response> deleteAlbum(int id) {
  return http.delete(
    Uri.parse('https://jsonplaceholder.typicode.com/albums/$id'),
  );
}

In this function, we are making a DELETE request to remove the album with the specified ID.

The http.delete() method returns a Future that contains a Response.

  • Future is a core Dart class for working with async operations. A Future object represents a potential value or error that will be available at some time in the future.

  • The http.Response the class contains the data received from a successful HTTP call.

  • The deleteAlbum() method takes an id argument that is needed to identify the data to be deleted from the server.

Updating the UI After Deletion

After successfully deleting an album, it’s essential to update the UI to reflect this change. To do this, you can manage the state in your Flutter application by using a StatefulWidget. When an album is deleted, the UI should respond accordingly.

For example, you could fetch the updated list of albums or show a message confirming the deletion. Below is a code snippet that demonstrates how to manage the state after deletion:

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Future<List<Album>> _futureAlbums;

  @override
  void initState() {
    super.initState();
    _futureAlbums = fetchAlbums();
  }

  Future<void> deleteAlbumAndRefresh(int id) async {
    await deleteAlbum(id);
    setState(() {
      _futureAlbums = fetchAlbums(); // Refresh the list after deletion
    });
  }
}

Now, when you click on the Delete Data button, the deleteAlbum() method is called and the id you are passing is the id of the data that you retrieved from the internet. This means you are going to delete the same data that you fetched from the internet.

Returning a response from the deleteAlbum() method

It’s important to handle the response of the delete request to ensure that the deletion was successful. You can modify the deleteAlbum function to throw an exception if the deletion fails:

Future<Album> deleteAlbum(String id) async {
  final http.Response response = await http.delete(
    Uri.parse('https://jsonplaceholder.typicode.com/albums/$id'),
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
  );

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then return an empty Album. After deleting,
    // you'll get an empty JSON `{}` response.
    // Don't return `null`, otherwise `snapshot.hasData`
    // will always return false on `FutureBuilder`.
    return Album.empty();
  } else {
    // If the server did not return a "200 OK response",
    // then throw an exception.
    throw Exception('Failed to delete album.');
  }
}

FutureBuilder() now rebuilds when it receives a response. Since the response won't have any data in its body if the request is successful, the Album.fromJson() method creates an instance of the Album object with a default value (null in our case). This behavior can be altered in any way you wish.

That's all! Now you've got a function that deletes the data from the internet.

Complete Example

Now, let's combine all the parts into a complete example that showcases the functionality of deleting data from a server:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class Album {
  final int id;
  final String title;

  const Album({required this.id, required this.title});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      id: json['id'] as int,
      title: json['title'] as String,
    );
  }
}

Future<List<Album>> fetchAlbums() async {
  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/albums'),
  );

  if (response.statusCode == 200) {
    List<dynamic> body = jsonDecode(response.body);
    return body.map((dynamic item) => Album.fromJson(item)).toList();
  } else {
    throw Exception('Failed to load albums');
  }
}

Future<void> deleteAlbum(int id) async {
  final response = await http.delete(
    Uri.parse('https://jsonplaceholder.typicode.com/albums/$id'),
  );

  if (response.statusCode != 200) {
    throw Exception('Failed to delete album.');
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Future<List<Album>> _futureAlbums;

  @override
  void initState() {
    super.initState();
    _futureAlbums = fetchAlbums();
  }

  Future<void> deleteAlbumAndRefresh(int id) async {
    await deleteAlbum(id);
    setState(() {
      _futureAlbums = fetchAlbums(); // Refresh the list after deletion
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Album List')),
      body: FutureBuilder<List<Album>>(
        future: _futureAlbums,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final albums = snapshot.data!;
            return ListView.builder(
              itemCount: albums.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(albums[index].title),
                  trailing: IconButton(
                    icon: const Icon(Icons.delete),
                    onPressed: () {
                      deleteAlbumAndRefresh(albums[index].id);
                    },
                  ),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('${snapshot.error}'));
          }
          return const CircularProgressIndicator();
        },
      ),
    );
  }
}

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

In this complete example, we have a simple app that displays a list of albums fetched from the server. Each album has a delete button, and when pressed, it deletes the corresponding album and refreshes the list to reflect the changes.

Conclusion

In this blog post, we covered how to delete data from a server in Flutter and update the UI accordingly. By leveraging the http package and managing state within a, you can ensure your app remains responsive and user-friendly. Deleting data is a vital part of any application, and with Flutter, it’s straightforward to implement. Happy coding!