Search code examples
flutterdartdio

How to navigate to different screen on success response in flutter using dio


I'm trying to navigate to other screen after success response using dio. but i'm having an error, and still stack at login.

I'm still starting with flutter.

here's my login page

import 'dart:ui';
import 'package:app/utils/api_provider.dart';
import 'package:flutter_signin_button/button_list.dart';
import 'package:flutter_signin_button/button_view.dart';
import 'package:app/utils/Strings.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:app/screens/signupscreen.dart';

import 'home_screen.dart';

class Loginscreen extends StatefulWidget {
  @override
  _LoginscreenState createState() => _LoginscreenState();
}

class _LoginscreenState extends State<Loginscreen> {
  String loginUrl = Africapital.login_url;
  String msgError = "";

  TextEditingController _usernameee = new TextEditingController();
  TextEditingController _password = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: SingleChildScrollView(
        child: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
                colors: [Colors.white, Colors.white],
                begin: Alignment.bottomLeft,
                end: Alignment.topLeft),
          ),
          child: Center(
            child: Column(
              children: <Widget>[
                SizedBox(
                  height: 50,
                ),
                new Container(
                  alignment: Alignment.center,
                  height: 100,
                  width: 100,
                  margin: EdgeInsets.only(
                    left: 40.0,
                  ),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(100),
                    color: Colors.white60,
                    boxShadow: [
                      BoxShadow(color: Colors.white60, spreadRadius: 5),
                    ],
                    image: DecorationImage(
                      image: AssetImage('assets/images/44.jpg'),
                      fit: BoxFit.contain,
                    ),
                  ),
                ),
                SizedBox(
                  height: 15,
                ),
                Center(
                  child: Text(msgError,
                      style: TextStyle(
                          color: Colors.red,
                          fontWeight: FontWeight.bold,
                          fontSize: 20)),
                ),
                SizedBox(
                  height: 5,
                ),
                Container(
                  alignment: Alignment(-0.90, 0.90),
                  margin: const EdgeInsets.only(left: 20.0, right: 20.0),
                  child: Text(
                    'Sign in with your account',
                    style: TextStyle(
                        color: Colors.black54,
                        fontSize: 16,
                        fontWeight: FontWeight.w500),
                  ),
                ),
                SizedBox(
                  height: 20.0,
                ),
                Container(
                  alignment: Alignment.center,
                  margin: const EdgeInsets.only(left: 20.0, right: 20.0),
                  padding: const EdgeInsets.only(left: 1, right: 1),
                  child: TextField(
                    controller: _usernameee,
                    cursorColor: Colors.indigoAccent,
                    style: TextStyle(color: Color(0xFF1a60be)),
                    decoration: new InputDecoration(
                      contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
                      labelText: '      Email',
                      focusedBorder: OutlineInputBorder(
                        borderSide:
                            BorderSide(color: Color(0xFF1a60be), width: 2.0),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderSide:
                            BorderSide(color: Colors.black38, width: 1.0),
                      ),
                      hintText: '      email@email.com',
                      hintStyle: TextStyle(
                          fontSize: 15,
                          letterSpacing: 1.5,
                          color: Color(0xFF1a60be),
                          fontWeight: FontWeight.w900),
                      filled: true,
                      hoverColor: Colors.black,
                      focusColor: Colors.transparent,
                      fillColor: Colors.white.withOpacity(0.3),
                      border: OutlineInputBorder(
                        borderSide: BorderSide(color: Colors.white38),
                        borderRadius: BorderRadius.circular(10),
                      ),
                    ),
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                Container(
                  alignment: Alignment.center,
                  margin: const EdgeInsets.only(left: 20.0, right: 20.0),
                  padding: const EdgeInsets.only(left: 1, right: 1),
                  child: TextField(
                    controller: _password,
                    obscureText: true,
                    cursorColor: Colors.indigoAccent,
                    style: TextStyle(color: Color(0xFF1a60be)),
                    decoration: new InputDecoration(
                      labelText: '      Password',
                      contentPadding: const EdgeInsets.symmetric(vertical: 5.0),
                      focusedBorder: OutlineInputBorder(
                        borderSide:
                            BorderSide(color: Color(0xFF1a60be), width: 2.0),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderSide:
                            BorderSide(color: Colors.black38, width: 1.0),
                      ),
                      hintText: '    ••••••••',
                      hintStyle: TextStyle(
                          fontSize: 25,
                          letterSpacing: 2.5,
                          color: Color(0xFF1a60be),
                          fontWeight: FontWeight.w900),
                      filled: true,
                      hoverColor: Colors.black,
                      focusColor: Colors.transparent,
                      fillColor: Colors.white.withOpacity(0.3),
                      border: OutlineInputBorder(
                        borderSide: BorderSide(color: Colors.white38),
                        borderRadius: BorderRadius.circular(10),
                      ),
                    ),
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    GestureDetector(
                      onTap: () {},
                      child: Container(
                        child: Text(
                          'Forgot Password?',
                          style: TextStyle(
                              color: Colors.black, fontWeight: FontWeight.w700),
                        ),
                      ),
                    ),
                    SizedBox(
                      width: 40,
                    )
                  ],
                ),
                SizedBox(
                  height: 20,
                ),
                Padding(
                  padding: const EdgeInsets.only(left: 25, right: 25),
                  child: ButtonTheme(
                      buttonColor: Color(0xFF3fc99c),
                      minWidth: MediaQuery.of(context).size.width,
                      height: 45,
                      child: RaisedButton(
                        onPressed: () {
                          _doLogin(context);
                        },
                        child: Text(
                          'Continue',
                          style: TextStyle(color: Colors.white, fontSize: 22),
                        ),
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(5)),
                      )),
                ),
                SizedBox(
                  height: 20,
                ),
                Align(
                  alignment: Alignment(-0.80, 0.90),
                  child: Text(
                    'Or Continue with',
                    style: TextStyle(
                        color: Colors.black54,
                        fontSize: 16,
                        fontWeight: FontWeight.w800),
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                Container(
                  width: MediaQuery.of(context).size.width,
                  height: 45,
                  margin: const EdgeInsets.only(left: 25, right: 25),
                  child: SignInButton(
                    Buttons.Google,
                    onPressed: () {},
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                Container(
                  width: MediaQuery.of(context).size.width,
                  height: 45,
                  margin: const EdgeInsets.only(left: 25, right: 25),
                  child: SignInButton(
                    Buttons.Facebook,
                    onPressed: () {},
                  ),
                ),
                SizedBox(
                  height: 25,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(
                      "Don't Have an Account?",
                      style: TextStyle(
                          color: Colors.black87,
                          fontSize: 14,
                          fontWeight: FontWeight.w400),
                    ),
                    SizedBox(
                      width: 10,
                    ),
                    GestureDetector(
                      onTap: () {
                        Navigator.push(context,
                            MaterialPageRoute(builder: (ctx) => Signscreen()));
                      },
                      child: Text(
                        'Sign up',
                        style: TextStyle(
                          decoration: TextDecoration.underline,
                          fontWeight: FontWeight.w800,
                          fontSize: 18,
                          color: Colors.black,
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 40,
                    ),
                  ],
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  void _doLogin(BuildContext context) async {
    String usernameee = _usernameee.text;
    String password = _password.text;
    ApiProvider apiService = new ApiProvider();
    print("hello");
    final loginresponse =
        await apiService.getLogin(uname: usernameee, passcode: password);
    if (loginresponse.response.data != 200) {
      throw Exception("error");
    } else {
      navigateToSubPage(context);
    }
  }

  Future navigateToSubPage(context) async {
    Navigator.push(
        context, MaterialPageRoute(builder: (context) => HomeScreen()));
  }
}

and here's my api_provider.dart

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter_session/flutter_session.dart';

class ApiProvider {
  Dio _dio;
  String aToken = '';

  final BaseOptions options = new BaseOptions(
    baseUrl: 'https://sooo.co.ke/africanapp/',
    connectTimeout: 15000,
    receiveTimeout: 13000,
  );
  static final ApiProvider _instance = ApiProvider._internal();

  factory ApiProvider() => _instance;

  ApiProvider._internal() {
    _dio = Dio(options);
    _dio.interceptors
        .add(InterceptorsWrapper(onRequest: (Options options) async {
      // to prevent other request enter this interceptor.
      _dio.interceptors.requestLock.lock();
      // We use a new Dio(to avoid dead lock) instance to request token.
      //Set the cookie to headers
      options.headers["cookie"] = aToken;

      _dio.interceptors.requestLock.unlock();
      return options; //continue
    }));
  }

  // ignore: missing_return
  Future<LoginApiResponse> getLogin({String passcode, String uname}) async {
    final request = {"email": uname, "password": passcode};

    FormData formData = FormData.fromMap({
      'email': uname,
      'password': passcode,
    });

    print(request);

    try {
      final response = await _dio.post('/', data: formData);
      //getting cookies from response
      String jsonsDataString = response.data.toString();
      final jsonData = jsonDecode(jsonsDataString);

      final cookies = response.headers.map['set-cookie'];
      print(cookies);
      print(response.data);
      var message = jsonData['msg'];
      var usrid = jsonData['uid'];
      var name = jsonData['username'];
      var mail = jsonData['email'];
      var images = jsonData['profile'];

      if (message == "welcomeback") {
        await FlutterSession().set('username', usrid);
        await FlutterSession().set('username', name);
        await FlutterSession().set('email', mail);
        await FlutterSession().set('image', images);
        print(message + " dan status : " + message);
      }

      //print(response.headers.toString());
      if (response.statusCode == 200) {
        final authToken = cookies[1].split(';')[0]; // server sending cookie
        // authToken in local storage, pass5. in further api calls.
        aToken =
            authToken; // global variable to refresh current api calls to add cookie.
        print(authToken);
      } else {
        // If that response was not OK, throw an error.
        throw Exception('Failed to load post');
      }
      return LoginApiResponse(jsonData);
    } catch (e) {
      print('Error: $e');
    }

    
  }

}

class LoginApiResponse {
  final Response response;
  LoginApiResponse(this.response);
}

Can anyone check it out and tell me where my problem is. thank you in advance.

I really need this help fast, I'm boiling to finish my project sooner.

Please help.


Solution

  • final jsonData = jsonDecode(jsonsDataString);
    ...
    return LoginApiResponse(jsonData);
    ...
    if (loginresponse.response.data != 200) 
    

    After decoding jsonData only has the data part and not the statusCode, so in the loginresponse of _doLogin() you won't have the status part, hence you won't navigate to other page.