Problem with async/await method, can't go through all requests [closed] - swift

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 14 days ago.
Improve this question
I have a func, when I run the function it only goes through the first 2 requests and ignore last two requests(sessionId and getDetails)
If I remove validateUser, for example, then it doesn't ignor the sessionId
func requestAllAuthNetwork(username: String, password: String) async throws {
Task {
let token = try await getToken()
let validateUser = try await validateUser(username: username, password: password, token: token.requestToken)
let sessionId = try await createSession(token: token.requestToken)
let getDetails = try await getDetails(sessionId.sessionID)
}
}
I try method "withThrowingTaskGroup" but the result was the same.
And some other method but nothing helped me.
func requestAllAuthNetwork(username: String, password: String) async throws {
try await withThrowingTaskGroup(of: Void.self) { group in
let token = try await getToken()
let validateUser = try await validateUser(username: username, password: password, token: token.requestToken)
try await group.next()
group.addTask {
let sessionId = try await self.createSession(token: token.requestToken)
let getDetails = try await self.getDetails(sessionId.sessionID)
}
try await group.waitForAll()
}
}

You are ignoring your errors.
func requestAllAuthNetwork(username: String, password: String) async throws {
//Task { //Remove this
let token = try await getToken()
let validateUser = try await validateUser(username: username, password: password, token: token.requestToken) //If this throws an error
let sessionId = try await createSession(token: token.requestToken) //This line won't run, this is by design.
let getDetails = try await getDetails(sessionId.sessionID)
// } //Remove this
}
If the function is marked async your don't need Task and a floating Task like that is a perfect source for a race condition.
Then where you call requestAllAuthNetwork(username: String, password: String)
make sure you have a do try catch
do{
try await requestAllAuthNetwork(username: "YourUsername", password:"Your password")
}catch{
print(error)
}
I am pretty certain you will get an error in the console now.
When something try and then throw the operations below that line will not get executed. You have to resolve this for the rest of the lines to run.

Related

async/await method throws exception -type int is not a subtype of bool

I am calling a graphql endpoint which returns success, but I do get an exception on the calling method.
Here is my calling method -
await AmplifyInstance()// this is where I get the exception. Snip below
.createUserOnAzureCosmosDB(user)
.then((result) {
print(result['data']['userPhoneNumber']);
_intlPhoneFieldController.text =
(result['data']['userPhoneNumber'].toString())
.substring(1);
_incrementStep('continueOnProfilePictureWidget');
});
Here is the called method -
Future<dynamic> createUserOnAzureCosmosDB(User user) async {
HttpLink link = GlobalVariables().graphqlEndpoint;
GraphQLClient graphQlClient = GraphQLClient(
link: link,
cache: GraphQLCache(
store: InMemoryStore(),
),
);
try {
QueryResult mutationResult = await graphQlClient.mutate(
//Mutation query here
if (mutationResult.data?['createUser'] != null) {
print('Created user on Cosmos DB');
registerUserStatus['result'] = true;
registerUserStatus['data'] = mutationResult.data?['createUser'];
}
} on ApiException catch (e) {
print('Mutation failed: $e');
registerUserStatus['result'] = false;
registerUserStatus['errorMessage'] = e.message;
}
return registerUserStatus;
}
And the returned registerUserStatus is just an array -
var registerUserStatus = {};
Here is the exception -
UPDATE eamirho3ein
Here is the result of print("result=$result);
I/flutter (14224): result = {result: true, data: {__typename: User, partitionKey: user, userPhoneNumber: 14160000000, userDisplayName: testuser, avatarUrl: www.url.com, createdAt: Today}}
This is not actually an answer, but rather a way to find the answer more easily yourself:
then chains make it increasingly hard to find your problem, because the compiler/debugger/IDE has a harder time pointing you to it. So don't do it.
With async/await available from the beginning, there never has been a reason to use then in any Dart program.
await AmplifyInstance().createUserOnAzureCosmosDB(user).then((result) {
Is equivalent to just writing:
final result = await AmplifyInstance().createUserOnAzureCosmosDB(user);
And then continuing on with the code you had put in the lambda function in the then part. Obviously, you need to remove the closing bracket somewhere too now.
This way, your error will actually pop up where it happens, not at the await of a huge chain that leaves you wondering what the problem might be.

http put did not send any response in flutter

Hey I have this app where I can update status, and I use http.put method, but it takes forever to response. I got this error
error
And here is the code for http.put
Future<void> mapEventToState(
Emitter<ReportStatusState> emit, ReportStatusEvent event) async {
emit(ReportStatusLoading());
ReportStatusPut statusPut = event.statusPutBody;
// ReportStatusModel model =
// await apiAuthRepository.updateReportStatus(statusPut, event.id);
ReportStatusModel model = await updateReportStatus({'biaya': '0', 'status': 'SELESAI'}, event.id);
print(model);
if (!model.success) {
emit(ReportStatusFailure(model.message));
}
print(model.code);
emit(ReportStatusSuccess());
}}
Future<ReportStatusModel> updateReportStatus(
Map data, String id) async {
final SharedPreferencesManager sharedPreferencesManager =
locator<SharedPreferencesManager>();
String? token =
sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken);
try {
final response = await http.put(
Uri.parse('https://api.komplekku.com/officer/api/report/v1/$id'),
body: json.encode(data),
headers: {'Authorization': 'Bearer $token'});
return ReportStatusModel.fromJson(json.decode(response.body));
} catch (e) {
throw Exception(e);
}
}
There is nothing wrong with the API, I already check using Postman and it worked perfectly fine, Anyone know what went wrong?

Is there any error in the try-catch exception handling below?

I tried to handle an exception while a user is trying to login after being authenticated by firebase. But this try-catch is not working in my flutter project.
Can someone let me know where did i go wrong? I have attached my code below.
Thank you in advance.
class AuthService {
//Creating an instance of firebase.
final auth.FirebaseAuth _firebaseAuth = auth.FirebaseAuth.instance;
User? _userFromFirebase(auth.User? user) {
if (user == null) {
return null;
}
return User(user.uid, user.email);
}
Stream<User?>? get user {
return _firebaseAuth.authStateChanges().map(_userFromFirebase);
}
Future<User?> signInWithEmailAndPassword(
String email,
String password,
) async {
try {
final credential = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
return _userFromFirebase(credential.user);
} on Exception catch (_, e) {
//I want to display a toast message if the login fails here.
print(e);
}
}
Future<void> signOut() async {
return await _firebaseAuth.signOut();
}
}
In your try-catch block you are catching Exception types, but Firebase Authentication has its own exception type, FirebaseAuthException.
For possible error codes for this specific sign-in see here, but there are others as well.
Check the following code:
try {
final credential = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
return _userFromFirebase(credential.user);
} on FirebaseAuthException catch (e) {
// here you will have the different error codes in `e.code`
// for example `invalid-email` or `wrong-password`
}
It is up to you how do you handle these errors. You can return the error code for example and handle it from where you call this function (as h8moss suggested in comment).
And keep in mind that there are other possible reasons for a sign-in to fail than FirebaseAuthException. For example network connection can be down. So a more complete solution to catch other errors as well would be something like:
try {
// sign in
} on FirebaseAuthException catch (e) {
// handle Firebase Authentication exceptions
} catch (e) {
// handle other exceptions
}

How to fetch string?

I have code like this:
Future<http.Response> makeRequest() async {
return await http.get(Uri.parse(url));
}
my "url" is a string, and it is working. From the internet i got string like "10" or "125", but when i use this method in my project and im converting it to string it only writes me an error:
Instance of 'Future Response'
, how can i take my string from the internet?
this is my url:
https://apialgorytm20210606150610.azurewebsites.net/algorytm/5w5
Future<String> getObjectFromAPI() async {
var response = await http.get(Uri.parse('www.myAPI.com/getData'),); //1
if (response.statusCode == 200) { //2
return(jsonDecode(response.body)["yourObjectHere"]); //3
} else {
return 'error';
}
}
Here you go.
Put your API url in line 1.
Line 2 checks if you receive a 200OK return or some kind of error code. Line 3 prints the decoded JSON response from the API, and you can enter the specific object you want to fetch as well
Future makeRequest() async {
var res= await http.get(Uri.parse(url));
If(res.statusCode==200){
print(res.body);
return res.body;}else{return null;}
}
now use the above function
var data=makeRequest();
print(data);

How can i convert Future<User> to User in my class? [duplicate]

This question already has answers here:
What is a Future and how do I use it?
(6 answers)
Closed 2 years ago.
What i am trying to do is i am fetching profile from fetchUser.But i don't know any other way that i can pull http data other than string.
class FollowingUserModel {
final String id;
final String author;
User profile;
final String profileid;
FollowingUserModel({this.id, this.profileid, this.author, this.profile}) { profile = fetchUser() as User; }
Future<User> fetchUser() async{
final response = await http.get("$SERVER_IP/api/users/$profileid/?format=json");
if (response.statusCode == 200) {
var responseJson = json.decode(response.body);
return User.fromJSON(responseJson);}}
factory FollowingUserModel.fromJSON(Map<String, dynamic> jsonMap) {
return FollowingUserModel(
id: jsonMap['id'] as String,
author: jsonMap['author'] as String,
profileid: jsonMap['profile'] as String,
);}}
Does anybody know how to do it?
Just create an asynchronous function .
If you have Future<User>, to convert it to User, you need to add await; and to use await, you need to add async:
Future<void> test() async {
User user = await fetchUser();
}
You can learn more about asynchronous function here
From where you are calling do this,
User user = await followingUserModel.fetchUser();
Future<User> means it will return an User object by asynchronously(in future), so make the call with await, then your code will wait till it get the return.