Chinook.DataLoader.DynamicMvvm 0.10.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Chinook.DataLoader.DynamicMvvm --version 0.10.0                
NuGet\Install-Package Chinook.DataLoader.DynamicMvvm -Version 0.10.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Chinook.DataLoader.DynamicMvvm" Version="0.10.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Chinook.DataLoader.DynamicMvvm --version 0.10.0                
#r "nuget: Chinook.DataLoader.DynamicMvvm, 0.10.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Chinook.DataLoader.DynamicMvvm as a Cake Addin
#addin nuget:?package=Chinook.DataLoader.DynamicMvvm&version=0.10.0

// Install Chinook.DataLoader.DynamicMvvm as a Cake Tool
#tool nuget:?package=Chinook.DataLoader.DynamicMvvm&version=0.10.0                

Chinook.DataLoader

Async data loading made visually pleasant!

License

Getting Started

Install the latest version of Chinook.DataLoader.Uno in your project.

Create a IDataLoader using the builder (see below on how to use with Chinook.DynamicMvvm).

var dataLoader = DataLoaderBuilder<MyData>
  .Empty
  .WithName("MyDataLoader")
  .WithLoadMethod(LoadData)
  .Build();

Task<MyData> LoadData(CancellationToken ct)
{
  // Your async operation here.
}

Add a DataLoaderView in your xaml.


<dl:DataLoaderView Source="{Binding MyDataLoader}" />

As the task is being executed, the IDataLoader will call its StateChanged event which will be used by DataLoaderView to visually represent the state of the async operation.

Features

Async data loading

The loading method of the IDataLoader must simply return a Task of the data type (here MyData).

Task<MyData> LoadData(CancellationToken ct)
{
  // Your async operation here.
}

This is where you would typically execute an API call or get data from any other async source.

This method receives a CancellationToken as the operation might be cancelled.

  • If the IDataLoader is disposed.
  • If another request was made and the concurrent mode is CancelPrevious.

Data loader states

At any given time, the IDataLoader can be in a combination of the following states.

State Description
IsLoading Is the data loader executing a request
Data Last data from a successful request
Error Error if the request failed (if any)

Imagine a scenario where you land on a page where the data has never been loaded before from an API.

  1. The system would first be on an initial state (not loading, no data, no error).
  2. The system would then start loading the data from the API.
  3. The system would then show the data returned from the API.
  4. You lose connection and refresh the page.
  5. The system notifies you that there was an error, but you still have your previous data.

This could be represented by the following state flow.

#1                  #2                 #3                  #4                 #5
IsLoading(false) -> IsLoading(true) -> IsLoading(false) -> IsLoading(true) -> IsLoading(false)
Data(null)       -> Data(null)      -> Data(myData)     -> Data(myData)    -> Data(myData)
Error(null)      -> Error(null)     -> Error(null)      -> Error(null)     -> Error(WebException)

Note: The error is cleared as soon as there is a successful request

Other useful states are available:

State Description
IsInitial Was a request ever made
IsEmpty Should the data be considered empty

Triggers

As the data might need to be updated, you can trigger a new load request on a IDataLoader using triggers.

Trigger Description
ManualDataLoaderTrigger Manually trigger a load request
ObservableDataLoaderTrigger Trigger a load request when the observable pushes a new value

You can create your own triggers by inheriting from DataLoaderTriggerBase.

Simply call RaiseLoadRequested when a load request should be requested.

Note: DataLoaderView has a AutoLoad property which, as its name suggests, automatically load the data of the DataLoader when it's displayed.

Requests and contexts

To provide metadata on the loading operation, two important pieces are used.

Metadata Description
IDataLoaderRequest Request to load data loading operation
IDataLoaderContext Metadata on the loading operation (key-value pair)

You can get additional information from the IDataLoader by adding the IDataLoaderRequest parameter.

Task<MyData> LoadData(CancellationToken ct, IDataLoaderRequest request)
{
  // This is the trigger that caused that loading operation.
  var sourceTrigger = request.SourceTrigger;

  // This is the context that was passed to the loading operation from the trigger.
  var context = request.Context;

  // Your async operation here.
}

The request is also available as part of the IDataLoaderState.

DataLoaderView

The DataLoaderView represents the different states of the IDataLoader using the following visual states.

Group State
DataStates Initial
DataStates Data
DataStates Empty
ErrorStates NoError
ErrorStates Error
LoadingStates NotLoading
LoadingStates Loading
CombinedStates Initial_NoError_NotLoading
CombinedStates Initial_NoError_Loading
CombinedStates Initial_Error_NotLoading
CombinedStates Initial_Error_Loading
CombinedStates Data_NoError_NotLoading
CombinedStates Data_NoError_Loading
CombinedStates Data_Error_NotLoading
CombinedStates Data_Error_Loading
CombinedStates Empty_NoError_NotLoading
CombinedStates Empty_NoError_Loading
CombinedStates Empty_Error_NotLoading
CombinedStates Empty_Error_Loading

You can easily define the template displayed in these states by using the following template properties.

Template Description
ContentTemplate Template used when there is data to show
EmptyTemplate Template used when there is no data to show
ErrorTemplate Template used when an error occurred
ErrorNotificationTemplate Template used when an error occured by there is data to show

To avoid seeing flickery transitions between the different visual states, the DataLoaderView supports different throttling options.

Options Description
StateMinimumDuration The minimum duration a visual state should be in
StateChangingThrottleDelay Delay before going to a new visual state (e.g. if the loading is really quick, you probably don't want to show a loading state)
<dl:DataLoaderView Source="{Binding MyDataLoader}"
                   StateMinimumDuration="0:0:1.5"
                   StateChangingThrottleDelay="0:0:0.100" />

DynamicMvvm

Extension methods are available on Chinook.DynamicMvvm to create data loaders with refresh commands.

Simply add the Chinook.DataLoader.DynamicMvvm package to your project.

public class MyViewModel : ViewModelBase
{
  public IDynamicCommand RefreshData => this.GetCommandFromDataLoaderRefresh(Data);

  public IDataLoader Data => this.GetDataLoader(GetData, b => b
    // You can optionally configure your data loader here
  );

  private async Task<MyData> GetData(CancellationToken ct)
  {
    // Get data from your API...
  }
}

Code Snippets

You can install the Visual Studio Extension Chinook Snippets and use code snippets to quickly generate data loaders when using Chinook.DynamicMvvm. All snippets related to IDataLoader start with ckdl.

Changelog

Please consult the CHANGELOG for more information about version history.

License

This project is licensed under the Apache 2.0 license - see the LICENSE file for details.

Contributing

Please read CONTRIBUTING.md for details on the process for contributing to this project.

Be mindful of our Code of Conduct.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.0 11,878 12/22/2023
2.0.0-feature.Uno5Update.7 151 12/6/2023
2.0.0-feature.Uno5Update.4 1,770 11/28/2023
1.2.1-feature.Uno5Update.2 76 11/3/2023
1.2.0 55,187 11/22/2022
1.1.2 1,002 11/1/2022
1.1.1 560 10/12/2022
1.1.0 27,750 9/22/2022
1.1.0-feature.dotnet6.2 145 9/22/2022
1.1.0-feature.dotnet6.1 118 9/21/2022
1.0.0 6,053 8/30/2022
0.10.0 465 8/25/2022
0.10.0-dev.91 3,063 8/9/2022
0.10.0-dev.89 404 8/4/2022
0.9.0-feature.uno-ui-4.71 187 3/15/2022
0.7.0-dev.87 19,847 5/25/2022
0.7.0-dev.85 141 5/25/2022
0.7.0-dev.83 5,308 5/19/2022
0.7.0-dev.81 146 5/17/2022
0.7.0-dev.79 168 5/13/2022
0.6.0-dev.77 181 5/2/2022
0.6.0-dev.76 5,877 3/31/2022
0.5.0-feature.uno-ui-4.73 145 3/15/2022
0.5.0-feature.uno-ui-4.72 150 3/15/2022
0.5.0-feature.uno-ui-4.71 149 3/15/2022
0.5.0-dev.73 5,704 3/15/2022
0.4.0-feature.uno-ui-4.70 5,151 12/21/2021
0.4.0-dev.69 16,110 11/26/2021
0.3.0-dev.67 11,818 10/4/2021
0.3.0-dev.65 782 9/21/2021
0.3.0-dev.63 1,994 9/13/2021
0.3.0-dev.60 936 8/30/2021
0.3.0-dev.58 2,329 7/26/2021
0.3.0-dev.56 2,082 7/5/2021
0.3.0-dev.54 12,389 6/22/2021
0.3.0-dev.52 274 6/19/2021
0.3.0-dev.50 268 6/5/2021
0.3.0-dev.48 1,598 4/20/2021
0.3.0-dev.44 15,262 4/8/2021
0.3.0-dev.42 8,204 3/16/2021
0.2.0-dev.37 2,523 12/17/2020
0.2.0-dev.35 3,146 11/2/2020
0.2.0-dev.33 7,997 10/27/2020
0.2.0-dev.31 238 10/13/2020
0.2.0-dev.29 251 9/29/2020
0.2.0-dev.27 6,954 8/13/2020
0.2.0-dev.25 292 6/26/2020