5

I am getting my response from the URL after login in but I can only print the data in my console but how to get the mail and name from the that response

I have tried with the future response but when I get a future response but its returning error

LoginPage.dart

import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'globals.dart' as globals;

class LoginPage extends StatefulWidget {
  static String tag = 'login-page';
  @override
  _LoginPageState createState() => new _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  LoginRequestData _loginData = LoginRequestData();


  bool _validate = false;
  bool _obscureText = true;
  var username, password;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: Container(
          color: Colors.lightGreen[500],
          child: Column(
            children: <Widget>[
              Center(
                child: Container(
                  width: MediaQuery
                      .of(context)
                      .size
                      .width,
                  height: MediaQuery
                      .of(context)
                      .size
                      .height / 2.5,
                  decoration: BoxDecoration(
                      gradient: LinearGradient(
                        // begin: Alignment.topCenter,
                        // end: Alignment.bottomCenter,
                          colors: [
                            Color(0xFFFFFFFF),
                            Color(0xFFFFFFFF),
                          ]
                      ),
                      borderRadius: BorderRadius.only(
                          bottomLeft: Radius.circular(90)
                      )
                  ),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Align(
                        alignment: Alignment.center,
                        child: Image.asset('images/ic_launcher1.png'),
                      ),
                    ],
                  ),
                ),
              ),
              Center(
                  child: SingleChildScrollView(
                    child: new Form(
                      key: _formKey,
                      autovalidate: _validate,
                      child: _getFormUI(),
                    ),
                  )
              )

            ],
          ),
        ),
      ),
    );
  }

  Widget _getFormUI() {
    return new Column(
      children: <Widget>[
        SizedBox(height: 24.0),
        Center(
          child: Text('Login',
            style: TextStyle(fontSize: 25,
                fontWeight: FontWeight.bold,
                color: Colors.white),),
        ),
        new SizedBox(height: 25.0),
        new TextFormField(
          keyboardType: TextInputType.emailAddress,
          autofocus: false,
          decoration: InputDecoration(
            hintText: 'Username',
            contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
            border:
            OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
          ),
          validator: _validateName,
          onSaved: (value) {
            _loginData.username = value;
          },
        ),
        new SizedBox(height: 8.0),
        new TextFormField(
            autofocus: false,
            obscureText: _obscureText,
            keyboardType: TextInputType.text,
            decoration: InputDecoration(
              hintText: 'Password',
              contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
              border:
              OutlineInputBorder(borderRadius: BorderRadius.circular(24.0)),
              suffixIcon: GestureDetector(
                child: Icon(
                  _obscureText ? Icons.visibility : Icons.visibility_off,
                  semanticLabel:
                  _obscureText ? 'show password' : 'hide password',
                ),
              ),
            ),
            validator: _validatePassword,
            onSaved: (String value) {
              _loginData.password = value;
            }
        ),
        new SizedBox(height: 15.0),
        new Padding(
          padding: EdgeInsets.symmetric(vertical: 16.0),
          child: RaisedButton(
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(24),
            ),
            onPressed: () {
              _submit();
//              Navigator.of(context).pushReplacementNamed('/home');
            },
            padding: EdgeInsets.all(12),
            color: Colors.black54,
            child: Text('Log In', style: TextStyle(color: Colors.white)),
          ),
        ),
        new FlatButton(
          child: Text(
            'Forgot password?',
            style: TextStyle(color: Colors.black54),
          ),
          onPressed: () {},
        ),
        new FlatButton(
          onPressed: _sendToRegisterPage,
          child: Text('Not a member? Sign up now',
              style: TextStyle(color: Colors.black54)),
        ),
        Text(''),
        Text(''),
        Text(''),
      ],
    );
  }

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

  String _validateName(String value) {
    if (value.isEmpty) {
      return "Username is Required";
    } else {
      username = value.toString();
    }
  }

  String _validatePassword(String value) {
    if (value.isEmpty) {
      return "Password is Required";
    } else {
      password = value.toString();
    }
  }

  _submit() {
    if (_formKey.currentState.validate()) {
      _formKey.currentState.save();
      print("Username ${_loginData.username}");
      print("Password ${_loginData.password}");
      return SessionId();
    } else {
      setState(() {
        bool _validate = false;
      });
    }
  }


  final Dio _dio = Dio();
  PersistCookieJar persistentCookies;
  final String url = "https://www.xxxx.in/rest/user/login.json";

  Future<String> get _localPath async {
    final directory = await getApplicationDocumentsDirectory();
    print(directory.path);
    return directory.path;
  }

  Future<Directory> get _localCoookieDirectory async {
    final path = await _localPath;
    final Directory dir = new Directory('$path/cookies');
    await dir.create();
    print(dir);
    return dir;
  }

  Future<String> getCsrftoken() async{
    try {
      String csrfTokenValue;
      final Directory dir = await _localCoookieDirectory;
      final cookiePath = dir.path;
      persistentCookies = new PersistCookieJar(dir: '$cookiePath');
      persistentCookies.deleteAll(); //clearing any existing cookies for a fresh start
      _dio.interceptors.add(
          CookieManager(persistentCookies) //this sets up _dio to persist cookies throughout subsequent requests
      );
      _dio.options = new BaseOptions(
        baseUrl: url,
        contentType: ContentType.json,
        responseType: ResponseType.plain,
        // connectTimeout: 5000,
        // receiveTimeout: 100000,
        headers: {
          HttpHeaders.userAgentHeader: "dio",
          "Connection": "keep-alive",
        },
      ); //BaseOptions will be persisted throughout subsequent requests made with _dio
      _dio.interceptors.add(
          InterceptorsWrapper(
              onResponse:(Response response) {
                List<Cookie> cookies = persistentCookies.loadForRequest(Uri.parse(url));
                csrfTokenValue = cookies.firstWhere((c) => c.name == 'csrftoken', orElse: () => null)?.value;
                if (csrfTokenValue != null) {
                  _dio.options.headers['X-CSRF-TOKEN'] = csrfTokenValue; //setting the csrftoken from the response in the headers
                }
                print(response);
                return response;
              }
          )
      );
      await _dio.get("https://www.xxxx.in/rest/user/login.json");
      print(csrfTokenValue);
      return csrfTokenValue;
    } catch (error, stacktrace) {
      print(error);
//      print("Exception occured: $error stackTrace: $stacktrace");
      return null;
    }
  }

   SessionId() async {
     try {
       final csrf = await getCsrftoken();
       FormData formData = new FormData.from({
         "username": "${_loginData.username}",
         "password": "${_loginData.password}",
         "csrfmiddlewaretoken" : '$csrf'
       });
       Options optionData = new Options(
         contentType: ContentType.parse("application/json"),
       );
       Response response = await _dio.post("https://www.xxxx.in/rest/user/login.json", data: formData, options: optionData);
   Payload payloadFromJson(String str) => 
   Payload.fromJson(json.decode(str));
      String payloadToJson(Payload data) => json.encode(data.toJson());
       if (response.statusCode == 200){
         return Navigator.of(context).pushReplacement(MaterialPageRoute(
             builder: (context) => HomeScreen(),
         ));
       }
       else{
         throw Exception();
       }
     } on DioError catch(e) {
       if(e.response != null) {
         print( e.response.statusCode.toString() + " " + e.response.statusMessage);
         print(e.response.data);
         print(e.response.headers);
         print(e.response.request);
       } else{
         print(e.request);
         print(e.message);
       }
     }
     catch (error, stacktrace) {
       print("Exception occured: $error stackTrace: $stacktrace");
       return null;
     }
   }
}

Homepage.dart

import 'package:flutter/material.dart';
...

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => new _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
  Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Color(0xffF2F2F2),
          appBar: AppBar(
            title: Text('Home'),
            automaticallyImplyLeading: true,
           drawer: new Drawer(
           child: Column(
             children: <Widget>[
               UserAccountsDrawerHeader(
                 accountName: Text("${globals.payload.user.name}"),
                 accountEmail: Text("${globals.payload.user.mail}"),
                 )
             ],
           )
         )
}

please anybody can help to display name and mail-in drawer

Here is my Json

{
    "sessid": "iszSjigXjxCvchpSRrU3j5Xp83t_LCXoIbwzx-mM3ag",
    "session_name": "SSESSb2a6bc76023596a5f4079539da5ffe57",
    "token": "zQESYCrGbL-3NzN8Lm-1ll3AQ-iCFYjiqRvxSpesGBc",
    "user": {
        "uid": "991",
        "name": "abc",
        "mail": "abc@gmail.com",
        "theme": "",
        "signature": "",
        "signature_format": "plain_text",
        "created": "1560678471",
        "access": "1565326417",
        "login": 1565328198,
        "status": "1",
        "timezone": "Asia/Kolkata",
        "language": "",
        "picture": "0",
        "data": {
            "mimemail_textonly": 0
        },
        "uuid": "9e614051-1f21-470a-9194-c567fced36f7",
        "roles": {
            "2": "authenticated user",
            "6": "Mock test user"
        },
        "rdf_mapping": {
            "rdftype": [
                "sioc:UserAccount"
            ],
            "name": {
                "predicates": [
                    "foaf:name"
                ]
            },
            "homepage": {
                "predicates": [
                    "foaf:page"
                ],
                "type": "rel"
            }
        }
    }
}

Find Json file here

Community
  • 1
  • 1
Mahant
  • 419
  • 2
  • 8
  • 19
  • Do you mean after login success, you want to parse json returned from Dio? Could you post json format you got? – chunhunghan Aug 09 '19 at 03:51
  • please check the json file I have attached @chunhunghan – Mahant Aug 09 '19 at 04:31
  • Your question is bit confusing. Do you mean, how to parse the JSON so as to extract email and user name fields ? Or is it like you are parsing it right and having a trouble in showing it in the drawer ? What is the error you are facing ? – Sukhi Aug 09 '19 at 04:48
  • how to parse the JSON so as to extract email and user name fields.@Sukhi – Mahant Aug 09 '19 at 05:02
  • Could you paste this JSON as text not image to allow me copy and provide struct? – chunhunghan Aug 09 '19 at 05:10
  • Now check with question I have updated.@chunhunghan – Mahant Aug 09 '19 at 05:25

2 Answers2

2

In comments, how to parse the JSON?

please paste your JSON string to https://app.quicktype.io/
It will provide correct format
code snippet to parse JSON.

// To parse this JSON data, do
//
//     final payload = payloadFromJson(jsonString);

import 'dart:convert';

Payload payloadFromJson(String str) => Payload.fromJson(json.decode(str));

String payloadToJson(Payload data) => json.encode(data.toJson());

class Payload {
    String sessid;
    String sessionName;
    String token;
    User user;

    Payload({
        this.sessid,
        this.sessionName,
        this.token,
        this.user,
    });

    factory Payload.fromJson(Map<String, dynamic> json) => new Payload(
        sessid: json["sessid"],
        sessionName: json["session_name"],
        token: json["token"],
        user: User.fromJson(json["user"]),
    );

    Map<String, dynamic> toJson() => {
        "sessid": sessid,
        "session_name": sessionName,
        "token": token,
        "user": user.toJson(),
    };
}

class User {
    String uid;
    String name;
    String mail;
    String theme;
    String signature;
    String signatureFormat;
    String created;
    String access;
    int login;
    String status;
    String timezone;
    String language;
    String picture;
    Data data;
    String uuid;
    Map<String, String> roles;
    RdfMapping rdfMapping;

    User({
        this.uid,
        this.name,
        this.mail,
        this.theme,
        this.signature,
        this.signatureFormat,
        this.created,
        this.access,
        this.login,
        this.status,
        this.timezone,
        this.language,
        this.picture,
        this.data,
        this.uuid,
        this.roles,
        this.rdfMapping,
    });

    factory User.fromJson(Map<String, dynamic> json) => new User(
        uid: json["uid"],
        name: json["name"],
        mail: json["mail"],
        theme: json["theme"],
        signature: json["signature"],
        signatureFormat: json["signature_format"],
        created: json["created"],
        access: json["access"],
        login: json["login"],
        status: json["status"],
        timezone: json["timezone"],
        language: json["language"],
        picture: json["picture"],
        data: Data.fromJson(json["data"]),
        uuid: json["uuid"],
        roles: new Map.from(json["roles"]).map((k, v) => new MapEntry<String, String>(k, v)),
        rdfMapping: RdfMapping.fromJson(json["rdf_mapping"]),
    );

    Map<String, dynamic> toJson() => {
        "uid": uid,
        "name": name,
        "mail": mail,
        "theme": theme,
        "signature": signature,
        "signature_format": signatureFormat,
        "created": created,
        "access": access,
        "login": login,
        "status": status,
        "timezone": timezone,
        "language": language,
        "picture": picture,
        "data": data.toJson(),
        "uuid": uuid,
        "roles": new Map.from(roles).map((k, v) => new MapEntry<String, dynamic>(k, v)),
        "rdf_mapping": rdfMapping.toJson(),
    };
}

class Data {
    int mimemailTextonly;

    Data({
        this.mimemailTextonly,
    });

    factory Data.fromJson(Map<String, dynamic> json) => new Data(
        mimemailTextonly: json["mimemail_textonly"],
    );

    Map<String, dynamic> toJson() => {
        "mimemail_textonly": mimemailTextonly,
    };
}

class RdfMapping {
    List<String> rdftype;
    Name name;
    Homepage homepage;

    RdfMapping({
        this.rdftype,
        this.name,
        this.homepage,
    });

    factory RdfMapping.fromJson(Map<String, dynamic> json) => new RdfMapping(
        rdftype: new List<String>.from(json["rdftype"].map((x) => x)),
        name: Name.fromJson(json["name"]),
        homepage: Homepage.fromJson(json["homepage"]),
    );

    Map<String, dynamic> toJson() => {
        "rdftype": new List<dynamic>.from(rdftype.map((x) => x)),
        "name": name.toJson(),
        "homepage": homepage.toJson(),
    };
}

class Homepage {
    List<String> predicates;
    String type;

    Homepage({
        this.predicates,
        this.type,
    });

    factory Homepage.fromJson(Map<String, dynamic> json) => new Homepage(
        predicates: new List<String>.from(json["predicates"].map((x) => x)),
        type: json["type"],
    );

    Map<String, dynamic> toJson() => {
        "predicates": new List<dynamic>.from(predicates.map((x) => x)),
        "type": type,
    };
}

class Name {
    List<String> predicates;

    Name({
        this.predicates,
    });

    factory Name.fromJson(Map<String, dynamic> json) => new Name(
        predicates: new List<String>.from(json["predicates"].map((x) => x)),
    );

    Map<String, dynamic> toJson() => {
        "predicates": new List<dynamic>.from(predicates.map((x) => x)),
    };
}

In comments, the following code is for demo purpose only, not best practice, there are other options can do this, but hard to describe in short since it's a huge topic, so from Global Variables in Dart

1 add globals.dart file

 library my_prj.globals;
 //import Payload class file too
 Payload payload;

2 Import this library everywhere you need access to these fields.

import 'globals.dart' as globals;
...
globals.payload = payloadFromJson(jsonString); //from your parse or http logical

3 In your drawer class

import 'globals.dart' as globals;
... 
return Drawer(
  child: Column(
    children: <Widget>[
      UserAccountsDrawerHeader(
        accountName: Text("${globals.payload.user.name}"),
        accountEmail: Text("${globals.payload.user.mail}"), 

Edit
In Homepage.dart add the following, then you can access your global variables

import 'globals.dart' as globals;

and do the same in LoginPage.dart, then you can

 globals.payload = payloadFromJson(jsonString);
chunhunghan
  • 51,087
  • 5
  • 102
  • 120
  • parsing is done but how to display it in UserAccountsHeader of drawer in home page. – Mahant Aug 09 '19 at 07:19
  • There are some options. Dart support global variable, you can check this https://stackoverflow.com/questions/29182581/global-variables-in-dart or use this package https://pub.dev/packages/get_it and it's huge topic, I suggest you to post another question to get better answer – chunhunghan Aug 09 '19 at 07:32
  • my company firewall block me. Could you check stackoverflow.com/questions/29182581/global-variables-in-dart? save your data as global variable, and you can use it everywhere. not a good options but work. – chunhunghan Aug 09 '19 at 07:59
  • could you please add the code or process by editing the answer please. – Mahant Aug 09 '19 at 08:04
  • revise typo. please check it. – chunhunghan Aug 09 '19 at 09:06
  • In step 2 I am stuck where should I implement that.I tried implementing in login page. its saying create method or class.As said by you from parse or http logic.My logic page is in login page as above – Mahant Aug 09 '19 at 09:40
  • I have updated my question with home page.Please help me in implementing the methods you explained.Also see my implementation in login page is correct or wrong. – Mahant Aug 09 '19 at 10:28
  • When I paste code globals.payload = payloadFromJson(jsonString); in below the response of login page error saying undefined json stirng – Mahant Aug 12 '19 at 04:14
  • It means globals.payload is a global variable. you can access this global variable everywhere. so In LoginPage.dart after correct authenticate user, save user information to this variable. – chunhunghan Aug 12 '19 at 05:14
1

In theory, you will need an object which has a similar structure. However, if the JSON is complex and you need one/two attributes, following can be the quick way.

_emailId = decodedBody["user"]["mail"]

Now, let's say you get JSON response in the login page and need to pass _emailId to HomePage. You can do this like below :

HomePage.dart

class HomePage extends StatelessWidget {
  final String emailId;

  const HomePage({
    Key key,
    @required this.emailId,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print (this.emailid);
    return .....
    );
  }
}

Update _sendToRegisterPage() as below :

_sendToRegisterPage() {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => HomeScreen(emailId:_emailId)),
    );
  }
Sukhi
  • 13,261
  • 7
  • 36
  • 53
  • I have updated my question with home page.Please help me in implementing the methods you explained.Also see my implementation in login page is correct or wrong. – Mahant Aug 09 '19 at 10:28
  • Refer [this](https://flutter.dev/docs/cookbook/design/drawer)page. There's a simple example on how to do it. Alternatively, you'll have to implement class UserAccountsDrawerHeader() which is nothing but a rectangle with gradient (or image) with a text overlay (user name, email id). In the simplest form, a Column widget saving two Text widgets. – Sukhi Aug 09 '19 at 10:36
  • Question which I am asking is I am getting response in loginpage and by taking that response I should implement it in homepage to get user name and mail.I have already read which they have explained is in dummy module but my case its not the same.Main problem in my question is to listen to the response and display in home page – Mahant Aug 09 '19 at 10:45
  • exactly where I shall write the code " _emailId = decodedBody["user"]["mail"] " in my case – Mahant Aug 09 '19 at 12:19
  • 1
    @Tuhin Yes, did some tweaks. – Mahant Aug 25 '21 at 01:05