Home > other >  Buttons don't count chapter ids correctly from json using linq in c#
Buttons don't count chapter ids correctly from json using linq in c#

Time:11-11

I have a program where the user has to get the text from json based on the chapter clicked within the protocol by the listview item (the chapters)

What goes wrong is when the user clicks the next button when he does not choose the first chapter within the protocol. He always gets to see ID 2 which belongs to the first chapter! How do I get it to click on whatever chapter the user sees the text with the following id?

the next problem i have is when i am in the last chapter and i click back then i land on another chapter System.NullReferenceException: 'Object reference not set to an instance of an object.' get on string nextTitile = _protocol.Name " - " content.NavTitle;

How do i fix this?

Here the user selects the chosen chapter within the protocol

    //for chosen step inside protocol

    //for chosen step inside protocol
    public void Handle_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        //change title based on clicked step
        var tappedStep = (Content)MyListView.SelectedItem;
        int stepIndex = (default);
        Navigation.PushAsync(new StepView(_protocol, Title, tappedStep.ChapterTitle, stepIndex));
        //Deselect item
        ((ListView)sender).SelectedItem = null;
    }

here is the stepview class where the user gets the text associated with the chosen chapter. With the corresponding back and next button to go to the next text

public partial class StepView : ContentPage
{
    //get step
    private Protocol _protocol;

    //go to selected step
    public StepView(Protocol protocol, string title, string chapterTitle)
    {
        _protocol = protocol;
        InitializeComponent();
        Title = title   " - "   chapterTitle;
        // get label text
        lblText.Text = protocol.Contents.FirstOrDefault(x => x.ChapterTitle == chapterTitle).Text;
    }

    private int index;

    public void BtnBack_Clicked(object sender, EventArgs e)
    {
        index--;
        var firstId = _protocol.Contents.FirstOrDefault(x => x.Contentid != null).Contentid;
        BtnNext.IsEnabled = true;
        if (index == firstId - 1)
        {
            BtnBack.IsEnabled = false;
        }
        var content = _protocol.Contents.ElementAtOrDefault(index);
        lblText.Text = content?.Text;
        //get current navTitle on button click
        getNewNavTitle(content);
    }

    public void BtnNext_Clicked(object sender, EventArgs e)
    {
        index  ;
        BtnBack.IsEnabled = true;
        if (index == _protocol.Contents.Count - 1)
        {
            BtnNext.IsEnabled = false;
        }
        var content = _protocol.Contents.ElementAtOrDefault(index);
        lblText.Text = content?.Text;
        //get current navTitle on button click
        getNewNavTitle(content);
    }

    //get new protocol   chapter based on btnBack and btnNext
    private void getNewNavTitle(Content content)
    {
        Title = null;
        string nextTitile = _protocol.Name   " - "   content.NavTitle;
        Title = nextTitile;
    }

    //go back to home
    public void btnHome_Clicked(object sender, EventArgs e)
    {
        //go to mainpage
        Navigation.PushAsync(new MainPage());
    }

This is the json I use

   {
  "protocols": [
    {
      "id": "1",
      "name": "Pols meten",
      "contents": [
        {
          "chapterTitle": "Voorzorg",
          "contentid": "1",
          "navTitle": "Voorzorg",
          "text": "voor blabla"
        },
        {
          "contentid": "2",
          "navTitle": "Voorzorg",
          "text": "voor blabla2"
        },
        {
          "contentid": "3",
          "navTitle": "Voorzorg",
          "text": "voor blablabla3"
        },
        {
          "contentid": "4",
          "chapterTitle": "Handeling",
          "navTitle": "Handeling",
          "text": "Handeling blabla"
        },
        {
          "contentid": "5",
          "navTitle": "Handeling",
          "text": "Handeling blabla2"
        },
        {
          "contentid": "6",
          "navTitle": "Handeling",
          "text": "Handeling blybli3"
        },
        {
          "contentid": "7",
          "chapterTitle": "Nazorg",
          "navTitle": "Nazorg",
          "text": "Nazorg blabla"
        },
        {
          "contentid": "8",
          "navTitle": "Nazorg",
          "text": "Nazorg blabla2"
        },
        {
          "contentid": "9",
          "navTitle": "Nazorg",
          "text": "Nazorg blybli3"
        }
      ]
    }
  ]
}

And this are my Domain Classes

public partial class RootObject
{
    [JsonProperty("protocols")]
    public List<Protocol> Protocols { get; set; }
}

public partial class Protocol
{
    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("contents")]
    public List<Content> Contents { get; set; }
}

public partial class Content
{
    [JsonProperty("contentid")]
    public long Contentid { get; set; }

    [JsonProperty("chapterTitle", NullValueHandling = NullValueHandling.Ignore)]
    public string ChapterTitle { get; set; }

    [JsonProperty("text")]
    public string Text { get; set; }
}

How do i fix my problem

CodePudding user response:

I think both of these problems are related to not setting the index property in your StepView constructor. Without an explicit value, a new StepView instance will have its index property set to default(int), which is 0.

Clicking the "Next" button always shows the second step since BtnNext_Clicked is incrementing index (to 1, since it was 0) and then displaying the item at that index.

Similarly, BtnBack_Clicked is decrementing index (to -1, since it was 0), which means calling _protocol.Contents.ElementAtOrDefault(index) will return null - later causing the NullReferenceException in getNewNavTitle.

You need to update the StepView constructor so that it sets the initial value of index correctly:

public StepView(Protocol protocol, string title, string chapterTitle, int stepIndex)
{
    _protocol = protocol;
    InitializeComponent();
    Title = title   " - "   chapterTitle;
    // get label text
    lblText.Text = protocol.Contents.FirstOrDefault(x => x.ChapterTitle == chapterTitle).Text;

    // Set the "index" property here. You need to make sure that the "stepIndex"
    // constructor parameter has the appropriate value.
    index = stepIndex;
}
  • Related