In this blog, we will implement How to api call in flutter using getx with example step by step in 2024.
Using this code you can easily create simple getx post api call in flutter with example, easily learn and use this code step by step in your android studio.
How to Login Api Call in Flutter using Getx Step by Step in 2024
Step 1 : Add some important dependencies in your "pubspec.yaml" File - See Below Snippet.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
http: ^1.2.1
get: ^4.6.6
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
http: ^1.2.1
get: ^4.6.6
-> Here we added two dependencies :
"http: ^1.2.1" -> For networking purpose use.
"get: ^4.6.6" -> for Getx purpose generally use for state management and getx pre defined utilities.
Step 2 : Create "main.dart" File in your Lib folder.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'login_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: const TextTheme(
headlineLarge: TextStyle(
color: Colors.white, fontSize: 25, fontFamily: 'MainFont'),
headlineMedium: TextStyle(color: Colors.black, fontSize: 20),
titleMedium: TextStyle(color: Colors.red, fontSize: 16),
),
useMaterial3: true,
),
home: const LoginScreen(),
);
}
}
import 'package:get/get.dart';
import 'login_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: const TextTheme(
headlineLarge: TextStyle(
color: Colors.white, fontSize: 25, fontFamily: 'MainFont'),
headlineMedium: TextStyle(color: Colors.black, fontSize: 20),
titleMedium: TextStyle(color: Colors.red, fontSize: 16),
),
useMaterial3: true,
),
home: const LoginScreen(),
);
}
}
Imp Note:
-> Remember when your using Getx state management then you should replace "MaterialApp" to "GetMaterialApp" as above you can see in "build overrided method" i have used "GetMaterialApp" instead to "MaterialApp" so this is very important if you forgot to use this then you don't have to use Getx features it will getting issue on runtime.
-> Call "LoginScreen()" dart file on home section here that means once your application open then login screen directly appears in your app.
Step 3 : Create "api_end_points.dart" File in your Lib folder.
-> Create this file because we are use all api "base url" and "end points" inside separate class this is good practice for example if some other developer work in same project he or she can easily find any api ends point in this separate class.
class ApiEndPoints {
static const String baseUrl = 'https://reqres.in/';
static _AuthEndPoints authEndpoints = _AuthEndPoints();
}
class _AuthEndPoints {
final String loginApi = 'api/login';
}
static const String baseUrl = 'https://reqres.in/';
static _AuthEndPoints authEndpoints = _AuthEndPoints();
}
class _AuthEndPoints {
final String loginApi = 'api/login';
}
Step 4 : Create "login_controller.dart" File in your Lib folder.
-> Create this file because here we are implementing all business logic and api calls and always you should separate business logic from view because code is robust, scalable, reusable and less load in main thread with the help of "controller" or "viewModel" class.
import 'dart:convert';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:my_test_app/home_page.dart';
import 'api_end_points.dart';
import 'package:flutter/material.dart';
class LoginController extends GetxController {
final emailController = TextEditingController().obs;
final passwordController = TextEditingController().obs;
RxBool isLoading = false.obs;
Future<void> loginApi() async {
isLoading.value = true;
try {
var url =
Uri.parse(ApiEndPoints.baseUrl + ApiEndPoints.authEndpoints.loginApi);
Map body = {
'email': emailController.value.text,
'password': passwordController.value.text
};
http.Response response = await http.post(url, body: body);
var data = jsonDecode(response.body);
if (response.statusCode == 200) {
isLoading.value = false;
Get.to(const HomePage());
Get.snackbar(
'Congratulation',
'Login Successfully',
snackPosition: SnackPosition.BOTTOM,
forwardAnimationCurve: Curves.elasticInOut,
reverseAnimationCurve: Curves.easeOut,
);
emailController.value.clear();
passwordController.value.clear();
} else {
isLoading.value = false;
Get.snackbar(
'Login Failed',
data['error'],
snackPosition: SnackPosition.BOTTOM,
forwardAnimationCurve: Curves.elasticInOut,
reverseAnimationCurve: Curves.easeOut,
);
}
} catch (error) {
isLoading.value = false;
Get.snackbar(
'Exception',
error.toString(),
snackPosition: SnackPosition.BOTTOM,
forwardAnimationCurve: Curves.elasticInOut,
reverseAnimationCurve: Curves.easeOut,
);
}
}
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:my_test_app/home_page.dart';
import 'api_end_points.dart';
import 'package:flutter/material.dart';
class LoginController extends GetxController {
final emailController = TextEditingController().obs;
final passwordController = TextEditingController().obs;
RxBool isLoading = false.obs;
Future<void> loginApi() async {
isLoading.value = true;
try {
var url =
Uri.parse(ApiEndPoints.baseUrl + ApiEndPoints.authEndpoints.loginApi);
Map body = {
'email': emailController.value.text,
'password': passwordController.value.text
};
http.Response response = await http.post(url, body: body);
var data = jsonDecode(response.body);
if (response.statusCode == 200) {
isLoading.value = false;
Get.to(const HomePage());
Get.snackbar(
'Congratulation',
'Login Successfully',
snackPosition: SnackPosition.BOTTOM,
forwardAnimationCurve: Curves.elasticInOut,
reverseAnimationCurve: Curves.easeOut,
);
emailController.value.clear();
passwordController.value.clear();
} else {
isLoading.value = false;
Get.snackbar(
'Login Failed',
data['error'],
snackPosition: SnackPosition.BOTTOM,
forwardAnimationCurve: Curves.elasticInOut,
reverseAnimationCurve: Curves.easeOut,
);
}
} catch (error) {
isLoading.value = false;
Get.snackbar(
'Exception',
error.toString(),
snackPosition: SnackPosition.BOTTOM,
forwardAnimationCurve: Curves.elasticInOut,
reverseAnimationCurve: Curves.easeOut,
);
}
}
}
-> Here i have used getx "obs" is observables just observe the changes in view controller and updated to "Obx" then "Obx" update the view.
-> I have used here to pass direct body inside "http.Response" because my post api is accept in "form data" and if your post api accept in "raw data" instead of "form data" then you should use "jsonEncode(body)" inside "body" parameter.
-> I have used "Get.to(const HomePage())" this is getx features it is used for navigate one screen to another screen but this is keep your back stack when you click back from your next screen then come back to this screen if you don't want to keep back stack while navigating then you should use "Get.offAll(const HomePage())" now your all back stack is cleared.
-> I have used "Get.snackbar" this is also getx features it is used for show notification with title or message form on runtime.
Step 5 : Create Final "login_screen.dart" File in your Lib folder (Complete Code).
-> Now create login design as well as api call.
-> I have used proper validation with api call in this screen.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:my_test_app/login_controller.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
LoginController loginController = Get.put(LoginController());
bool passToggle = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String? validateEmail(String? email) {
if (email!.isEmpty) {
return 'Can\'t be empty';
}
if (email.length < 4) {
return 'Too short';
}
if (!RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(email)) {
return 'Invalid Email Id';
}
// return null if the text is valid
return null;
}
String? validatePassword(String? password) {
if (password!.isEmpty) {
return 'Can\'t be empty';
}
if (password.length < 6) {
return 'Password should not less than 6 digit';
}
// return null if the text is valid
return null;
}
void _submit() {
import 'package:get/get.dart';
import 'package:my_test_app/login_controller.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
LoginController loginController = Get.put(LoginController());
bool passToggle = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String? validateEmail(String? email) {
if (email!.isEmpty) {
return 'Can\'t be empty';
}
if (email.length < 4) {
return 'Too short';
}
if (!RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(email)) {
return 'Invalid Email Id';
}
// return null if the text is valid
return null;
}
String? validatePassword(String? password) {
if (password!.isEmpty) {
return 'Can\'t be empty';
}
if (password.length < 6) {
return 'Password should not less than 6 digit';
}
// return null if the text is valid
return null;
}
void _submit() {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
//here call login api after successfull validation...
loginController.loginApi();
}
}
_formKey.currentState!.save();
//here call login api after successfull validation...
loginController.loginApi();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: const Text("Login Page"),
),
body: SingleChildScrollView(
padding: const EdgeInsets.only(top: 120.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Center(
child: SizedBox(
width: 200,
height: 150,
child: Image.asset('assets/images/boy.png')),
),
Padding(
padding: const EdgeInsets.only(
top: 15.0, bottom: 5.0, left: 30.0, right: 30.0),
child: TextFormField(
controller: loginController.emailController.value,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
prefixIcon: Icon(Icons.email),
hintText: 'Enter valid email id',
),
validator: validateEmail,
autovalidateMode: AutovalidateMode.onUserInteraction,
),
),
Padding(
padding: const EdgeInsets.only(
left: 30.0, right: 30.0, top: 15, bottom: 10),
child: TextFormField(
controller: loginController.passwordController.value,
obscureText: passToggle,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter secure password',
prefixIcon: const Icon(Icons.lock),
suffixIcon: InkWell(
onTap: () {
setState(() {
passToggle = !passToggle;
});
},
child: Icon(
passToggle ? Icons.visibility : Icons.visibility_off),
),
),
validator: validatePassword,
autovalidateMode: AutovalidateMode.onUserInteraction,
),
),
Container(
alignment: Alignment.topRight,
padding: const EdgeInsets.only(right: 18.0),
child: TextButton(
onPressed: () {},
child: const Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
),
Obx(() {
return loginController.isLoading.value
? const CircularProgressIndicator()
: Container(
width: 350.0,
height: 70,
padding: const EdgeInsets.only(
left: 30.0, right: 30.0, top: 10.0, bottom: 10.0),
child: FilledButton(
onPressed: _submit,
child: const Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 22),
),
),
);
}),
TextButton(
onPressed: () {},
child: const Text(
'New User? Create Account',
style: TextStyle(color: Colors.black, fontSize: 15),
),
)
],
),
),
),
);
}
}
-> Here i have used "Obx" and wrap inside login button code because "Obx" is observe the changes of "obs" and "obs" is attached in view controller (email and password TextInput Field) just observe the view controller real time changes and pass to "Obx" and "Obx" update the view - here with help of "Obx" or controller i have implement loading logic like if "isLoading" is true then show "Circular Progress Indicator" otherwise if "isLoading" is false then show login button.
Step 6 : Create Final Screen "home_page.dart" File in your Lib folder.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: Center(
child: SizedBox(
height: 60,
width: 350,
child: FilledButton(
onPressed: () {
Get.back();
},
child: const Text(
'Welcome',
style: TextStyle(color: Colors.white, fontSize: 22),
),
),
),
),
);
}
}
import 'package:get/get.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: Center(
child: SizedBox(
height: 60,
width: 350,
child: FilledButton(
onPressed: () {
Get.back();
},
child: const Text(
'Welcome',
style: TextStyle(color: Colors.white, fontSize: 22),
),
),
),
),
);
}
}
-> Here i have used "Get.back()" this is getx features it is used for navigate to your back screen.
-> This "home_page.dart" is call in "login_controller.dart" file for navigate login to home screen after successfully api call.
Reference
Here are the reference blog of complete tutorial of How to api call in flutter using getx step by step in 2024 you can easily learn and use in your code and below i have attached video if you guys want to learn more then watch below video thank you for your support.
Conclusion
In this blog i have shown you How to api call in flutter using getx step by step in 2024. you can easily use this code and modify according to your need.