I'm trying to implement "live" input validation. The problem I have been facing for a while now is how to live check if the username already exists in the database.
For all database requests I am using Volley POSTs to an PHP API which resulted in:
private boolean checkTaken(String username, Context context){
boolean taken;
Volley.getInstance(context).addToRequestQueue(new StringRequest(Request.Method.POST, url, output -> taken = output.contains("taken"), error -> {}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", username);
return params;
}
@Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
});
return taken;
}
Which would have been great but doesn't work because the return statement is reached long before the API response has arrived. That's when I discovered RequestFutures and tried to implement them as I saw here:
private boolean checkTaken(String username, Context context){
RequestFuture<String> taken = RequestFuture.newFuture();
Volley.getInstance(context).addToRequestQueue(new StringRequest(Request.Method.POST, url, taken, error -> {}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", username);
return params;
}
@Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
});
try {
return taken.get(500, TimeUnit.MILLISECONDS).contains("taken");
} catch (InterruptedException | ExecutionException | TimeoutException e) {
return false;
}
}
Unfortunately it doesn't work even if I increase the timeout to an unbearable amount, the taken.get()
never gets resolved. I think it's because the taken
used in the request is interpreted as a new variable for the output and not as the actual FutureRequest.
I would be very thankful for a hint why this doesn't work or another solution for my problem.
Method call:
if (!email.matches(regex)){
return "Username has an invalid format";
} else if (checkTaken(username, context)){
return "Username already taken";
} else{
return null;
}