Reputation: 93
I am developing a blazor app which asks several questions to the user. I want to ask one question before proceeding to the next question. So, I have a list of questions, and I want to show each item from the list step-by-step instead of putting all the questions in a single view.
If I want to show all questions in a single page, then the following Index.razor will do. This is a working a code:
@foreach (var item in items)
{
<h2>@item.Question</>
}
@code
{
List<Item> items = new();
protected override async Task OnInitializedAsync()
{
items = await HttpClient.GetFromJsonAsync<List<Item>>(NavigationManager.BaseUri + "items");
}
}
where the Item
class is:
public class Item
{
public int Id { get; set; }
public string Question { get; set; }
}
BUT, I do not want that. I want to show one question at a time. Maybe something like this, i.e. where I can call some random question in a single view:
@* THIS CODE IS NOT WORKING *@
<h2>@items[3].Question</>
@code
{
List<Item> items = new();
protected override async Task OnInitializedAsync()
{
items = await HttpClient.GetFromJsonAsync<List<Item>>(NavigationManager.BaseUri + "items");
}
}
I am guessing this has something to do with the await
stuff, but cannot figure out at all.
Anyway, If I can get this right, then I can maybe continue writing code to call each item from the list one-by-one.
p.s For the rest of the code, I am just using the default Blazor template. The DbContext
looks like this:
public class QuestionsContext: DbContext
{
public DbSet<Item> Items { get; set; }
public QuestionsContext(DbContextOptions options) : base(options) { }
}
and the controller looks like this:
[Route("items")]
[ApiController]
public class ItemController : Controller
{
private readonly QuestionsContext _db;
public ItemController(QuestionsContextdb)
{
_db = db;
}
[HttpGet]
public async Task<ActionResult<List<Item>>> GetItems()
{
return await (_db.Items.ToListAsync());
}
}
Upvotes: 0
Views: 512
Reputation: 266
It is a bit hard to give a solution that would ideally fit your needs. For example, you haven’t really said how would you like the items to be changed — button click, timer or whatever.
Anyway, first of all, as already been mentioned you have to be sure your collection of items loaded by providing simple if-else
statement.
Define some private fields to store data and use it for displaying.
Then, you can create a button (for sake of example) that will trigger the question update, and define a method that will be triggered.
@if (items is null)
{
<p>Loading…</p
}
else
{
@_currentQuestion
<button type=“button” @onclick=“UpdateCurrentQuestion”> Update Question </button>
}
@code {
int _currentIndex = 0; // index to be incremented
string? _currentQuestion; // displayed question
List<Item> items = new();
protected override async Task OnInitializedAsync()
{
items = await HttpClient.GetFromJsonAsync<List<Item>>(NavigationManager.BaseUri + "items");
_currentQuestion = items[0].Question; // get the first question
}
void UpdateCurrentQuestion()
{
_currentIndex++;
_currentQuestion = items[_currentIndex].Question;
}
}
Unfortunately, I can’t test this right now, but it should do the trick.
Also, you can change the UpdateCurrentQuestion
method to async Task
and add a Task.Delay()
if you don’t want a button.
I hope it helps!
Upvotes: 1