2

My receiving Viewmodel (QuestionsPageViewModel) is not receiving the TopidId after passing it through Shell navigation as shown in the code below. I have placed the breakpoint at the LoadQuestions method in the QuestionsPageViewModel. When it is called, TopicId is null. What am I missing?

HomePageViewModel

//This is in a command executed after clicking a button. And this is working fine
await Shell.Current.GoToAsync($"{nameof(QuestionsPage)}?TopicId={pack.TopicId}");

QuestionsPageViewModel

[INotifyPropertyChanged]
[QueryProperty(nameof(TopicId), nameof(TopicId))]
    public partial class QuestionsPageViewModel
    {
        public ObservableRangeCollection<Question> QuestionsList { get; set; } = new();
        [ObservableProperty]
        string? title;

        [ObservableProperty]
        public string topicId;

        public QuestionsPageViewModel()
        {
            LoadQuestions();
        }

        async void LoadQuestions()
        {
            Title = Utilities.ConvertTopicIdToString(short.Parse(TopicId));

            try
            {
                using (var context = new DataContext())
                {
                    QuestionPack questionPack = context.QuestionPacks
                        .First(x => x.TopicId == short.Parse(TopicId));

                    var questions = JsonConvert.DeserializeObject<List<Question>>(questionPack.Questions);
                    QuestionsList.AddRange(questions);
                }

            }
            catch (Exception ex)
            {
                await Shell.Current.DisplayAlert("Error", $"Something went wrong: {ex}", "Cancel");
            }
        }
    }
}
4
  • Did you put a breakpoint on the gotoasync call, and verify that pack.topicid is not null? Why is property in one place topicId instead of TopicId? Commented Jun 3, 2022 at 16:50
  • 2
    I believe that ObservableProperty attribute is supposed to turn the private field into a public property Commented Jun 3, 2022 at 17:05
  • 1
    @ToolmakerSteve Yes I did. pack.topidId is not null. and as @Jason said, ObservableProperty makes it behind the scenes Commented Jun 4, 2022 at 16:28
  • @TanakaMawere could you please mark my answer as accepted if it was what you needed? Commented Jun 6, 2022 at 11:28

1 Answer 1

6

First of all, your field topicId should be private. CommumityToolkit.Mvvm will generate for you the public property.

Secondly, topicId is null because you're checking its value in a function called in the constructor. While you're executing the constructor, the shell navigation parameters are not initialized yet.

If you want to be sure that LoadQuestions() will be called after topicId is initialized, CommumityToolkit.Mvvm since version 8.0.0 should generate a partial method that can be used to execute some code after an ObservableProperty changes its value. In your case the name of this method should be OnTopicIdChanged(string value).

Try adding in your viewmodel this method and remove the function call from the constructor:

partial void OnTopicIdChanged(string value)
{
    LoadQuestions();
}
Sign up to request clarification or add additional context in comments.

8 Comments

CommunityToolkit.Mvvm does not recognise that there is such a method
@TanakaMawere you need to use the latest preview version of CommunityToolkit.Mvvm (currently 8.0.0-preview4)
Is it stable enough to include into a production application? After updating, I am noticing errors from [ICommand]. RelayCommand is good enough without further edits?
Honestly I wouldn't use MAUI itself in a production application yet, but that's up to you. Anyway this is a very simple feature that you can verify firsthand in the autogenerated code, so it shouldn't cause any troubles. Can't guarantee for other sections of the toolkit. If you are worried about the preview, you could create TopicId as a classic property, without the ObservableProperty attribute and use the setter.
What kind of errors? I've used [ICommand] without problems.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.