Home > database >  How to call a function only once while the page is active in flutter
How to call a function only once while the page is active in flutter

Time:12-29

I have a dart page voterhome(like dashboard),at first when I arrive at voterhome it will call the getuserdetails() function and get the adhar of user to pass it to other pages so I can navigate to other pages (like vote,voteregister ..etc)

when I return back to voterhome from other pages it will call the getuserdetails()function again because the function is inside initstate() I don't want this to happen how can I do that

my code :

voterhome.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:election/services/IntoLogin.dart';
import 'package:election/pages/Voter/Vote.dart';
import 'package:election/pages/Voter/VoteRegister.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:web3dart/web3dart.dart';

import '../../services/Auth.dart';
import '../../utils/Constants.dart';
import '../../services/Electioninfo.dart';
import '../../services/VerifyEmail.dart';

class VoterHome extends StatefulWidget {
  //getting required parameters to pass on to vote and authorize
  final Web3Client ethClient;
  final String electionName;
  final String electionaddress;
  const VoterHome({Key? key, required this.ethClient, required this.electionName, required this.electionaddress}) : super(key: key);

  @override
  State<VoterHome> createState() => _VoterHomeState();
}

class _VoterHomeState extends State<VoterHome> {
  //creating clients
  late Client? httpClient;//http client
  late Web3Client? ethclient;// eth client
//sign out user
  final User? user = Auth().currentuser;
  Future<void>signOut()async{
    await Auth().signOut();
    if(!mounted)return;
    Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context)=>IntroLogin()), (route) => false);
  }
 // voters info
   var email;
   var adhar;
   var name;
   var phone;

  //checking if voter authorized or voted   // dont have to do this because we does this on the respected pages
  late bool isAuth = false;//if  he is authorized
  late  bool isVoted = false;//if he is voted
  Future<void>getUserDetail() async {
    try {
      final DocumentSnapshot voters = await FirebaseFirestore.instance
          .collection('voters')
          .doc(user?.email)
          .get();
      if (voters.data() != null) {
        email = voters.get('email');
        name = voters.get('name');
        phone = voters.get('phone');
        adhar = voters.get('adharnum');
        print('adhar is $adhar');

      }else{
        print('cannot find details');
      }
      showSnackBar(succesdetailsnackSnack);
    } catch (e) {
      if (kDebugMode) {
        print('get check user ::::: $e');
        showSnackBar(errordetailsnackSnack);
      }
    }
  }//function to check ends


  @override
  void initState() {
    httpClient = Client();
    ethclient = Web3Client(infura_url, httpClient!);
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await getUserDetail();
      setState(() { });
    });
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    Map<String,dynamic> voterdata = {'name':name,'adharnum':adhar.toString(),'email':email,};
    if(user!.emailVerified){
      return Scaffold(
          appBar: AppBar(
            leading: IconButton(onPressed: () { signOut(); }, icon: const Icon(Icons.logout),),
            actions: [IconButton(onPressed:(){setState(() {});}, icon: const Icon(Icons.refresh))],
            title: const Text('Voter DASHBOARD'),backgroundColor: Colors.cyan,),
          body: SingleChildScrollView(
            child: Column(
              children: [
                Container(
                  padding: const EdgeInsets.all(24),
                  margin: const EdgeInsets.only(bottom: 16),
                  child: InkWell(
                    onTap: () {
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => VoteRegister(electionName:widget.electionName,
                                  ethClient: widget.ethClient, electionaddress:widget.electionaddress,adhar:adhar,)));
                    },
                    child: Card(borderOnForeground: true,elevation: 4,
                      child: Column(
                        children: [
                          Container(height: 200,
                              decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(15),
                                  image: const DecorationImage(
                                      image: AssetImage('assets/undraw/electionday.png')))),
                          Container(decoration: const BoxDecoration(color: Colors.cyan),width: double.infinity,
                            child: const Center(
                              child: Text('Register to Vote',style: TextStyle(
                                  fontWeight: FontWeight.bold,fontSize:16,color: Colors.white),),
                            ),
                          )
                        ],
                      ),
                    ),
                  ),
                ),
                Container(
                  padding: const EdgeInsets.all(24),
                  margin: const EdgeInsets.only(bottom: 16),
                  child: InkWell(
                    onTap: () {
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => VoterVote(ethClient:ethclient!,electionName:widget.electionName,
                                  electionaddress:widget.electionaddress ,votermap:voterdata,)));
                    },
                    child: Card(borderOnForeground: true,elevation: 4,
                      child: Column(
                        children: [
                          Container(height: 200,
                              decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(15),
                                  image: const DecorationImage(
                                      image: AssetImage('assets/undraw/upvote.png')))),
                          Container(decoration: const BoxDecoration(color: Colors.cyan),width: double.infinity,
                            child: const Center(
                              child: Text('Vote',style: TextStyle(fontWeight: FontWeight.bold,fontSize:16,color: Colors.white),),
                            ),
                          )
                        ],
                      ),
                    ),
                  ),
                ),
                Container(
                  padding: const EdgeInsets.all(24),
                  margin: const EdgeInsets.only(bottom: 16),
                  child: InkWell(
                    onTap: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => ElectionInfo(ethClient:ethclient!,electionName:widget.electionName,
                                electionAddress:widget.electionaddress,)));
                    },
                    child: Card(borderOnForeground: true,elevation: 4,
                      child: Column(
                        children: [
                          Container(height: 200,
                              decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(15),
                                  image: const DecorationImage(
                                      image: AssetImage('assets/undraw/electionday.png')))),
                          Container(decoration: const BoxDecoration(color: Colors.cyan),width: double.infinity,
                            child: const Center(
                              child: Text('Election details',style: TextStyle(
                                  fontWeight: FontWeight.bold,fontSize:16,color: Colors.white),),
                            ),
                          )
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),
          )
      );
    }else{
      return Scaffold(
        appBar:AppBar( ///app bar
          backgroundColor: Colors.cyan,
          leading: IconButton(
            onPressed: () {
              signOut();
            },
            icon: const Icon(Icons.logout_sharp),
          ),
          title: const Text('Verify Voter email'),
          actions: [
            IconButton(
                onPressed: () {
                  refresh();
                },
                icon: const Icon(Icons.refresh))
          ],
        ),
        body: Container(margin: const EdgeInsets.only(top: 56),
          child: Center(
            child: Column(
              children: [
                Text('Your Email ${user?.email} is not verified'),
                const SizedBox(height: 24,),
                ElevatedButton(
                    onPressed: () {
                      Navigator.pushAndRemoveUntil(
                          context,
                          MaterialPageRoute(builder: (context) => const VerifyEmail()),
                              (route) => false);
                    },
                    child: const Text('Verify Email'))
              ],
            ),
          ),
        ),
      );
    }
  }
  //function to refresh using setstate
  void refresh() {
    setState(() {});
  }
  //snackbar
  SnackBar errordetailsnackSnack = const SnackBar(content: Text('You are not logged in if you are please check your internet connection'));
  SnackBar succesdetailsnackSnack = const SnackBar(content: Text('successfull'));
  SnackBar votedSnack = const SnackBar(content: Text('You have already voted'));
  SnackBar RegisterSnack = const SnackBar(content: Text('You have already registered'));
  // SnackBar errorSnack = const SnackBar(content: Text('Fill all the details'));
  // SnackBar datanullSnack = const SnackBar(content: Text('No users registerd yet'));
  //function to show snackbar
  ScaffoldFeatureController<SnackBar, SnackBarClosedReason> showSnackBar(SnackBar snackBar) {
    return ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }
}

vote.dart //when i go to voterhome() from this it again calls the function

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:election/pages/Voter/VoterHome.dart';
import 'package:election/utils/Constants.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:web3dart/web3dart.dart';

import '../../services/Auth.dart';
import '../../services/functions.dart';
import '../../services/IntoLogin.dart';

class VoterVote extends StatefulWidget {
  final Web3Client ethClient;
  final String electionName;
  final String electionaddress;
   final  votermap;
  const VoterVote({Key? key, required this.ethClient, required this.electionName, required this.electionaddress, this.votermap,}) : super(key: key);

  @override
  State<VoterVote> createState() => _VoterVoteState();
}

class _VoterVoteState extends State<VoterVote> {

  final User? user = Auth().currentuser;//fi// rebase auth current user initialization

  //sign out user function
  Future<void> signOut() async {
    if (!mounted) return;
    await Auth().signOut();
    if (!mounted) return;
    Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(builder: (context) =>  IntroLogin()),
            (route) => false);
  }

  //checking if the voter is already voted
  late bool isAuth = false;
  late bool isVoted = false;

  Future<void>getUserDetail() async {
    var voterdetails = widget.votermap;
    try {
      final DocumentSnapshot voters = await FirebaseFirestore.instance
          .collection('Election')
          .doc(widget.electionName).collection('voterAuth').doc(voterdetails['adharnum'])
          .get();
      if (voters.data() != null) {
        isAuth = voters.get('isAuth');
        isVoted = voters.get('isVoted');
      }else{
        isAuth = false;
        isVoted= false;
        print('cannot find details');
      }
    } catch (e) {
      if (kDebugMode) {
        print('get check user ::::: $e');
      }
    }
  }//function to check ends

  TextEditingController privatekeyController = TextEditingController();
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await getUserDetail();
      setState(() { });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if(isVoted== true && isAuth == true){
      return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.cyan,
          leading: IconButton(onPressed: (){signOut();},icon: const Icon(Icons.logout_sharp),),
          title:const Text('Vote'),
          actions: [
            IconButton(onPressed:(){
              refresh();
            }, icon: const Icon(Icons.refresh))
          ],
        ),
        body: const Center(child: Text('you have already voted sir'),),
      );
    }else if(isVoted == false&&isAuth == true){
      return Scaffold(
        appBar:AppBar(
          backgroundColor: Colors.cyan,
          leading: IconButton(onPressed: (){signOut();},icon: const Icon(Icons.logout_sharp),),
          title:const Text('Vote'),
          actions: [
            IconButton(onPressed:(){
              refresh();
             }, icon: const Icon(Icons.refresh))
          ],
        ),
        body: Container(margin:const EdgeInsets.only(bottom: 56,top: 24),alignment: Alignment.topCenter,
          child:SingleChildScrollView(
            child: Column(
              children: [
                Center(
                    child: SelectableText("$voter_private_key && $voter_key2 && $voter_key3")
                ),
                const SizedBox(height: 24,),
                Container(padding: const EdgeInsets.all(16),
                  child: TextField(
                      controller: privatekeyController,
                      decoration:
                      const InputDecoration(hintText: 'Private key for voting',border: OutlineInputBorder(
                          borderRadius:
                          BorderRadius.all(Radius.circular(8))))),
                ),
                const SizedBox(height: 24,),
                SingleChildScrollView(
                  child: StreamBuilder<List>(stream:getCandidatesNum(widget.ethClient,widget.electionaddress).asStream(),
                    builder: (context, snapshot) {
                      if (snapshot.connectionState == ConnectionState.waiting) {
                        return const Center(
                          child: CircularProgressIndicator(),
                        );
                      } else {
                        return Column(
                          children: [
                            for (int i = 0; i < snapshot.data![0].toInt(); i  )
                              FutureBuilder<List>(
                                  future: candidateInfo(i, widget.ethClient,widget.electionaddress),
                                  builder: (context, candidatesnapshot) {
                                    if (candidatesnapshot.connectionState ==
                                        ConnectionState.waiting) {
                                      return const Center(
                                        child: CircularProgressIndicator(),
                                      );
                                    } else {
                                      return Card(    //card to represent the candidate
                                        color: Colors.cyan,
                                        child: SizedBox(height: 100,
                                          child: Center(
                                            child: ListTile(
                                              title: Text('Name: ${candidatesnapshot.data![0][0]}'),
                                              subtitle: Text('Votes: ${candidatesnapshot.data![0][1]}'),
                                              leading: ConstrainedBox(
                                                constraints: const BoxConstraints(
                                                  minHeight: 90,
                                                  minWidth: 90,
                                                  maxHeight: 100,
                                                  maxWidth: 100,
                                                ),
                                                child:const Image(image: AssetImage('assets/undraw/electionday.png')),
                                              ),
                                              trailing: ElevatedButton(
                                                onPressed: ()async {
                                                  try{
                                                    await vote(i,widget.ethClient,privatekeyController.text,widget.electionaddress);
                                                    await registerAuth();
                                                    gotoDashboard();
                                                    showSnackBar(succesdetailsnackSnack);
                                                  }catch(e){
                                                    if (kDebugMode) {
                                                      print(e);
                                                    }
                                                    showSnackBar(errordetailsnackSnack);
                                                    gotoDashboard();
                                                  }
                                                }, child: const Text('Vote'),),
                                            ),
                                          ),
                                        ),
                                      );
                                    }
                                  })
                          ],
                        );
                      }
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }else{
      return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.cyan,
          leading: IconButton(onPressed: (){signOut();},icon: const Icon(Icons.logout_sharp),),
          title:const Text('Vote'),
          actions: [
            IconButton(onPressed:(){
              refresh();
            }, icon: const Icon(Icons.refresh))
          ],
        ),
        body: const Center(child: Text('you are not authorized please authorize first'),),
      );
    }
  }

  //snackbar
  SnackBar errordetailsnackSnack = const SnackBar(content: Text(' already voted or please check your internet connection'));
  SnackBar succesdetailsnackSnack = const SnackBar(content: Text('successfull'));
  SnackBar voterSnack = const SnackBar(content: Text('you are a voter logout from voter account'));
  SnackBar adminSnack = const SnackBar(content: Text('you are an admin logout from Admin account'));
  // SnackBar errorSnack = const SnackBar(content: Text('Fill all the details'));
  // SnackBar datanullSnack = const SnackBar(content: Text('No users registerd yet'));
  //function to show snackbar
  ScaffoldFeatureController<SnackBar, SnackBarClosedReason> showSnackBar(SnackBar snackBar) {
    return ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }

  void refresh() {
    setState(() {});
  }

  Future<void> registerAuth() async {
    var voterdetails = widget.votermap;
    try {
      await FirebaseFirestore.instance.collection('Election').doc(widget.electionName).collection('voterAuth').doc(voterdetails['adharnum']).update({'isVoted':true});
      print('updated data aaaaaaaaaaaaaaa');
    } catch (e) {
      if (kDebugMode) {
        print('failed to register on firebase $e');
      }
    }
  }
  void gotoDashboard(){
    Navigator.pushAndRemoveUntil(context,MaterialPageRoute(builder:(context)=>VoterHome(ethClient: widget.ethClient,
        electionName: widget.electionName, electionaddress: widget.electionaddress)), (route) => false);
  }
}

      

CodePudding user response:

One way to achieve what you want is by making your page retain its state.

Try this code

  1. You have to add with AutomaticKeepAliveClientMixin to the screen like in the snippet below.
  2. Override this @override bool get wantKeepAlive => true;.
  3. Inside build method, add this super.build(context);.
class _TestScreen extends State<TestScreen> with AutomaticKeepAliveClientMixin<TestScreen> {
 
  @override
  bool get wantKeepAlive => true;

  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold();
  }

}

After doing this, your page will not call initState() everytime that page is loaded.

CodePudding user response:

When you navigate from VoteHome page to VoteRegister page, you use the push method. The push method returns a Future object. You can use the then method of Future to execute your code after VoteRegister was popped from the navigation stack or in other words the user pressed back button in appbar.

Navigator.of(context)
  .push(MaterialPageRoute(
     builder: (context) => VoteRegister(electionName:widget.electionName,ethClient: widget.ethClient, electionaddress:widget.electionaddress,adhar:adhar,)))
.then((value) {
        // you can do what you need here
        // setState etc.
    // also reload your data here
      });
  • Related