Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / Blazor

Templated Data container with Razor

5.00/5 (10 votes)
26 Jun 2023CPOL2 min read 9.3K  
Rather than littering a razor component with @if (a == b) logic to show items, use render fragments to make a declarative component
While writing Blazor components, I got sick of wrapping the visibility of content inside @if.../else logic to show different content when data was present, to when it wasn't. In this simple trick, we are going to look at a handy little method of displaying content depending on whether or not data is present.

Introduction

I have been working on a Blazor application and I hated that one of my forms had this big old ugly @if (a == b) show some content else show a message to say there was no data. It was ugly, and it didn't fit into the templated nature of the code so I decided to do something about it.

Background

This is a simple component that consists of three variables, but it makes life look a lot neater. Gone is the code that looks like this:

ASP.NET
@if (_value == 0) {
  <p>There is no data</p>
} else {
  <div class="mb-8">
    <p>There is content here.</p>
  </div>
}

That code is replaced by the (in my eye), much more elegant:

ASP.NET
<DataContainer HasData="@(_value > 0)">
  <NoData>
    <p>There is no data</p>
  </NoData>
  <DataTemplate>
    <div class="mb-8">
      <p>There is content here</p>
    </div>
  </DataTemplate>
</DataContainer>

The Code

The code behind this relies on the ability of razor to let us create RenderFragments and use this to create our own RenderTree. The code is as simple as creating three parameters, and overriding the BuildRenderTree method like this:

C#
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace Goldlight.ServiceVirtualisation.Components;

public class DataContainer : ComponentBase
{
  [Parameter] public bool HasData { get; set; }

  [Parameter] public RenderFragment DataTemplate { get; set; } = null!;

  [Parameter] public RenderFragment NoData { get; set; } = null!;

  protected override void BuildRenderTree(RenderTreeBuilder builder)
  {
    base.BuildRenderTree(builder);
    builder.AddContent(0, HasData ? DataTemplate : NoData);
  }
}

That's it; that's all there is to it. Having created this component, I find that I use it all over the place. It's simple to use a similar concept to build a component that shows and hides a spinner, replacing it with content to manage a loading component.

A point of note; I have chosen to deliberately set the components with null! to show that, even though they start defined as null, they will definitely have a value before I use them when I'm building the render tree. I could have added checks in the build method, if these were nullable properties, but as the problem I am solving is to show different data under different conditions, then I don't need to make the render fragments nullable.

I hope you like this tip (there's no code download because the code for the tip is a dozen lines long or so). When you start to play around with render fragments, you'll find all sorts of situations in which you will want to use them.

History

  • 26th June, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)