Reputation: 1921
In my flutter application , I have to navigate to other screen on Api success response.
I have a login screen in my app for that I have to call a Post api for user login and on success response of that Api, I want to go on other screen
Below is the code that I have done
import 'package:flutter/material.dart';
import 'package:flutter_login_app/screens/login.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
),
home: Login(),
);
}
}
Code for my Login class
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_login_app/models/LoginApiResponse.dart';
import 'package:flutter_login_app/models/UserLoginModel.dart';
import 'package:flutter_login_app/network/services.dart';
import 'package:flutter_login_app/screens/second_page.dart';
class Login extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new LoginState();
}
}
class LoginState extends State<Login> {
TextEditingController usrNameController = new TextEditingController();
TextEditingController passController = new TextEditingController();
@override
void dispose() {
// Clean up the controller when the widget is disposed.
usrNameController.dispose();
passController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: Text("Login"),
centerTitle: true,
),
body: Align(
alignment: Alignment.center,
child: new Container(
child: new ListView(
children: <Widget>[
new Container(
margin: const EdgeInsets.all(20.0),
child: new Column(
children: <Widget>[
new TextField(
controller: usrNameController,
decoration: new InputDecoration(
hintText: "Enter user name",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
),
),
new Padding(
padding: new EdgeInsets.fromLTRB(0, 20, 0, 0)),
new TextField(
controller: passController,
obscureText: true,
decoration: new InputDecoration(
hintText: "Enter password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
),
),
new Padding(
padding: new EdgeInsets.fromLTRB(0, 20, 0, 0)),
SizedBox(
width: double.infinity,
height: 55,
child: new RaisedButton(
onPressed: () {
_doLogin(context);
},
child: new Text("Login"),
))
],
),
)
],
),
),
));
}
void _doLogin(BuildContext context) {
String username = usrNameController.text;
String password = passController.text;
User user = new User(User_ID: username, Password: password);
ApiService apiService = new ApiService();
print("hello");
Future<LoginApiResponse>loginresponse = apiService.getLogin("Authenticate", body: user.toMap());
print("hello");
FutureBuilder<LoginApiResponse>(
future: loginresponse,
builder: (BuildContext context, AsyncSnapshot<LoginApiResponse> snapshot) {
print("hello");
print(snapshot.data.code);
print(snapshot.data.message);
navigateToSubPage(context);
});
}
Future navigateToSubPage(context) async {
Navigator.push(
context, MaterialPageRoute(builder: (context) => SecondPage()));
}
}
ApiService class code
import 'dart:convert';
import 'dart:io';
import 'package:flutter_login_app/models/LoginApiResponse.dart';
import 'package:http/http.dart' as http;
class ApiService{
String _baseUrl ="http://myloginapi/";
Future<LoginApiResponse>getLogin(String _methodName, {Map body})async{
final response = await http.post(_baseUrl + _methodName,body: body);
//int statusCode = response.statusCode;
if (response.statusCode == 200) {
return LoginApiResponse.fromJson(json.decode(response.body));
}else{
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
}
}
Code for LoginApiResponse
class LoginApiResponse {
String code;
String message;
LoginApiResponse({this.code, this.message});
factory LoginApiResponse.fromJson(Map<String, dynamic>json){
return LoginApiResponse(
code : json['Code'],
message : json['Message']
);
}
Map toMap() {
var map = new Map<String, dynamic>();
map["Code"] = code;
map["Message"] = message;
return map;
}
}
Can someone tell me where I am doing wrong?
Upvotes: 3
Views: 5107
Reputation: 1374
as I can see your getLogin method is a future type. the await and async will handle your future call no need of FutureBuilder
.
void _doLogin(BuildContext context)async {
String username = usrNameController.text;
String password = passController.text;
User user = new User(User_ID: username, Password: password);
ApiService apiService = new ApiService();
print("hello");
final loginresponse =
await apiService.getLogin("Authenticate", body: user.toMap());
if(loginresponse.responce.statusCode!=200){
throw Exception("error")
}
else {
navigateToSubPage(context);
}
}
you need to return the response as well
Future<LoginApiResponse>getLogin(String _methodName, {Map body})async{
final response = await http.post(_baseUrl + _methodName,body: body);
//int statusCode = response.statusCode;
if (response.statusCode == 200) {
return LoginApiResponse.fromJson(json.decode(response.body));
}else{
// If that response was not OK, throw an error.
throw Exception('Failed to load post');
}
return LoginApiResponse(response);
}
class LoginApiResponse {
final Responce response;
LoginApiResponse(this.response);
}
Upvotes: 4