I fixed the error, the page, and viewmodel and the pagre needs to be transient
viewModel dosent hit the second time
Eduardo Gomez Romero
625
Reputation points
I have this login flow
StartupPage
public class StartupPageViewModel : BaseViewModel {
private readonly IAppService _appService;
private readonly ISecureStorage _secureStorage;
IDataService<DemyUser> dataService;
public StartupPageViewModel(IAppService appService, ISecureStorage secure, IDataService<DemyUser> dataService) {
_appService = appService;
_secureStorage = secure;
this.dataService = dataService;
CheckAuth();
}
private async void CheckAuth() {
var currentUserEmail = await _secureStorage.GetAsync(Constants.LOGGED_USER);
if (string.IsNullOrEmpty(currentUserEmail)) {
if (DeviceInfo.Platform == DevicePlatform.WinUI) {
Shell.Current.Dispatcher.Dispatch(async () => {
await Shell.Current.GoToAsync($"//{nameof(LoginPage)}", true);
});
} else {
await Shell.Current.GoToAsync($"//{nameof(LoginPage)}", true);
}
} else {
var loggedUser = await dataService.GetByEmailAsync<DemyUser>(Constants.USERS,
currentUserEmail);
FlyoutHelper.CreateFlyoutHeader(loggedUser);
FlyoutHelper.CreateFlyoutMenu(loggedUser?.CurrentRole!);
await NvigationHelper.NavigatoToDashboardRoleAsync(loggedUser?.CurrentRole!);
}
Login
public partial class LoginPageViewModel(IDataService<DemyUser> dataService, IAppService appService,
IAuthenticationService authenticationService, ISecureStorage storage) : BaseViewModel {
[ObservableProperty]
bool isPopOpen;
[ObservableProperty]
DemyUser user = new();
[RelayCommand]
void OpenPopUp() {
IsPopOpen = true;
}
[RelayCommand]
async Task Login() {
IsBusy = true;
//var user = await authenticationService.LoginWithEmailAndPassword("s@s.com", "123456");
var user = await authenticationService.LoginWithEmailAndPassword(User.Email!, User.Password!);
if(user is not null) {
var currentUser = await dataService.GetByEmailAsync<DemyUser>(Constants.USERS,
user!.Info.Email);
await storage.SetAsync(Constants.LOGGED_USER, currentUser!.Email!);
if (currentUser?.CurrentRole is not null) {
FlyoutHelper.CreateFlyoutMenu(currentUser.CurrentRole!);
FlyoutHelper.CreateFlyoutHeader(currentUser);
await appService.NavigateTo($"//{currentUser.CurrentRole}DashboardPage", true);
} else {
await appService.NavigateTo($"//{nameof(RoleSelectionPage)}", true);
}
}
IsBusy = false;
}
[RelayCommand]
public void Appearing() {
//ClearUserFields();
}
[RelayCommand]
async Task Register() {
IsBusy = true;
var completeName = $"{User.Firstname} {User.Lastname}";
var user = await authenticationService.RegisterWithEmailAndPassword(
User.Email!, User.Password!, completeName!);
if(user != null) {
User.DemyId = NumberGenerator.GenerateRandomNumberString(8);
var uid = await dataService.AddAsync("Users", User);
await dataService.UpdateAsync<DemyUser>("Users", uid, uid, Constants.UID);
await appService.DisplayAlert("Congratulations", "Registration successful", "OK");
IsPopOpen = false;
IsBusy = false;
}
IsBusy = false;
}
RolseSelectionRole
ISecureStorage _secureStorage;
private readonly IDataService<DemyUser> _dataService;
[ObservableProperty]
string? welcomeText;
public ObservableCollection<UserRoles>? Roles { get; set; }
string? selectedRole;
string? CurrentUserEmail;
DemyUser? demyUser;
public RoleSelectionPageViewModel(IDataService<DemyUser> dataService, ISecureStorage secureStorage) {
_dataService = dataService;
_secureStorage = secureStorage;
InitPopUp();
}
private async void InitPopUp() {
Roles = GetRoles();
CurrentUserEmail = await _secureStorage.GetAsync(Constants.LOGGED_USER);
demyUser = await _dataService.GetByEmailAsync<DemyUser>(Constants.USERS, CurrentUserEmail);
WelcomeText = $"Welcome {demyUser?.FullName}, please chose a role";
}
[RelayCommand]
public void RoleSelected(UserRoles SelectedRole) {
foreach (var role in Roles!) {
role.IsSelected = role == SelectedRole; // Set IsSelected to true only for the selected rol
if (role.IsSelected) {
role.SelectedColor = Constants.SelectedColor;
} else {
role.SelectedColor = Constants.DefaultUnselectedColor;
}
}
selectedRole = SelectedRole.Name.ToString();
}
[RelayCommand]
public async Task UpdateUserCurrentRole() {
var currentUser = await _dataService.GetByEmailAsync<DemyUser>(Constants.USERS,
demyUser!.Email!);
if (currentUser is not null) {
currentUser.Roles ??= [];
currentUser.CurrentRole = selectedRole;
if (!currentUser.Roles.Contains(selectedRole!)) {
currentUser.Roles.Add(selectedRole!);
}
await _dataService.UpdateAsync(Constants.USERS, currentUser.Uid!, currentUser);
}
var updatedUser = await _dataService.GetByEmailAsync<DemyUser>(Constants.USERS,
demyUser!.Email!);
FlyoutHelper.CreateFlyoutHeader(updatedUser);
FlyoutHelper.CreateFlyoutMenu(updatedUser?.CurrentRole!);
await NvigationHelper.NavigatoToDashboardRoleAsync(updatedUser?.CurrentRole!);
}
private ObservableCollection<UserRoles> GetRoles() {
return Roles = [
new() { Name = Helpers.Roles.Teacher },
new() { Name = Helpers.Roles.Student },
new() { Name = Helpers.Roles.Coordinator },
];
}
Everything is working as expectedI can change roles.
And everything gets updated
but I f I log out and enter with a new user
and attempt to change roles
I get the previews user, and the xaml gets messed up
Log out command
[RelayCommand]
async Task SignOut() {
secureStorage.RemoveAll();
FlyoutHelper.GeetDefaultMenuItems();
await appService.NavigateTo($"//{nameof(LoginPage)}", true);
Chage roles command
[RelayCommand]
async Task SignOut() {
secureStorage.RemoveAll();
FlyoutHelper.GeetDefaultMenuItems();
await appService.NavigateTo($"//{nameof(LoginPage)}", true);
FlyoutHelprer
ublic static class FlyoutHelper {
public static void CreateFlyoutHeader(DemyUser? updatedUser) {
IAppService appService = new AppService();
Shell.Current.FlyoutHeader = new FlyoutHeader(
new FlyoutHeaderViewModel(
$"{updatedUser!.Firstname} {updatedUser.Lastname}"!,
updatedUser.DemyId!,
updatedUser.Email!,
updatedUser.CurrentRole!,
appService
));
}
public static void CreateFlyoutMenu(string role) {
switch (role) {
case nameof(Roles.Student):
CreateStudentItems();
break;
case nameof(Roles.Teacher):
CreateTeacherItems();
break;
case nameof(Roles.Coordinator):
CreateCoordintorItems();
break;
}
}
private static void CreateStudentItems() {
var studentItems = new FlyoutItem() {
Title = "Welcome",
Route = nameof(StudentDashboardPage),
FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems,
Items = {
new ShellContent {
Title = "Welcome",
ContentTemplate = new DataTemplate(typeof(WelcomePage)),
},
new ShellContent {
Title = "Join meeting",
ContentTemplate = new DataTemplate(typeof(JoinMeetingPage)),
}
}
};
if (!Shell.Current.Items.Contains(studentItems)) {
Shell.Current.Items.Add(studentItems);
}
}
private static void CreateTeacherItems() {
var TeacherItems = new FlyoutItem() {
Title = "Welcome",
Route = nameof(TeacherDashboardPage),
FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems,
Items = {
new ShellContent {
Title = "Welcome",
ContentTemplate = new DataTemplate(typeof(WelcomePage)),
},
new ShellContent {
Title = "My courses",
ContentTemplate = new DataTemplate(typeof(MyCoursesPage)),
},
new ShellContent {
Title = "New lecture",
ContentTemplate = new DataTemplate (typeof(NewLecturePage)),
},
new ShellContent {
Title = "New Test",
ContentTemplate = new DataTemplate(typeof(NewTestPage)),
},
new ShellContent {
Title = "Schedule lecture",
ContentTemplate = new DataTemplate (typeof(NewLecturePage)),
},
new ShellContent {
Title = "Schedule test",
ContentTemplate = new DataTemplate(typeof(ScheduleTestPage)),
},
}
};
if (!Shell.Current.Items.Contains(TeacherItems)) {
Shell.Current.Items.Add(TeacherItems);
}
}
private static void CreateCoordintorItems() {
var CoordinatorItems = new FlyoutItem() {
Title = "Welcome",
Route = nameof(CoordinatorDashboardPage),
FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems,
Items = {
new ShellContent {
Title = "Welcome",
ContentTemplate = new DataTemplate(typeof(WelcomePage)),
},
new ShellContent {
Title = "Manage courses",
ContentTemplate = new DataTemplate(typeof(ManageCoursePage)),
},
new ShellContent {
Title = "Register student",
ContentTemplate = new DataTemplate(typeof(RegisterStudentPage)),
}
}
};
if (!Shell.Current.Items.Contains(CoordinatorItems)) {
Shell.Current.Items.Add(CoordinatorItems);
}
}
public static void GeetDefaultMenuItems() {
var defaultItems = new List<ShellContent> {
new() { ContentTemplate = new DataTemplate(typeof(StartupPage)),
Route = nameof(StartupPage), FlyoutItemIsVisible = false },
new() { ContentTemplate = new DataTemplate(typeof(LoginPage)),
Route = nameof(LoginPage), FlyoutItemIsVisible = false },
new() { ContentTemplate = new DataTemplate(typeof(NoInternetPage)),
Route = nameof(NoInternetPage), FlyoutItemIsVisible = false },
new() { ContentTemplate = new DataTemplate(typeof(RoleSelectionPage)),
Route = nameof(RoleSelectionPage), FlyoutItemIsVisible = false }
};
Shell.Current.Items.Clear();
foreach (var item in defaultItems) {
Shell.Current.Items.Add(item);
}
}
}
Demo