Home > Net >  _LoginScreenState.build.<anonymous closure>
_LoginScreenState.build.<anonymous closure>

Time:02-23

Someone can help me? I get errors when running the code.

This full code errors

Restarted application in 5,728ms.
D/EGL_emulation(12613): app_time_stats: avg=500967.44ms min=177.41ms max=1001757.50ms count=2
D/EGL_emulation(12613): app_time_stats: avg=1551.20ms min=1551.20ms max=1551.20ms count=1
E/flutter (12613): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: setState() called after dispose(): _LoginScreenState#96e43(lifecycle state: defunct, not mounted)
E/flutter (12613): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
E/flutter (12613): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (12613): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter (12613): #0      State.setState.<anonymous closure>
E/flutter (12613): #1      State.setState
E/flutter (12613): #2      _LoginScreenState.build.<anonymous closure>
E/flutter (12613): #3      _LoginScreenState.build.<anonymous closure>
E/flutter (12613): #4      _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter (12613): #5      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (12613): <asynchronous suspension>
E/flutter (12613):

This Login Page

import 'package:flutter/material.dart';
import 'package:login/api_service.dart';
import 'package:login/otp_verify.dart';
import 'package:login/login_page.dart';
import 'package:snippet_coder_utils/FormHelper.dart';


class LoginScreen extends StatefulWidget {
  
  

  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  TextEditingController patientNoController = TextEditingController();
  bool isAPICallProcess = false;

  String patientPhoneNumber = ' 60176713856';
  
  @override
  Widget build(BuildContext context) {
    final patientNoController = TextEditingController();
     
    final logo = Hero(
      tag: 'logo',
      child: CircleAvatar(
        backgroundColor: Colors.transparent,
        radius: 40.0,
        child: Image.network(
          "https://i.imgur.com/bOCEVJg.png",
          height: 180,
          fit: BoxFit.contain,
          
        ),
      ),
    ); 
    final txtPatientNo = TextField(
      controller: patientNoController,
      decoration: InputDecoration(
        hintText: 'Phone Number',
        contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(30.0)
        )
        ),
       
    );
    
    final btnLogin = RaisedButton(
      child: Text("Verify"),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
      onPressed: (){
        if (patientNoController != null && patientNoController.text ==" 60176713856");
          

              });
              APIService.signin(patientPhoneNumber).then((respone) async {
                setState(() {
                  isAPICallProcess = false;
                });
               if (respone) {
                 Navigator.pushAndRemoveUntil(
                   context, 
                   MaterialPageRoute(
                     builder: (context) => OtpPage(
                       
                     ),
                   ), 
                   
                   (route) => false,
                   
                );
               }

      },
    );

    return Scaffold(
      appBar: AppBar(
        title: Text("Patient Login Page"),
      ),
      body: Center(
        child: ListView(
          shrinkWrap: true,
          padding: EdgeInsets.only(left: 25, right: 25),
          children: <Widget>[
          logo,
          SizedBox(height: 20,),
          txtPatientNo,
          SizedBox(height: 20,),
          btnLogin,
        ],
        ),
      ),
    );

  }
}

Can anyone tell me where my mistake is? I'm new to using flutter. I want to use TextEditingControl and create an APICallProcess. But my problem. I stack the first page. Is my coding correct or not. Someone can explain to me so I can learn.

CodePudding user response:

This might happen because after you call setState you immediately call Navigator.pushAndRemoveUntil. setState will execute the passed callback (in this case () {isAPICallProcess = false;}, and marks to widget to be rebuilt.

But you Navigator call can execute pretty quickly, so there is a chance when the engine tries to rebuild this login page of yours after setState, it is no longer in the widget tree, and is disposed.

I don't know what do you use this isAPICallProcess but my guess is that you do not really need it after this widget is disposed. So you can avoid this error message with this, checking for the widget's mounted state:

if (mounted) {
  setState(() {
    isAPICallProcess = false;
  });
}

CodePudding user response:

My login page code - in MaterialPageRoute I have an error at patientPhoneNumber: patientPhoneNumber,

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

import 'otp_verify.dart';


class LoginScreen extends StatefulWidget {
  const LoginScreen({Key? key}) : super(key: key);


  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  bool isAPICallProcess = false;
  String patientPhoneNumber = ' 60176713856';
  final TextEditingController patientNoController = TextEditingController();
  _LoginScreenState(){
    patientNoController.text = ' 60176713856';
  }

  @override
  Widget build(BuildContext context) {
   
     
    final logo = Hero(
      tag: 'logo',
      child: CircleAvatar(
        backgroundColor: Colors.transparent,
        radius: 40.0,
        child: Image.network(
          "https://i.imgur.com/bOCEVJg.png",
          height: 180,
          fit: BoxFit.contain,
          
        ),
      ),
    ); 
   

    //TextField
    final txtPatientNo = TextField(
      controller: patientNoController,
      decoration: InputDecoration(
        hintText: 'Phone Number',
        contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(30.0)
        )
        ),
       
    );
    
    //Button
    final btnLogin = RaisedButton(
      child: const Text("Verify"),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
      onPressed: (){
        if (patientNoController != null && patientNoController.text ==" 60176713856");
          

              });
              //Signin
              APIService.signin(patientPhoneNumber).then((respone) async {
               if (mounted) {
                 setState(() {
                   isAPICallProcess = false;   
                });
                if (respone) {
                  MaterialPageRoute(
                    builder: (context) => OtpPage(
                      patientPhoneNumber: patientPhoneNumber,
                    )
                    );
                    (route) => false;
                  
                }

               }

      },
    );

    return Scaffold(
      appBar: AppBar(
        title: const Text("Patient Login Page"),
      ),
      body: Center(
        child: ListView(
          shrinkWrap: true,
          padding: const EdgeInsets.only(left: 25, right: 25),
          children: <Widget>[
          logo,
          const SizedBox(height: 20,),
          txtPatientNo,
          const SizedBox(height: 20,),
          btnLogin,
        ],
        ),
      ),
    );
  
  }

    @override
    void dispose() {
    patientNoController.dispose();
    super.dispose();
 }
}

My otp verify page code

import 'package:flutter/material.dart';

import 'api_service.dart';
import 'appoinment_list.dart';

class OtpPage extends StatefulWidget {
  
   _otpPageVerifyState createState() => _otpPageVerifyState();
}

class _otpPageVerifyState extends State<OtpPage> {
  bool isAPICallProcess = false;
  String otpVerifyNo = '134679';
  final TextEditingController otpVerifyNoController = TextEditingController();
  _otpPageVerifyState(){
    otpVerifyNoController.text = '134679';
  }
@override
Widget build(BuildContext context) {
  
  final logo = Hero(
      tag: 'logo',
      child: CircleAvatar(
        backgroundColor: Colors.transparent,
        radius: 40.0,
        child: Image.network(
          "https://i.imgur.com/6aiRpKT.png",
          height: 180,
          fit: BoxFit.contain,
          
        ),
      ),
    ); 
 //TextField
    final txtotpVerify = TextField(
      controller: otpVerifyNoController,
      decoration: InputDecoration(
        hintText: 'OTP Number',
        contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(30.0)
        )
        ),
       
    );
    //Button
    final btnLogin = RaisedButton(
      child: const Text("Verify"),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
      onPressed: (){
        if (otpVerifyNoController != null && otpVerifyNoController.text =="134679");

        });
       //Signin
              APIService.verifyOTP(otpVerifyNo).then((respone) async {
               if (mounted) {
                 setState(() {
                   isAPICallProcess = false;   
                });
                if (respone!.isNotEmpty){
                  MaterialPageRoute(
                    builder: (context) => AppoinmentList(
                      token: respone,
                    )
                  );
                }
               }

      },
    );

return Scaffold(
      appBar: AppBar(
        title: const Text("Patient Login Page"),
      ),
      body: Center(
        child: ListView(
          shrinkWrap: true,
          padding: const EdgeInsets.only(left: 25, right: 25),
          children: <Widget>[
          logo,
          const SizedBox(height: 20,),
          txtotpVerify,
          const SizedBox(height: 20,),
          btnLogin,
        ],
        ),
      ),
    );
  
  }

    @override
    void dispose() {
    otpVerifyNoController.dispose();
    super.dispose();
}
}

My API service page

import 'dart:async';
import 'dart:convert' show json;
import 'package:http/http.dart' as http;

class APIService {
/* 

use the phone number and otp below
phone:  60176713856
otp: 134679

Step:
1. Signin
2. Verify OTP
3. Get an appointment list

*/

  static Future<String?> verifyOTP(otp) async {
    var url =
        'https://us-central1-cheart.cloudfunctions.net/api_v2/consumerWebVerifyOTP';

    Map data = {
      "API": "ConsumerWebVerifyOTP",
      "Token": "",
      "Data": {
        "tokenType": "jwt",
        "otpNumber": otp.trim(),
      }
    };

    //encode Map to JSON
    var body = json.encode(data);
    var response = await http.post(Uri.parse(url),
        headers: {"Content-Type": "application/json"}, body: body);

    if (response.statusCode == 200) {
      var result = json.decode(response.body.toString());
      if (result['ResponseCode'] == "0") {
        var token = result['Data']['token'];

        return token;
      } else if (result['ResponseCode'] != "0") {
        return null;
      }
    }
  }

  static Future<bool> signin(patientPhoneNumber) async {
    bool ret = false;
    var url =
        "https://us-central1-cheart.cloudfunctions.net/api_v2/consumerWebLogin";

    Map data = {
      "API": "ConsumerWebLogin",
      "Token": "",
      "Data": {
        "tokenType": "jwt",
        "patientPhoneNumber": patientPhoneNumber.trim(),
      }
    };

    try {
      //encode Map to JSON
      var body = json.encode(data);
      var response = await http.post(Uri.parse(url),
          headers: {"Content-Type": "application/json"}, body: body);

      if (response.statusCode == 200) {
        var result = json.decode(response.body.toString());
        if (result['ResponseCode'] == "0") {
          ret = true;
        } else if (result['ResponseCode'] != "0") {
          ret = false;
        }
      }
    } catch (e) {
      ret = false;
    }

    return ret;
  }

  static Future<String?> getAppointmentList(String token) async {
    var url =
        'https://us-central1-cheart.cloudfunctions.net/api_v2/consumerWebGetPatientAppointment';

    Map data = {
      "API": "UserGetWebCallAppointmentList",
      "Token": token,
      "Data": {"tokenType": "jwt", "appointmentStatus": 0}
    };

    //encode Map to JSON
    var body = json.encode(data);
    var response = await http.post(Uri.parse(url),
        headers: {"Content-Type": "application/json"}, body: body);

    if (response.statusCode == 200) {
      var result = json.decode(response.body.toString());
      if (result['ResponseCode'] == "0") {
        // if (result['Data'] != null) {
        //   // convert into list
        // }

        return result['ResponseMsg'];
      } else if (result['ResponseCode'] != "0") {
        if (result['ResponseCode'] == "1") {}
      }
    }
  }
}

The appointment list page is still not complete

import 'package:flutter/material.dart';

import 'api_service.dart';

class AppoinmentList extends StatefulWidget {
  final String token;
  const AppoinmentList({
    Key? key,
    required this.token,
  }) :super(key: key);

@override
_AppoinmentListState createState() => _AppoinmentListState();
  
  
}
class _AppoinmentListState extends State<AppoinmentList> {
  @override
  void initState() {
    super.initState();
    APIService.getAppointmentList(widget.token);
  
}

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }
}

When I enter the phone number on the login page and click the button verify. I can't go to the OTP page. I don't know why. Can check my code if my code has wrong. I hope you can help me.

Phone number: 60176713856
OTP number: 134679

  • Related