Showing alert function when the button is click with Async and Await function

227 views Asked by At

I am have the username and password text filed with button . I am expecting when username or password is not correct that time I want to show alert view and message saying that incorrect username or password when user click the signing button . I am handing the concurrency with async and await . But the issue is the alert function is not getting called ..

Here is the my code ..

import SwiftUI

struct LoginView: View {
    @State private var username = ""
    @State private var password = ""
    @EnvironmentObject var viewModel: AuthViewModel
    
    var body: some View {
        
        NavigationStack {
            
            VStack {
                // Login Image
                Image("signin")
                    .resizable()
                    .scaledToFill()
                    .frame(width: 100, height: 120)
                    .padding(.vertical, 32)
                
                // form filed
                VStack(spacing: 24) {
                    InputView(text: $username, title: "username", placeholder: "[email protected]")
                        .autocapitalization(.none)
                    InputView(text: $password, title: "password", placeholder: "enter your password", isSecureField: true)
                    
                }
                .padding(.horizontal)
                .padding(.top, 15)
                
                // creating sign in button
                
                Button {
                    
                    Task {
                        try await viewModel.signIn(withEmail: username, password: password)
                    }
                    
                } label: {
                    HStack {
                        Text("Sign In")
                            .fontWeight(.semibold)
                        Image(systemName: "arrow.right")
                    }
                    .foregroundColor(.white)
                    .frame(width: UIScreen.main.bounds.width - 32 , height: 40)
                    
                }
                .background(Color(.systemBlue))
                .disabled(!formValid)
                .opacity(formValid ? 1.0: 0.5)
                .cornerRadius(10)
                .padding(.top ,24)
                
                Spacer()
                
                // sign up button
                
                NavigationLink {
                    RegistrationView()
                    // Hiding the navigation back button hidden .
                        .navigationBarBackButtonHidden(true)
                } label: {
                    HStack(spacing: 3) {
                        Text("Dont have an account?")
                        Text("Sign up")
                            .fontWeight(.bold)
                    }
                    .font(.system(size: 14))
                }
            }
            .alert(isPresented: $viewModel.isErrorOccured) {
                Alert(title: Text("Incorrect Username or password"), message: Text(viewModel.customError?.localizedDescription ?? ""),dismissButton: .default(Text("Okay")))
            }
        }
    }
}
1

There are 1 answers

3
Shehata Gamal On BEST ANSWER

BTW there is no code in your snippet that shows where you change value of showingAlert to true and curly braces after the Button expects action code not a view , the correct way is to attach .alert modifier to closing of VStack

VStack {
   // Login Image
   Image("signin")
   .....
   .....
   .....
}
.alert(isPresented: $viewModel.isErrorOccured) {
   Alert(title: Text("Incorrect Username or password"), message: Text(viewModel.customError?.localizedDescription ?? ""),dismissButton: .default(Text("Okay")))
}

And replace

Task {
    if showingAlert == false {
      try await viewModel.signIn(withEmail: username, password: password)
   } else {
       alertView() // this function not getting called.
   }
 }

with

Task {
      try await viewModel.signIn(withEmail: username, password: password)
}