0

This is the function that changes location:

string restaurantId = (string)e.Parameter;

Console.WriteLine(restaurantId);

await Shell.Current.GoToAsync($"location?restaurantId={restaurantId}");

Param is not undefined and it is consoled there. And the page changes, but the query param is empty string:

[QueryProperty("RestaurantId", "restaurantId")]
internal partial class LocationModel : ObservableObject
{
    [ObservableProperty]
    public string restaurantId;
       
    public LocationModel() 
    {
        Console.WriteLine(RestaurantId); // EMPTY
    }
}

This is AppShell.cs where routes are registered:

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute("login", typeof(LoginPage));
        Routing.RegisterRoute("home", typeof(MainPage));
        Routing.RegisterRoute("location", typeof(LocationPage));
    }
}

What am I doing wrong?

Julian
  • 5,290
  • 1
  • 17
  • 40
1baz
  • 148
  • 1
  • 9
  • 2
    Properties are not guaranteed to be set in the constructor – Jason Feb 12 '23 at 02:31
  • @Jason, then how do I pass a parameter and be guaranteed to retrieve it? – 1baz Feb 12 '23 at 03:21
  • 2
    You just should not assume the property will be available in the constructor. If you absolutely must have the value in the constructor, pass it as a parameter, not a navigation property – Jason Feb 12 '23 at 03:26
  • Read farther down in Maui Shell Navigation doc. It mentions at least two ways to process query parameters. – ToolmakerSteve Feb 12 '23 at 05:55
  • Query parameters should be defined on Views (or rather Pages), not Models or ViewModels, as described in the [documentation](https://learn.microsoft.com/dotnet/maui/fundamentals/shell/navigation#process-navigation-data-using-query-property-attributes). The property never gets set in your scenario, because you need to retrieve it in your View and then pass it along to the ViewModel/Model. Where's your Page defined? Can you show the code behind of your Page and where you set up the routes? – Julian Feb 12 '23 at 09:10

1 Answers1

0

One way to fix this is to use the [QueryProperty] on your LocationPage (the Page) and not on the LocationModel (the ViewModel), and then pass it along from the Page to the ViewModel.

LocationPage.xaml.cs

[QueryProperty(nameof(Id), "restaurantId")]
public partial class LocationPage : ContentPage
{
    private LocationModel _viewModel;

    public string Id
    {
        set => _viewModel.RestaurantId = value;
    }

    public LocationPage()
    {
        InitializeComponent();
        BindingContext = _viewModel = new LocationModel();
    }
}

LocationModel

public partial class LocationModel : ObservableObject
{
    [ObservableProperty]
    public string restaurantId;
}

This way you can retrieve the query parameter and pass it along to the ViewModel. You'll have to implement the logic for loading data in the ViewModel according to the passed RestaurantId yourself. You could also do this using a method, such as Load(string restaurantId) instead of using a property.

You can read more about how query parameters work in the official documentation.

Julian
  • 5,290
  • 1
  • 17
  • 40