Why can I not update public List<string> Images
property when OnGetAsync
method returns the data?
I am trying render the images on my _Carousel
partial but public List<string> Images
property is still an empty list.
I am coming from ReactJs
and I am still figuring out how dotNet razor pages works.
Is there any similar functionality in razor pages as useEffect
in Reactjs?
namespace WebUI.Pages.Home.Item
{
public class ItemModel : PageModel
{
[BindProperty]
public List<string> Images { get; set; } = new();
private readonly ILogger<ItemModel> _logger;
// private item service ...
public ItemModel(Logger<ItemModel> logger)
{
// Item service
_logger = logger
}
public async Task<IActionResult> OnGetAsync([FromQuery] int id)
{
var result = await _itemService.getItemById(id);
foreach (var item in result.ItemImages)
{
Images.Add(item.Url);
// **Note that I can log item.Url here and it arrives correctly**
}
return new JsonResult(result);
}
}
}
partial _Carousel.cshtml
, @Model.Images.Count()
is still 0 even though the Item has been fetched and I can see the log that it has 3 images.
@model WebUI.Pages.Home.Item.ItemModel
@if (@Model.Images.Count() > 0)
{
<div>URLs: @Model.Images.Count()</div>
}
<div >
<div id="panel-1" >
<div >
<div >
<div id="carouselExampleFade" data-ride="carousel">
// render images from @Model.Images
<a href="#carouselExampleFade" role="button" data-slide="prev">
<span aria-hidden="true"></span>
<span >Previous</span>
</a>
<a href="#carouselExampleFade" role="button" data-slide="next">
<span aria-hidden="true"></span>
<span >Next</span>
</a>
</div>
</div>
</div>
</div>
</div>
@section Scripts { }
I also added Item.cshtml
where partial _Carousel.cshtml
is being called to render images.
@page
@using WebUI.Pages.Home.Item
@model WebUI.Pages.Home.Item.ItemModel
<div >
@Html.Partial("_Carousel", Model)
<div ></div>
</div>
@section Scripts {
<script src="~/lib/axios/dist/axios.js"></script>
<script>
$(document).ready(function () {
var url = document.URL;
var id = url.split("?")[1].split("=")[1];
var data = {};
axios.get(`@Url.Page("/Home/Item")?Id=${id.toString()}`)
.then((response) => {
item = response.data;
var listItem = `
<div style="width: 18rem;" onClick=navigateToItem(${item.Id})>
<div >
<h5 >${item.Name}</h5>
<p >${item.Description}</p>
</div>
</div>`;
$('.card-group').append(listItem);
}).catch(error => {
console.log(error)
});
});
</script>
}
What is the razor way of doing this? I should point out that I am new to razor pages. Any suggestions is mostly welcome.
CodePudding user response:
Razor Pages works quite different compared to reactJs. You don't need to use javascript for this. OnGetAsync
should not return json. It should return the Page. Your code could look like this:
Item.cshtml.cs
:
public class ItemModel : PageModel
{
private readonly ILogger<ItemModel> _logger;
// private item service ...
public ItemModel(Logger<ItemModel> logger)
{
// Item service
_logger = logger
}
[BindProperty]
public Item Item { get; set; }
public async Task<IActionResult> OnGetAsync(int id)
{
Item = await _itemService.getItemById(id);
return Page();
}
}
Item.cshtml
:
(using the partial tag helper is better)
@page
@using WebUI.Pages.Home.Item
@model WebUI.Pages.Home.Item.ItemModel
@if (Model.Item != null)
{
<div >
<partial name="_Carousel" model="@Model.Item.ItemImages" />
<div >
<div style="width: 18rem;">
<div >
<h5 >@Model.Item.Name</h5>
<p >@Model.Item.Description</p>
</div>
</div>
</div>
</div>
}
_Carousel.cshtml
:
@model List<string>
@if (Model != null && Model.Count > 0)
{
<div>URLs: @Model.Count</div>
}
...