diff --git a/Directory.Build.props b/Directory.Build.props index 0db47a6..6659289 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 3.0.0-rc1.19457.4 - 3.0.0-preview9.19457.4 - 3.0.0-rc1.19456.14 + 3.0.0 + 3.0.0-preview9.19465.2 + 3.0.0 diff --git a/docs/06-authentication-and-authorization.md b/docs/06-authentication-and-authorization.md index 11cbfae..7057658 100644 --- a/docs/06-authentication-and-authorization.md +++ b/docs/06-authentication-and-authorization.md @@ -69,12 +69,12 @@ public void ConfigureServices(IServiceCollection services) } ``` -To flow the authentication state information through your app, you need to add one more component. In `App.razor`, surround the `` with a ``: +To flow the authentication state information through your app, you need to add one more component. In `App.razor`, surround the entire `` with a ``: ```html - - Page not found + + ... ``` @@ -193,7 +193,7 @@ If you're now logged in, you'll be able to place orders and see order status. Bu To fix this, let's make the UI prompt the user to log in (if necessary) as part of placing an order. -In the `Checkout` page component, add some logic to `OnInitializedAsync` to check whether the user is currently authenticated. If they aren't, send them off to the login endpoint. +In the `Checkout` page component, add an `OnInitializedAsync` with some logic to to check whether the user is currently authenticated. If they aren't, send them off to the login endpoint. ```cs @code { @@ -307,30 +307,42 @@ So, go to `MyOrders`, and and put the following directive at the top (just under @attribute [Authorize] ``` -Now, logged in users can reach the *My orders* page, but logged out users will see the message *Not authorized* instead. Verify you can see this working. - -Finally, let's be a bit friendlier to logged out users. Instead of just saying *Not authorized*, we can customize this to display a link to sign in. Go to `App.razor`, and pass the following `` and `` parameters to the ``: +The `[Authorize]` functionality is part of the routing system, and we'll need to make some changes there. In `App.razor`, replace `` with ``. ```html - - Page not found - - -
-

You're signed out

-

To continue, please sign in.

- Sign in -
-
- - - Please wait... - + + + + + ...
``` +The `AuthorizeRouteView` component is like `RouteView` in that it can display a routable component and it's layout, but also integrates with `[Authorize]`. + +--- + +Now, logged in users can reach the *My orders* page, but logged out users will see the message *Not authorized* instead. Verify you can see this working. + +Finally, let's be a bit friendlier to logged out users. Instead of just saying *Not authorized*, we can customize this to display a link to sign in. Go to `App.razor`, and pass the following `` and `` parameters to the ``: + +```html + + +
+

You're signed out

+

To continue, please sign in.

+ Sign in +
+
+ + Please wait... + +
+``` + Now if you're logged out and try to go to *My orders*, you'll get a much nicer outcome: ![image](https://user-images.githubusercontent.com/1101362/51807840-11225180-2284-11e9-81ed-ea9caacb79ef.png) diff --git a/docs/07-javascript-interop.md b/docs/07-javascript-interop.md index 1dd1c6b..bb81403 100644 --- a/docs/07-javascript-interop.md +++ b/docs/07-javascript-interop.md @@ -22,7 +22,7 @@ Open *Map.razor* and take a look at the code: protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); @@ -30,11 +30,15 @@ Open *Map.razor* and take a look at the code: } ``` -The `Map` component uses dependency injection to get an `IJSRuntime` instance. This service can be used to make JavaScript calls to browser APIs or existing JavaScript libraries by calling the `InvokeAsync` method. The first parameter to this method specifies the path to the JavaScript function to call relative to the root `window` object. The remaining parameters are arguments to pass to the JavaScript function. The arguments are serialized to JSON so they can be handled in JavaScript. +The `Map` component uses dependency injection to get an `IJSRuntime` instance. This service can be used to make JavaScript calls to browser APIs or existing JavaScript libraries by calling the `InvokeVoidAsync` or `InvokeAsync` method. The first parameter to this method specifies the path to the JavaScript function to call relative to the root `window` object. The remaining parameters are arguments to pass to the JavaScript function. The arguments are serialized to JSON so they can be handled in JavaScript. -The `Map` component first renders a `div` with a unique ID for the map and then calls the `deliveryMap.showOrUpdate` function to display the map in the specified element with the specified markers pass to the `Map` component. This is done in the `OnAfterRenderAsync` component lifecycle event to ensure that the component is done rendering its markup. The `deliveryMap.showOrUpdate` function is defined in the *content/deliveryMap.js* file, which then uses [leaflet.js](http://leafletjs.com) and [OpenStreetMap](https://www.openstreetmap.org/) to display the map. The details of how this code works isn't really important - the critical point is that it's possible to call any JavaScript function this way. +The `Map` component first renders a `div` with a unique ID for the map and then calls the `deliveryMap.showOrUpdate` function to display the map in the specified element with the specified markers pass to the `Map` component. This is done in the `OnAfterRenderAsync` component lifecycle event to ensure that the component is done rendering its markup. The `deliveryMap.showOrUpdate` function is defined in the *wwwroot/deliveryMap.js* file, which then uses [leaflet.js](http://leafletjs.com) and [OpenStreetMap](https://www.openstreetmap.org/) to display the map. The details of how this code works isn't really important - the critical point is that it's possible to call any JavaScript function this way. -How do these files make their way to the Blazor app? If you peek inside of the project file for the ComponentsLibrary you'll see that the files in the content directory are built into the library as embedded resources. The Blazor build infrastructure then takes care of extracting these resources and making them available as static assets. +How do these files make their way to the Blazor app? For a Blazor library project (using `Sdk="Microsoft.NET.Sdk.Razor"`) any files in the `wwwroot/` folder will be bundled with the library. The server project will automatically serve these files using the static files middleware. + +The final link is for the page hosting the Blazor client app to include the desired files (in our case `.js` and `.css`). The `index.html` includes these files using relative URIs like `_content/BlazingPizza.ComponentsLibrary/localStorage.js`. This is the general pattern for references files bundled with a Blazor class library - `_content//`. + +--- If you start typing in `Map`, you'll notice that the editor doesn't offer completion for it. This is because the binding between elements and components are governed by C#'s namespace binding rules. The `Map` component is defined in the `BlazingPizza.ComponentsLibrary.Map` namespace, which we don't have an `@using` for. diff --git a/docs/08-templated-components.md b/docs/08-templated-components.md index a8be736..2579387 100644 --- a/docs/08-templated-components.md +++ b/docs/08-templated-components.md @@ -2,18 +2,28 @@ Let's refactor some of the original components and make them more reusable. Along the way we'll also create a separate library project as a home for the new components. -## Creating a component library (command line) +We're going to create a new project using the Razor Class Library template. + +## Creating a component library (Visual Studio) + +Using Visual Studio, right click the solution explorer and choose `Add->New Project`. + +Then, select the Razor Class Library template. -We're going to create a new project using the **dotnet** cli in this step since the Razor Class Library template in Visual Studio does not yet have all of the settings we want. +![image](https://user-images.githubusercontent.com/1430011/65823337-17990c80-e209-11e9-9096-de4cb0d720ba.png) + +Enter the project name `BlazingComponents` and click *Create*. + +## Creating a component library (command line) To make a new project using **dotnet** run the following commands from the directory where your solution file exists. ``` -dotnet new razorclasslib -o BlazingComponents --support-pages-and-views false +dotnet new razorclasslib -o BlazingComponents dotnet sln add BlazingComponents ``` -This should create a new project called `BlazingComponents` and add it to the solution file. This is the same template used to create libraries of standlone Razor Pages - but with an option to use default settings for Blazor and components. +This should create a new project called `BlazingComponents` and add it to the solution file. ## Understanding the library project @@ -30,8 +40,8 @@ It looks like: - - + + @@ -51,7 +61,7 @@ We are going to revisit the dialog system that is part of `Index` and turn it in Let's think about how a *reusable dialog* should work. We would expect a dialog component to handle showing and hiding itself, as well as maybe styling to appear visually as a dialog. However, to be truly reusable, we need to be able to provide the content for the inside of the dialog. We call a component that accepts *content* as a parameter a *templated component*. -Blazor happens to have a feature that works for exactly this case, and it's similar to how a layout works. Recall that a layout has a `Body` parameter, and the layout gets to place other content *around* the `Body`. In a layout, the `Body` parameter is of type `RenderFragment` which is a delegate type that the runtime has special handling for. The good news is that this feature is not limited to layouts. Any component can declare a parameter of type `RenderFragment`. +Blazor happens to have a feature that works for exactly this case, and it's similar to how a layout works. Recall that a layout has a `Body` parameter, and the layout gets to place other content *around* the `Body`. In a layout, the `Body` parameter is of type `RenderFragment` which is a delegate type that the runtime has special handling for. The good news is that this feature is not limited to layouts. Any component can declare a parameter of type `RenderFragment`. We've also used this feature extensively in `App.razor`. All of the components used to handle routing and authorization are templated components. Let's get started on this new dialog component. Create a new component file named `TemplatedDialog.razor` in the `BlazingComponents` project. Put the following markup inside `TemplatedDialog.razor`: @@ -242,23 +252,21 @@ Now, these are our three states of the dialog, and we'd like accept a content pa Here's an example of the three parameters to add: ```C# - [Parameter] public RenderFragment LoadingContent { get; set; } - [Parameter] public RenderFragment EmptyContent { get; set; } - [Parameter] public RenderFragment ItemContent { get; set; } + [Parameter] public RenderFragment Loading{ get; set; } + [Parameter] public RenderFragment Empty { get; set; } + [Parameter] public RenderFragment Item { get; set; } ``` -note: naming a `RenderFragment` parameter with the suffix *Content* is just a convention. - Now that we have some `RenderFragment` parameters, we can start using them. Update the markup we created earlier to plug in the correct parameter in each place. ```html @if (items == null) { - @LoadingContent + @Loading } else if (items.Count == 0) { - @EmptyContent + @Empty } else { @@ -266,14 +274,14 @@ else @foreach (var item in items) {
- @ItemContent(item) + @Item(item)
} } ``` -The `ItemContent` accepts a parameter, and the way to deal with this is just to invoke the function. The result of invoking a `RenderFragment` is another `RenderFragment` which can be rendered directly. +The `Item` accepts a parameter, and the way to deal with this is just to invoke the function. The result of invoking a `RenderFragment` is another `RenderFragment` which can be rendered directly. The new component should compile at this point, but there's still one thing we want to do. We want to be able to style the `
` with another class, since that's what `MyOrders.razor` is doing. Adding small extensibiliy points to plug in additional css classes can go a long way for reusability. @@ -284,9 +292,9 @@ Let's add another `string` parameter, and finally the functions block of `Templa List items; [Parameter] public Func>> Loader { get; set; } - [Parameter] public RenderFragment LoadingContent { get; set; } - [Parameter] public RenderFragment EmptyContent { get; set; } - [Parameter] public RenderFragment ItemContent { get; set; } + [Parameter] public RenderFragment Loading { get; set; } + [Parameter] public RenderFragment Empty { get; set; } + [Parameter] public RenderFragment Item { get; set; } [Parameter] public string ListGroupClass { get; set; } protected override async Task OnParametersSetAsync() @@ -303,11 +311,11 @@ Lastly update the `
` to contain `
- @ItemContent(item) + @Item(item)
}
@@ -325,9 +333,9 @@ else List items; [Parameter] public Func>> Loader { get; set; } - [Parameter] public RenderFragment LoadingContent { get; set; } - [Parameter] public RenderFragment EmptyContent { get; set; } - [Parameter] public RenderFragment ItemContent { get; set; } + [Parameter] public RenderFragment Loading { get; set; } + [Parameter] public RenderFragment Empty { get; set; } + [Parameter] public RenderFragment Item { get; set; } [Parameter] public string ListGroupClass { get; set; } protected override async Task OnParametersSetAsync() @@ -394,29 +402,29 @@ For our `TemplatedList` here's an example that sets each parameter to some dummy ```html
- Hi there! - + Hi there! + How are you? - - + + Are you enjoying Blazor? - +
``` -The `ItemContent` parameter is a `RenderFragment` - which accepts a parameter. By default this parameter is called `context`. If we type inside of ` ` then it should be possible to see that `@context` is bound to a variable of type `OrderStatus`. We can rename the parameter by using the `Context` attribute: +The `Item` parameter is a `RenderFragment` - which accepts a parameter. By default this parameter is called `context`. If we type inside of ` ` then it should be possible to see that `@context` is bound to a variable of type `OrderStatus`. We can rename the parameter by using the `Context` attribute: ```html
- Hi there! - + Hi there! + How are you? - - + + Are you enjoying Blazor? - +
``` @@ -426,12 +434,12 @@ Now we want to include all of the existing content from `MyOrders.razor`, so put ```html
- Loading... - + Loading... +

No orders placed

Order some pizza -
- + +
@item.Order.CreatedTime.ToLongDateString()
Items: @@ -447,7 +455,7 @@ Now we want to include all of the existing content from `MyOrders.razor`, so put Track >
-
+
``` @@ -458,7 +466,7 @@ There were a number of steps and new features to introduce here. Run this and ma To prove that the list is really working correctly we can try the following: 1. Delete the `pizza.db` from the `Blazor.Server` project to test the case where there are no orders -1. Add an `await Task.Delay(3000);` to `LoadOrders` to test the case where we're still loading +2. Add an `await Task.Delay(3000);` to `LoadOrders` to test the case where we're still loading ## Summary diff --git a/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/00-Starting-point/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/01-Components-and-layout/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/02-customize-a-pizza/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/03-show-order-status/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/04-refactor-state-management/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/05-checkout-with-validation/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/06-add-authentication/BlazingPizza.Client/App.razor b/save-points/06-add-authentication/BlazingPizza.Client/App.razor index 758e415..5ff0ef5 100644 --- a/save-points/06-add-authentication/BlazingPizza.Client/App.razor +++ b/save-points/06-add-authentication/BlazingPizza.Client/App.razor @@ -1,17 +1,23 @@  - - Page not found - - -
-

You're signed out

-

To continue, please sign in.

- Sign in -
-
- - - Please wait... - + + + + +
+

You're signed out

+

To continue, please sign in.

+ Sign in +
+
+ +
Please wait...
+
+
+
+ + +
Page not found
+
+
diff --git a/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/06-add-authentication/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/07-javascript-interop/BlazingPizza.Client/App.razor b/save-points/07-javascript-interop/BlazingPizza.Client/App.razor index 758e415..5ff0ef5 100644 --- a/save-points/07-javascript-interop/BlazingPizza.Client/App.razor +++ b/save-points/07-javascript-interop/BlazingPizza.Client/App.razor @@ -1,17 +1,23 @@  - - Page not found - - -
-

You're signed out

-

To continue, please sign in.

- Sign in -
-
- - - Please wait... - + + + + +
+

You're signed out

+

To continue, please sign in.

+ Sign in +
+
+ +
Please wait...
+
+
+
+ + +
Page not found
+
+
diff --git a/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/07-javascript-interop/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/save-points/08-templated-components/BlazingComponents/TemplatedList.razor b/save-points/08-templated-components/BlazingComponents/TemplatedList.razor index f01d5a7..f541e56 100644 --- a/save-points/08-templated-components/BlazingComponents/TemplatedList.razor +++ b/save-points/08-templated-components/BlazingComponents/TemplatedList.razor @@ -2,11 +2,11 @@ @if (items == null) { - @LoadingContent + @Loading } else if (items.Count == 0) { - @EmptyContent + @Empty } else { @@ -14,7 +14,7 @@ else @foreach (var item in items) {
- @ItemContent(item) + @Item(item)
} @@ -24,9 +24,9 @@ else List items; [Parameter] public Func>> Loader { get; set; } - [Parameter] public RenderFragment LoadingContent { get; set; } - [Parameter] public RenderFragment EmptyContent { get; set; } - [Parameter] public RenderFragment ItemContent { get; set; } + [Parameter] public RenderFragment Loading { get; set; } + [Parameter] public RenderFragment Empty { get; set; } + [Parameter] public RenderFragment Item { get; set; } [Parameter] public string ListGroupClass { get; set; } protected override async Task OnParametersSetAsync() diff --git a/save-points/08-templated-components/BlazingPizza.Client/App.razor b/save-points/08-templated-components/BlazingPizza.Client/App.razor index 758e415..5ff0ef5 100644 --- a/save-points/08-templated-components/BlazingPizza.Client/App.razor +++ b/save-points/08-templated-components/BlazingPizza.Client/App.razor @@ -1,17 +1,23 @@  - - Page not found - - -
-

You're signed out

-

To continue, please sign in.

- Sign in -
-
- - - Please wait... - + + + + +
+

You're signed out

+

To continue, please sign in.

+ Sign in +
+
+ +
Please wait...
+
+
+
+ + +
Page not found
+
+
diff --git a/save-points/08-templated-components/BlazingPizza.Client/Pages/MyOrders.razor b/save-points/08-templated-components/BlazingPizza.Client/Pages/MyOrders.razor index 0e9dac2..e79e928 100644 --- a/save-points/08-templated-components/BlazingPizza.Client/Pages/MyOrders.razor +++ b/save-points/08-templated-components/BlazingPizza.Client/Pages/MyOrders.razor @@ -4,12 +4,12 @@
- Loading... - + Loading... +

No orders placed

Order some pizza -
- + +
@item.Order.CreatedTime.ToLongDateString()
Items: @@ -25,7 +25,7 @@ Track >
-
+
diff --git a/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/Map/Map.razor b/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/save-points/08-templated-components/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers); diff --git a/src/BlazingComponents/TemplatedList.razor b/src/BlazingComponents/TemplatedList.razor index f01d5a7..f541e56 100644 --- a/src/BlazingComponents/TemplatedList.razor +++ b/src/BlazingComponents/TemplatedList.razor @@ -2,11 +2,11 @@ @if (items == null) { - @LoadingContent + @Loading } else if (items.Count == 0) { - @EmptyContent + @Empty } else { @@ -14,7 +14,7 @@ else @foreach (var item in items) {
- @ItemContent(item) + @Item(item)
} @@ -24,9 +24,9 @@ else List items; [Parameter] public Func>> Loader { get; set; } - [Parameter] public RenderFragment LoadingContent { get; set; } - [Parameter] public RenderFragment EmptyContent { get; set; } - [Parameter] public RenderFragment ItemContent { get; set; } + [Parameter] public RenderFragment Loading { get; set; } + [Parameter] public RenderFragment Empty { get; set; } + [Parameter] public RenderFragment Item { get; set; } [Parameter] public string ListGroupClass { get; set; } protected override async Task OnParametersSetAsync() diff --git a/src/BlazingPizza.Client/Pages/MyOrders.razor b/src/BlazingPizza.Client/Pages/MyOrders.razor index 6c80a90..741b067 100644 --- a/src/BlazingPizza.Client/Pages/MyOrders.razor +++ b/src/BlazingPizza.Client/Pages/MyOrders.razor @@ -4,12 +4,12 @@
- Loading... - + Loading... +

No orders placed

Order some pizza -
- + +
@item.Order.CreatedTime.ToLongDateString()
Items: @@ -25,7 +25,7 @@ Track >
-
+
diff --git a/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs index a9f83aa..f36b098 100644 --- a/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -8,10 +8,10 @@ public static class LocalStorage public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.delete", key); + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } } diff --git a/src/BlazingPizza.ComponentsLibrary/Map/Map.razor b/src/BlazingPizza.ComponentsLibrary/Map/Map.razor index 7c80243..c2413ac 100644 --- a/src/BlazingPizza.ComponentsLibrary/Map/Map.razor +++ b/src/BlazingPizza.ComponentsLibrary/Map/Map.razor @@ -11,7 +11,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { - await JSRuntime.InvokeAsync( + await JSRuntime.InvokeVoidAsync( "deliveryMap.showOrUpdate", elementId, Markers);