Flutter Provider Http Post Request Example With Loading Animation

Flutter Provider Http Post Request Example With Loading Animation

    Previously we use http.get for loading data with Provider State Management

    Here we will see how to use flutter Provider state management to do a http post request. Here we will acheive three things

    1. Load restful api data from server using Provider

    2. Notify the UI about the loaded data using Provider

    3. Redirect the user to a new page using Provider

    Signup model

    flutter provider post request

    The above picture helps us build our data model.

    signup_model.dart

    class SignUpBody{
      String name;
      String phone;
      String email;
      String password;
      SignUpBody({
        required this.name,
        required this.phone,
        required this.email,
        required this.password
      });
    
      Map<String, dynamic> toJson(){
        final Map<String, dynamic> data = <String, dynamic>{};
        data["f_name"] = name;
        data["phone"] = phone;
        data['email'] = email;
        data['password'] = password;
        return data;
      }
    }

    Here we used four fields to build our data model.  We have a constructor which will convert object to Json before we send it to the server.

    Service class

    We need to create service or service class, to post data to the network or server using. We are using a restful api here to do it.

    This service class contains only one method. It's name is regsiter class. Inside this method we call http.post method to send the info from the user and other related network information.

    service_class.dart

    import 'dart:convert';
    import 'dart:developer';
    import 'dart:io';
    import 'package:http/http.dart' as http;
    import 'package:provider_post_request/signup_model.dart';
    
    Future<http.Response?> register(SignUpBody data) async {
      http.Response? response;
      try {
        response =
        await http.post(
            Uri.parse("http://127.0.0.1:8000/api/v1/auth/register"),
            headers: {
              HttpHeaders.contentTypeHeader: "application/json",
            },
            body: jsonEncode(data.toJson()));
      } catch (e) {
        log(e.toString());
      }
      return response;
    }
    

    In the above code http.post takes three parameters

    Uri: for pointing to server and end point

    headers: for protocol and data type

    body: for sending the actual data

    Regardless whatever the response we get back from the server, we just return it and check in DataClass(below). We have use jsonEncode() and toJson() to make sure that we are sending json to the server.

    Data class (Provider)

    This is another important class. Here the state management magic happens. This class extends ChangeNotifier and holds two variables. 

    loading: using this variable we know when the data is loaded. 

    isBack: for a call back function. If statuscode is 200 then we set it to true

    data_class.dart

    import 'package:flutter/cupertino.dart';
    import 'package:http/http.dart' as http;
    import 'package:provider_post_request/service_class.dart';
    import 'package:provider_post_request/signup_model.dart';
    
    class DataClass extends ChangeNotifier {
      bool loading = false;
      bool isBack = false;
      Future<void> postData(SignUpBody body) async {
        loading = true;
        notifyListeners();
        http.Response response = (await register(body))!;
        if (response.statusCode == 200) {
          isBack = true;
    
        }
        loading = false;
        notifyListeners();
      }
    }

    We also used notifyListeners() to let the UI about the changes happened here.

    Provider entry point

    Entry point of this app is main() method. Here we have used MultiProvider since, in future you can multiple providers in your app. Right now you only have one provider(DataClass).

    Code for main.dart

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import 'package:provider_post_request/sing_up.dart';
    
    import 'data_class.dart';
    
    void main() {
      runApp(MultiProvider(providers: [
        ChangeNotifierProvider(create: (_)=>DataClass()),
    
      ],
          child:const MyApp()));
    }
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return
          MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: const ProviderDemoScreen(),
    
          );
      }
    }
    
    class ProviderDemoScreen extends StatefulWidget {
      const ProviderDemoScreen({Key? key}) : super(key: key);
    
      @override
      _ProviderDemoScreenState createState() => _ProviderDemoScreenState();
    }
    
    class _ProviderDemoScreenState extends State<ProviderDemoScreen> {
    
      @override
      Widget build(BuildContext context) {
    
        return Scaffold(
          backgroundColor: Colors.grey[300],
          appBar: AppBar(
            title: const Text("Provider Demo"),
          ),
          body: Center(
            child: GestureDetector(
              onTap: (){
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SignUpPage()),
                );
              },
              child: Center(
                child: Container(
                  height: 70,
                  padding: const EdgeInsets.symmetric(horizontal: 40,vertical: 20),
                  margin: const EdgeInsets.only(left: 40, right: 40),
                  child: const Text("Go to Singup page", style: TextStyle(
                    fontSize: 20,
                    color: Color(0xFF74beef),
                  ),),
                  decoration: BoxDecoration(
                      color: Colors.grey[300],
                      borderRadius: BorderRadius.circular(15),
                      boxShadow: const [
                        BoxShadow(
                          color: Colors.grey,
                          offset: Offset(4, 4),
                          blurRadius: 15,
                          spreadRadius: 1,
                        ),
                        BoxShadow(
                          color: Colors.white,
                          offset: Offset(-4, -4),
                          blurRadius: 15,
                          spreadRadius: 1,
                        ),
    
                      ]
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    

     

    Signup page using provider

    Sign up page get the provider using Provider.of<DataClass>(context, listen:false). Once you have the provider instance, you can retreive the provider properties(loading and isBack).

    Inside sign up page, the register() method gets the provider instance and access the properties.

    Here we also call the postData method by sending the object, which triggers a call to the server. Before we can send the data through the postData() method, created an object using SignUpBody model class.

    The posting animation also gets starter inside this class. Based on boolean loading

    It changes it states from false->true->false

    This is where provider notifies the consumer(UI) that, the app internal state has been changed.

    sign_up.dart

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/gestures.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_spinkit/flutter_spinkit.dart';
    import 'package:provider/provider.dart';
    import 'package:provider_post_request/signup_model.dart';
    
    import 'app_text_field.dart';
    import 'data_class.dart';
    import 'home_page.dart';
    
    class SignUpPage extends StatelessWidget {
      const SignUpPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        var emailController = TextEditingController();
        var passwordController = TextEditingController();
        var nameController = TextEditingController();
        var phoneController = TextEditingController();
    
        Future<void> _registration() async {
          String name = nameController.text.trim();
          String phone = phoneController.text.trim();
          String email = emailController.text.trim();
          String password = passwordController.text.trim();
          SignUpBody signUpBody = SignUpBody(
              name: name, phone: phone, email: email, password: password);
          var provider = Provider.of<DataClass>(context, listen: false);
          await provider.postData(signUpBody);
          if (provider.isBack) {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) =>  HomePage()),
            );
          }
        }
    
        return Scaffold(
            backgroundColor: Colors.grey[300],
            body: Consumer<DataClass>(builder: (context, data, child) {
              return data.loading
                  ? Center(
                child: Container(
                  child: SpinKitThreeBounce(
                    itemBuilder: (BuildContext context, int index) {
                      return DecoratedBox(
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(15),
                          color: index.isEven ? Colors.red : Colors.green,
                        ),
                      );
                    },
                  ),
                ),
              )
                  : SingleChildScrollView(
                physics: BouncingScrollPhysics(),
                child: Column(
                  children: [
                    SizedBox(height: 100),
                    //app logo
                    Container(
                        height: 100,
                        child: Center(
                          child: CircleAvatar(
                            backgroundColor: Colors.grey[300],
                            radius: 80,
                          ),
                        )),
                    //your email
                    AppTextField(
                        textController: emailController,
                        hintText: "Email",
                        icon: Icons.email),
                    const SizedBox(
                      height: 20,
                    ),
                    //your password
                    AppTextField(
                        textController: passwordController,
                        hintText: "Password",
                        icon: Icons.password_sharp,
                        isObscure: true),
                    SizedBox(
                      height: 20,
                    ),
                    //your name
                    AppTextField(
                        textController: nameController,
                        hintText: "Name",
                        icon: Icons.person),
                    SizedBox(
                      height: 20,
                    ),
                    //your phone
                    AppTextField(
                        textController: phoneController,
                        hintText: "Phone",
                        icon: Icons.phone),
                    SizedBox(
                      height: 20 + 20,
                    ),
                    //sign up button
                    GestureDetector(
                      onTap: () {
                        _registration();
                      },
                      child: Container(
                        height: 70,
                        padding: const EdgeInsets.symmetric(
                            horizontal: 40, vertical: 23),
                        margin: const EdgeInsets.only(left: 40, right: 40),
                        child: const Text(
                          "Sign up",
                          style: TextStyle(
                            fontSize: 20,
                            color: Color(0xFF74beef),
                          ),
                        ),
                        decoration: BoxDecoration(
                            color: Colors.grey[300],
                            borderRadius: BorderRadius.circular(15),
                            boxShadow: const [
                              BoxShadow(
                                color: Colors.grey,
                                offset: Offset(4, 4),
                                blurRadius: 15,
                                spreadRadius: 1,
                              ),
                              BoxShadow(
                                color: Colors.white,
                                offset: Offset(-4, -4),
                                blurRadius: 15,
                                spreadRadius: 1,
                              ),
                            ]),
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    //tag line
                    RichText(
                        text: TextSpan(
                            text: "Have an account already?",
                            style: TextStyle(
                                color: Colors.grey[500], fontSize: 20))),
                    SizedBox(
                      height: MediaQuery.of(context).size.height * 0.05,
                    ),
                    //sign up options
                    RichText(
                        text: TextSpan(
                            text:
                            "Sign up using one of the following methods",
                            style: TextStyle(
                                color: Colors.grey[500], fontSize: 16))),
                  ],
                ),
              );
            }));
      }
    }
    

     

    Code for app text field

    app_text_field.dart

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class AppTextField extends StatelessWidget {
      final TextEditingController textController;
      final String hintText;
      final IconData icon;
      bool isObscure;
      AppTextField({Key? key,
    
        required this.textController,
        required this.hintText,
        required this.icon,
        this.isObscure=false}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Container(
    
          margin:EdgeInsets.only(left: 20, right: 20),
          decoration: BoxDecoration(
              color: Colors.grey[300],
              borderRadius: BorderRadius.circular(15),
              boxShadow: [
                const BoxShadow(
                  color: Colors.grey,
                  offset: Offset(4, 4),
                  blurRadius: 15,
                  spreadRadius: 1,
                ),
                const BoxShadow(
                  color: Colors.white,
                  offset: Offset(-4, -4),
                  blurRadius: 15,
                  spreadRadius: 1,
                ),
    
              ]
          ),
          child: TextField(
            obscureText: isObscure?true:false,
            controller: textController,
            decoration: InputDecoration(
                fillColor: Colors.grey[300],
                filled: true,
                //hintText,
                hintText: hintText,
                // prefixIcon
                prefixIcon: Icon(icon, color:Colors.yellow),
                //focusedBorder
                focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(15),
                    borderSide: const BorderSide(
                      width: 0.0,
                      color:Colors.white,
                    )
                ),
                //enabled Border
                enabledBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(15),
                    borderSide: const BorderSide(
                      width: 0.0,
                      color:Colors.white,
                    )
                ),
                // enabledBorder
                //
                // border
                border:OutlineInputBorder(
                  borderRadius: BorderRadius.circular(15),
    
                )
            ),
          ),
        );
      }
    }
    

     

    Code for home page

    home_page.dart

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.grey[300],
          appBar: AppBar(
            title: Text("Provider Demo"),
          ),
          body: Center(
            child: GestureDetector(
    
              child: Center(
                child: Container(
                  height: 70,
                  padding: const EdgeInsets.symmetric(horizontal: 40,vertical: 20),
                  margin: const EdgeInsets.only(left: 40, right: 40),
                  child: const Center(
                    child: Text("Home page", style: TextStyle(
                      fontSize: 20,
                      color: Color(0xFF74beef),
                    ),),
                  ),
                  decoration: BoxDecoration(
                      color: Colors.grey[300],
                      borderRadius: BorderRadius.circular(15),
                      boxShadow: const [
                        BoxShadow(
                          color: Colors.grey,
                          offset: Offset(4, 4),
                          blurRadius: 15,
                          spreadRadius: 1,
                        ),
                        BoxShadow(
                          color: Colors.white,
                          offset: Offset(-4, -4),
                          blurRadius: 15,
                          spreadRadius: 1,
                        ),
    
                      ]
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }
    

    Courses


    Recent posts