In Mobile App Development, interacting with the RESTful APIs is a very common requirement. In this article, we are going to discuss how to handle HTTP post Requests in Flutter using Provider as the state management.

HTTP POST method allows you to send the data to a server and create new resources which can be users, posts, etc.

What is State Management?

State management is a crucial aspect of Flutter app development. It allows you to efficiently manage and update the data of the application and UI. In a typical application, the state refers to the current values and conditions of various variables, objects, and UI components. This can include user input, application settings, API responses, and other data that can change over time.

What is Provider?

Provider is one of the most popular state management solutions in Flutter. It offers a simple and flexible way to handle state across the entire application.

Alright Now let’s dive into the project.

Step 1: Adding Dependencies

In this project, we shall be using two packages to make the HTTP request and the other is for state management.

dependencies:
  //other dependencies
  provider: ^6.0.5
  http: ^1.1.0

Step 2: API endpoint

In this project, we are going to use the endpoint from reqres.in . Now create a new file named app_urls.dart where all the endpoints of the applications are placed.

 class AppUrls{
   static String BASE_URL="https://reqres.in/api/";
   static String loginUrl=BASE_URL+"register";
}

Step 3: Create Model

Models serve as a representation of data entities within an application. They define the structure, attributes, and behavior of the data, allowing developers to work with and manipulate it in a structured manner. It is also useful for data validation and type safety.

Create a new file named register_response.dart inside lib folder.

class RegisterResponse {
  int? id;
  String? token;
  String? error;

  RegisterResponse({this.id, this.token, this.error});

  RegisterResponse.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    token = json['token'];
    error = json['error'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['token'] = token;
    data['error'] = error;
    return data;
  }
}

Step 4: Define Provider Class(handle HTTP post Requests)

This is the place we are going to apply our request to the server. Create a file named register_provider.dart .

class RegisterProvider with ChangeNotifier {}

ChangeNotifier consists of a method named notifyListeners() that triggers a notification to all registered listeners when the state changes. It is essential to call notifyListeners() after modifying the state to inform the listeners to update the UI.

Inside it, we create a method to call post requests.

loginUser(String email, String password) async {
    isLoading = true;
    notifyListeners();
    final Map<String, dynamic> loginData = {
      "email": email.trim(),
      "password": password.trim(),
    };
    return await post(Uri.parse(AppUrls.loginUrl),
        body: jsonEncode(loginData),
        headers: {
          'Content-Type': 'application/json',
        }).then(onValue).catchError(onError);
  }

Above you can see the method loginUser is accepting two parameters, email, and password. Also, there is an isLoading state which gets triggered to true when this method is called. Then, there is notifyListeners() what now triggers the UI that the isLoading value is set to true. Now, we are mapping the key and value i.e. our data that needs to be sent to the server. And finally, we call the post method to the endpoint with the items to the body with the header.

Now after getting the response to the post, then(onValue) is triggered. If there is an error catchError(onError) is triggered.

Let’s start with success

 Future<FutureOr> onValue(Response response) async {
    String? result;

    final Map<String, dynamic> responseData = json.decode(response.body);
    loginResponse = RegisterResponse.fromJson(responseData);

    _statusCode = response.statusCode;
    if (response.statusCode == 200) {
      result = loginResponse.token;
      isLoading = false;
    } else {
      result = loginResponse.error;
      isLoading = false;
    }

    notifyListeners();
    return result;
  }

This method returns the response, which is of String data type as of now. This can be different as per your API response.

And if there is some problem making the request

onError(error) async {
    return error;
  }

Step 5: Call request from UI

Create a new file named register_screen.dart.

After all this, first, we need to initialize the Provider inside the build method.

@override
  Widget build(BuildContext context) {
    final registerProvider = Provider.of<RegisterProvider>(context);
}

Now, we make the method call when the button is clicked.

ElevatedButton(
                    onPressed: () {
                     final loginResponse = registerProvider.loginUser(
                            emailController.text, passwordController.text);                     

                   }
child:// code
)

After getting the loginResponse we check if the response is Ok or not. If the response is Ok or the status code is 200 we show the Snackbar with the Id and the token. If not we show the Snackbar with the message Failed.

loginResponse.then((response) {
                          if (registerProvider.statusCode == 200) {
                            ScaffoldMessenger.of(context).showSnackBar(
                              SnackBar(
                                content: Text(
                                    'Token: ${registerProvider.loginResponse.token!}  Id: ${registerProvider.loginResponse.id.toString()}'),
                              ),
                            );
                          } else {
                            ScaffoldMessenger.of(context).showSnackBar(
                              const SnackBar(
                                content: Text("Registration Failed"),
                              ),
                            );
                          }
                        });

And to show the loading indicator when the request is being made, we listen to the isLoading value.

ElevatedButton(
onPressed:(){
//code here
},
child: registerProvider.isLoading
                        ? const CircularProgressIndicator(
                            color: Colors.white,
                          )
                        : const Text(
                            'Register',
                            style: TextStyle(fontSize: 16),
                          ),
                  )

Conclusion

Here you learned how to handle HTTP post Requests in Flutter with Provider state management. Provider is one of the common state management in Flutter. You can play around with the code and you can use it as the base for using Provider as the state management.

Thanks for reading this article.

Also, follow to get updated on exciting articles and projects.

If I got something wrong? Let me know in the comments. I would love to improve.

Full Code:

https://github.com/nbnD/provider_post_data

Let’s get connected

We can be friends. Find on FacebookLinkedinGithubYouTube

BuyMeACoffee, and Instagram.

Contribute: BuyMeACoffee

ContactContact Us

Leave a Reply

Your email address will not be published. Required fields are marked *

handle HTTP post Requests