Reputation: 1320
I started looking into Openweathermap API (weather Data). The Api response is a Json file. I managed to get everything working with MS WinForms in (VisualStudio).
Now I wanted to do the same on my BlazorWebpage. But I cant get it to work. I am stuck maybe you could point me in the right direction.
In the Winforms project I succsessfull call the Api with this code:
private async Task CallWeatherApiAsync()
{
oneDayWeatherInfo = new OneDayWeatherDataModel();
using (HttpResponseMessage response = await client.GetAsync(client.BaseAddress))
{
if (response.IsSuccessStatusCode)
{
oneDayWeatherInfo= await response.Content.ReadAsAsync<OneDayWeatherDataModel>();
}
}
}
Everything from the api response data "goes" in the right places. The WeatherDataModel is the C# Class structur "from" the jsonfile. The Classes looking like this (on first read skip this):
namespace Blazor_WeatherApi.Models
{
public class OneDayWeatherDataModel
{
//Name of the City
public string Name { get; set; }
public Main Main { get; set; }
public Coord Coord { get; set; }
public List<Weather> Weather { get; set; }
public Wind Wind { get; set; }
public Clouds Clouds { get; set; }
public Sys Sys { get; set; }
public int Visibility { get; set; }
public int Dt { get; set; }
public int Timezone { get; set; }
public int Id { get; set; }
public int Cod { get; set; }
}
public class Main
{
public double Temp { get; set; }
public double Feels_like { get; set; }
public double Temp_min { get; set; }
public double Temp_max { get; set; }
public int Pressure { get; set; }
public int Humidity { get; set; }
}
public class Coord
{
public double Lon { get; set; }
public double Lat { get; set; }
}
public class Weather
{
public int Id { get; set; }
public string Main { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
}
public class Wind
{
public double Speed { get; set; }
public int Deg { get; set; }
public double Gust { get; set; }
}
public class Clouds
{
public int All { get; set; }
}
public class Sys
{
public int Type { get; set; }
public int Id { get; set; }
public double Message { get; set; }
public string Country { get; set; }
public int Sunrise { get; set; }
public int Sunset { get; set; }
}
}
Now to my problem I created a blazor project and I can call the data from the root ModelClass like Name (first Propertie in the class Model) But I cant use anything else that is one class deeper besides root class. E.g. If I want to get the temperatur value root->Main->Temp then I get an error. I used the same ClassModel in the winforms project there it was successful.
Here the Blazor code that works only for the Properties from the "root class":
@page "/weather"
@inject HttpClient http;
<h3>ApiCall</h3>
<button class="btn btn-primary" @onclick="@GetWeatherData">Get Weather</button>
<table>
<tr>
<td>@weatherModel.Name</td>
</tr>
<tr>
<td>@weatherModel.Dt</td>
</tr>
@*<tr>
<td>@weatherModel.Main.Temp</td> // IF I DECOMMENT THIS 3 LINES I GET the ERROR
</tr>*@
</table>
@code {
OneDayWeatherDataModel weatherModel = new OneDayWeatherDataModel();
private async Task GetWeatherData()
{
weatherModel = await http.GetJsonAsync<OneDayWeatherDataModel>
("https://api.openweathermap.org/data/2.5/weather?id=...");
}
}
If I comment the 3 lines out I have a working blazer api call and I get the name of the city from the web-api-call from openweathermap. BUT...
The Error occures when I decomment @weatherModel.Main.Temp the project freezes an Visual Studio tells me it is in HoldModus (System.NullReferenceException: "Object reference not set to an instance of an object.")
This happens at the moment I browse to the page NOT after I click the button ??? Any idea what I did wrong? And sorry that the post is so long and intertwined :)
Upvotes: 0
Views: 261
Reputation: 1532
The problem is that you are manually instantiating the class in the following line and not setting the 'Main' property to anything, and therfore it is null
OneDayWeatherDataModel weatherModel = new OneDayWeatherDataModel();
You could ensure that you populate the property or use access it with the following to avoid the null reference error:
<td>@weatherModel?.Main?.Temp</td>
However you might also want to consider something like the below so that that table doesnt show unless it's got the data from the API:
@if (weatherModel != null) {
<table>
<tr>
<td>@weatherModel.Name</td>
</tr>
<tr>
<td>@weatherModel.Dt</td>
</tr>
<tr>
<td>@weatherModel.Main.Temp</td>
</tr>
</table>
}
@code {
OneDayWeatherDataModel weatherModel = null;
private async Task GetWeatherData()
{
weatherModel = await http.GetJsonAsync<OneDayWeatherDataModel>
("https://api.openweathermap.org/data/2.5/weather?id=...");
}
}
Upvotes: 1