0

I am trying to build an app that helps you make dinner decisions. I want the user to be able to click a button and the app should display one random dinner name using an API. I am trying to display the data from an API. This is my code so far. I am getting a null exception. Any assistance is appreciated :)

namespace jello
{
    public partial class NetworkingManager : ContentPage
    {
        private string name;
        public string url;
        public String Name {
            get { return name; }
            set
                {
                    name = value;
                }
        }

        public class RecipeClass
        {
            public class Data
            {
                public string strMeal { get; set; }
            }
            public Data data { get; set; }
        }

        public const string Url = "https://www.themealdb.com/api/json/v1/1/search.php?f=a";
        public HttpClient client = new HttpClient();
    
        public NetworkingManager()
        {
            InitializeComponent();
            BindingContext = this;
            name = GetDetails();
        }
    
        string temp;

        public async void  GetString()
        {
            var content = await client.GetStringAsync(Url);
            temp = content;
        }
    
        public RecipeClass getObj()
        {  
            var output = JsonConvert.DeserializeObject<RecipeClass>(temp);
            return output;
        }
           
        public String GetDetails()
        {
            var name = getObj().data.strMeal;
            return name;
        }
    }
}
Palle Due
  • 5,929
  • 4
  • 17
  • 32
  • Can you give us a sample of the JSON you get from the API ? – Achon Mar 02 '21 at 07:32
  • 1
    You never call `GetString` and your `temp` remains `null` in `ctor()` -> `getDetails()` -> `getObj()` call – Quercus Mar 02 '21 at 07:38
  • 1
    do not use `async void` use `async Task`. – Marco Mar 02 '21 at 07:41
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – derpirscher Mar 03 '21 at 07:44

2 Answers2

0

You can do this :

    public async void  GetMeal()
    {
        var content = await client.GetStringAsync(Url);
        var output = JsonConvert.DeserializeObject<RecipeClass>(content);
        Name = output.data.strMeal;
    }

And call it like this :GetMeal() you don't need to put name = GetMeal(); Your property Name is set at the end.

Achon
  • 90
  • 4
  • 1
    Read the recommendations [here](https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming): Avoid async void. – Palle Due Mar 02 '21 at 09:14
0

Your underlying problem is that you want to call something asynchronous from your constructor and constructors cannot be async. You can solve that by using this asynchronous factory pattern:

First make your constructor private so it cannot be called from the outside:

private NetworkingManager()
{
    InitializeComponent();
    BindingContext = this;
}

Then you make an async method to initialize it:

private async Task<MyClass> InitializeAsync()
{
    var temp = await GetStringAsync();
    var output = JsonConvert.DeserializeObject<RecipeClass>(temp);
    name = output.data.strMeal;
    return this;
}

public async Task<string> GetStringAsync()
{
    return await client.GetStringAsync(Url);
}

And finally an async method to create it:

public static Task<NetworkingManager> CreateAsync()
{
    var manager = new NetworkingManager();
    return manager.InitializeAsync();
}

You construct the instance from the outside by doing:

NetworkingManager instance = await NetworkingManager.CreateAsync();

And finally a note about naming: Don't call a class member temp. There's nothing temporary about it. It lives as long as the instance. Don't call a method the very general GetString if it gets a specific string like here. Call it GetMealString or GetMealName or something. The same goes for getObj, which should start with a capital letter by the way. Name your mebers in a clear and specific way and the program's structure will become much clearer to you.

Palle Due
  • 5,929
  • 4
  • 17
  • 32