Reputation: 569
Basically I have an activity indicator that doesn't display until all of the other code in the method has executed. I've looked and the IsBusy property is getting set to true on both the code side (login page) and the xaml binding (login xaml) so I know the correct value is at least getting passed around.
I'm pretty sure I have everything set up correctly as far as async / await goes to not lock anything.
I have a BaseViewModel class that all of my view models use. Here's the code in there for IsBusy:
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
Here's my XAML for login page. The activity indicator is placed inside a single Stack Layout inside the Content Page tag:
<ActivityIndicator IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
HeightRequest="40"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="100" Android="100" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
And here is the LoginPageViewModel code. If I'm understanding this correctly the indicator should display as soon as it's set to true on the first line and then disappear after the API call has been made and the user isn't authenticated.
public async void OnLogin()
{
IsBusy = true;
var isAuthenticated = await LoginPageValidation.IsAuthenticated(email, password);
if (!isAuthenticated )
{
IsBusy = false;
IsForgotPasswordLabelVisible = true;
DisplayUserAndPasswordMismatchPrompt();
return;
}
}
I'm sure the issue is something small but I'm just not seeing it.
EDIT: Adding IsAuthenticated methods
IsAuthenticated
public static async Task<bool> IsAuthenticated(string email, string password)
{
var isAuthenticated = false;
try
{
var payload = $"{{\n\t\"Email\":\"{email}\",\n\t\"Password\":\"{password}\"\n}}";
var response = await LoginApi.Authenticate(payload);
isAuthenticated = bool.Parse(response["isAuthenticated"].ToString());
}
catch (Exception e)
{
// log stuff here
}
return isAuthenticated;
}
Authenticate API call:
public static async Task<JObject> Authenticate(string payloadBody)
{
IRestResponse response = null;
try
{
var client = new RestClient($"{url}/authenticate");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("undefined", payloadBody, ParameterType.RequestBody);
response = client.Execute(request);
} catch (Exception e)
{
// log some bad stuff here
}
return JObject.Parse(response.Content);
}
Upvotes: 0
Views: 338
Reputation: 14971
Through your updated codes of Authenticate
method,you could change
client.Execute;
to
client.ExecuteAsync
in this case you will display your ActivityIndicator as your expect
Upvotes: 1
Reputation: 1507
Make sure your viewmodel implements INotifyPropertyChanged then:
public bool IsBusy
{
set { isBusy = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsBusy))); }
get { return isBusy; }
}
Upvotes: 0