Giter VIP home page Giter VIP logo

blazor-state's People

Contributors

blazorbowl avatar chan18 avatar jafin avatar megafetis avatar mikeyoshino avatar shadynagy avatar stefanbemelmans avatar steventcramer avatar taylorchasewhite avatar tmyllymaki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blazor-state's Issues

Better documentation

Documentation is currently very miserable.

It should describe how to use the library in more detail:

  • How to mutate/set/modify state
  • How to access the state from blazor components

Basic and minimal TODO example should be included in the docs for easier adoption.

Removal of Startup in Blazor 3.2

Hi there

Is there an new version for this release or do I create the state service differently as I am getting an exception when running the app.
blazor.webassembly.js:1 WASM: Error: Failed to start platform. Reason: [object XMLHttpRequest]

Blazorstate.js only included as static files in _content when asp.net core environment is Development

Hey,

I am trying to implement the Blazor-state library in an new project i am working on. I also managed to get the redux dev tools working with the ASPNETCORE_ENVIRONMENT "Development" in my launchSettings.json.

But I also have a environment called "Test" where I want the redux dev tools to be enabled. But the moment I change the ASPNETCORE_ENVIRONMENT to "Test" the blazor-state.js is not published to the _content folder anymore?

This is the situation in environment "Development"
image

And this is the situation in environment "Test"
image

Subscriptions adding up indefinitely

So this is my first time building a state based app, but I'm pretty sure it shouldn't be like this.

If you start the TimewarpBlazorApp Template and go to the Counter Page, you can click the Button, which is fine. The Count increases as it should.
But if you spam it, every action will add a 2 new Subscribers, increasing the times the whole component is re-rendered with every click.

So when the Counter hits 140, you can really notice the slowdown.

Is there a way, to remove duplicate Subscriptions? Resetting the Store doesn't help either...

Initialize is being called prior to completion of constructor.

State is created by the Store when requested and doesn't already exist. It uses the DI Container to create the state but Initialize was being called in the constructor of the base class which would be called prior to the constructor in the derived class.

Thus Initialization couldn't use any of the to be constructed items.

State should not be shared by duplicate components as an option

Take the Counter component. Say you put 3 versions on the same page. If you click the button multiple times, the state changes in one component. If you navigate away and back, all three components now show the same state.

It would be useful to use the same component in an application without sharing state.

Or do you recommend another approach for this use case?

Dom not updating when setting a DynamicComponent with blazor-state action

Hi I have a stackoverflow question here.

I am using mudblazor and blazor-state together it was working great until I ran into a problem where I was using an action to set the type of a DynamicComponent, I expected it to render and show the component which it doesn't. It looks like the dom is not updating, only when I click the link a second time the component shows up, I have uploaded the code here, any help will be much appreciated.e uploaded the code here, any help will be much appreciated.

InputBase Support

I need to capture state changes in an InputBase component for custom controls. I can't inherit from BlazorStateComponent.

What's the best way to achieve this?

FYI: Nuget REST API

For some reason the Nuget REST API doesn't return details about your package:
https://azuresearch-usnc.nuget.org/query?q=packageid:Blazor-State
I've sent a support email to Nuget about this, but thought I'll notify you as well.

GetState<T> returns null

This is a two fold question. One I have a component but rather than put the code behind in a code block (@code {...}) I have defined a partial class. But if I do that GetState is not resolved. Two, The only way I can do it is if in the razor I have @using BlazorState and @inherits BlazorStateComponent. But if I do that GetState returns null and throws an exception because it has determined that the state is null even though I have initialized the state and mutating the state seems to work fine. How can I handle this situation without putting all of the code in a @code block?

Failing to construct services

I've been following the tutorial available here. However, after completing the Displaying state in the user interface stage, I attempt to run the app and receive the following two errors:

InvalidOperationException: Error while validating the service descriptor 'ServiceType: BlazorState.Features.JavaScriptInterop.JsonRequestHandler Lifetime: Scoped ImplementationType: BlazorState.Features.JavaScriptInterop.JsonRequestHandler': Unable to resolve service for type 'System.Text.Json.JsonSerializerOptions' while attempting to activate 'BlazorState.Features.JavaScriptInterop.JsonRequestHandler'.

InvalidOperationException: Unable to resolve service for type 'System.Text.Json.JsonSerializerOptions' while attempting to activate 'BlazorState.Features.JavaScriptInterop.JsonRequestHandler'.

I copy of my source can be found here .

Currently running on preview 8 build 28405-07

Tutorial?

I followed the tutorial under documentation and all seemed to work but I looked at the output of the debugger console in Chrome DEV Tools and I see these messages:

Redux DevTools are not installed.
ReduxDevTools.ts:53 Unable to connect to Redux DevTools.
Initialize.ts:12 InitializeJavaScriptInterop

Should I be concerned? They are not error messages but I don't think I am connected with the Chrome Redux DEV Tools.

Slow when storing array of data from API call

Hi

I have tired many things to improve the performance but I am worried I am doing it very wrong. It appears that maybe memory is being recovered between calls as the first call return in about 400ms but after that it takes about 4000ms.

State object member is an array
public INQ_ID4U_ENT_DTO[] MeItems { get; private set; }
I get the data from the server like this
INQ_ID4U_ENT_DTO[] MeItems = await _httpClient.GetJsonAsync<INQ_ID4U_ENT_DTO[]>($"id4u_ent/inq_id4u_ent", "in4m_now");

Only when I set the state variable to the array returned from the HTTP call does it become very slow.
I am seeing these messages in the console at each call.
L: GC_MAJOR_SWEEP: major size: 2784K in use: 28752K
blazor.webassembly.js:1 L: GC_MAJOR: (LOS overflow) time 8.89ms, stw 8.90ms los size: 1024K in use: 8K

Should I not use the blazer state to receive and cache datasets?

thanks you

Julian

The JSON value could not be converted to System.Int32.

When using Redux DevTools, after following the tutorial, if I attempt to "Jump" to a point in time I get a WASM error of the following:

System.Text.Json.JsonException: The JSON value could not be converted to System.Int32. Path: $.id | LineNumber: 0 | BytePositionInLine: 376. ---> System.InvalidOperationException: Cannot get the value of a token type 'String' as a number.

Looking into it a bit it seems the id from states are serialized as strings, while Newtonsoft handled this well, System.Text.Json does not. Have you come across this before?

image

UI will not update after individual actions

I'm dispatching two actions under one method. The state will change (Message1 first then 1 second later Message2) but the UI will only update after the method that calls the two message update actions finishes.

I've replicate this issue in this repo. I found this issue while at work trying to implement a loading screen.

To see this navigate to "/State" and click the button. The first false should turn true instantly and the second should turn true after one second.

The page is called "State" and the message handlers and actions are under Common/State/Details

Asynchronous action handlers vs. action-reducer-effect-action-reducer - why the difference?

After implementing the same state management using both Fluxor and Blazor-State, it strikes me that the most significant difference is that Blazor-State combines the notions of Reducers and Effects into one thing, called "Handlers". In Blazor-State, a handler is by default asynchronous, so that you can dispatch (called "Send" in Blazor-State) an action, then its handler can modify the state, then call out to a web service or other "outside" thing asynchronous, then modify the state again. So, for a routine action that gets data from a service, in Blazor-State, I need only one action and one handler. The caller can do things while the handler starts running, then await the single dispatch call when we want to react to it. On the await, the component can (will) rerender with the newly changed state (e.g. to show a Loading spinner based on the state) and then after the await completes, the component can (will) rerender with the newly changed state (e.g. to remove the spinner and show the new data from the state).

Fluxor has separate Effects and Reducers, so to do the same thing in Fluxor, I need two separate actions and thus two reducers, and an effect: One parameterless action that results in a reducer and invokes the Effect, then the Effect calls an outside service in a background task that my component can't see, then the effect dispatches a second action, whose reducer can change the state with the newly received data.

My naive look at things makes me appreciate the simpler model of Blazor-State with its combined effects and reducers--I don't see what the added complexity of separating them (in Fluxor) gives me as a benefit.

Your good friend Mr. P. Morris wants to keep Fluxor to the same pattern established in Redux/Flux and so isn't enamored with combining them. But more interestingly for Blazor-State, he says: "I think you have actually found a bug in Blazor State rather than a feature. As the changes are not being notified to subscribers, then you have to have a call to StateHasChanged before the await in Step 2 in order to see the middle changes, but then you are putting UI logic into your reducer and also tying your logic to a single UI framework. Essentially, your state is getting concerned with rendering details, and that's not a good mix."

But I see it as a feature and not a bug; there are many cases where I might want to change my state, let the components render, then change the state again and let them render again. It seems that narrower case is common enough to justify it.

I also don't see a confusion of concerns: the handler (what he calls reducer) need not call StateHasChanged, but it need only await the first asynchronous as in any ordinary asynchronous fashion. The component will automatically rerender on the first await.

Now there is nowhere in this pattern to allow any intermediate changes to cause a rerender--say I make three changes to the state, and await the first and second changes; the second change will not cause a rerender. How would you handle such a need to rerender if I wanted to update the state three times in a handler?

And finally, reacting to Mr. P. Morris, do you think this is a bug or a good feature? And is it a good feature just because it is useful, or does it actually follow from some design/architecture decision to break from the Flux pattern?

(This is spurred by a discussion in the Fluxor issues.)

State per object instance

Hi,
I have the one page with many tabs. Every tab has it's own instance of an object (Simulation 1, Simulation 2, ...), so every object has independent data.
If I create SimulationState class and then I change data on Simulation 1 Tab, state will be changed and data will be updated on all other tabs too.
So, it is possible to have a state per object instance? Any ideas?
Thank you.

State Initialize called twice

It looks like the State is Initialized twice when a BlazorStateComponent is the opening page.

Steps to test with with the Blazor Counter example:

  1. Put a break-point on the Initialize method of the CounterState class.
  2. Run the app and select the Counter page. The app will break once on the Initialize method.
  3. Refresh the page (stay on the Counter page).
  4. The app will break twice on the Initialize method.

My workaround is a Loaded logic on the MainLayout.razor component:

    bool Loaded { get; set; }
    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            Loaded = true;
            StateHasChanged();
        }
        base.OnAfterRender(firstRender);
    }

No BlazorStateComponents are loaded until the Loaded flag is true.

Tutorial invokes state change on an assumed static method

The tutorial indicates

void IncrementCount()
{
    Mediator.Send(new CounterState.IncrementCountAction { Amount = 5 });
}

But in realty the Send method returns a Task and requires a instance of the object. Should the tutorial be updated? So it seems the overall project will not compile. For example when I move this code in my own project I get:
image

namespace BreakpointManagement.Shared.Features.BreakpointManagement
{
    public partial class BreakpointManagementState
    {
        public class UpdateProjectAction : IAction
        {
            public BreakpointProjectSummary Project { get; set; }
        }
    }
}

It seems that to call this method (Send) you have to have an instance of Mediator and the constructor depends on ServiceFactory. So the long and short of it is that I don't know how to create an instance of Mediator?
image

Fallback code for server-side mode would be appreciated

Hi, I am using Blazor.State for a while now and I like it very much. I am used to MediatR, that made it a simple choice for me.

The new ASP.NET CORE roadmap shows, that Blazor server-side will be released first (called Razor-Components). It would be incredible valuable, If we could use Blazor.State for both modes.

Request: The store should be unique to the current user-session. Maybe even optional, to have a global-state (Themes, Locale ...) for everyone and personal state for the rest.

Do you think this is feasable?

Memory management could be something to think about too. Maybe saving state to disc or to Redis or SQL would give additional value.

Will Blazor-state support generics in the State?

Will Blazor-state support generics in the State something like this?

public partial class SomeState<T> : State<SomeState<T>>
  {
    public IEnumerable<T> List { get; private set; }
  }

I was using Fluxor until I found out it would not support Generic types.

Latest version 3.3.0 creates ILLinker error

Fatal error in Mono IL Linker build 04-Nov-2020 18:57:16 /home/bamboo/.nuget/packages/microsoft.aspnetcore.components.webassembly.build/3.2.1/targets/Blazor.MonoRuntime.targets(326,5): error : Unhandled exception. Mono.Linker.MarkException: Error processing method: 'System.Void SmartWorkflow.Application.Processors.SaveWorkItemProcessor/<Run>d__6::MoveNext()' in assembly: 'SmartWorkflow.Application.dll' [/home/bamboo/bamboo-agent-home/xml-data/build-dir/PHOENIX-SWM1-TESTANDPUBLISH/src/Marvin/Client/Marvin.Client.csproj] build 04-Nov-2020 18:57:16 ---> Mono.Cecil.ResolutionException: Failed to resolve System.Threading.Tasks.Task1<!!0> MediatR.IMediator::Send(MediatR.IRequest1<!!0>,System.Threading.CancellationToken) build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference) build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference) build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction) build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body) build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method) build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.ProcessQueue() build 04-Nov-2020 18:57:16 --- End of inner exception stack trace --- build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.ProcessQueue() build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue() build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.Process() build 04-Nov-2020 18:57:16 at Mono.Linker.Steps.MarkStep.Process(LinkContext context) build 04-Nov-2020 18:57:16 at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step) build 04-Nov-2020 18:57:16 at Mono.Linker.Pipeline.Process(LinkContext context) build 04-Nov-2020 18:57:16 at Mono.Linker.Driver.Run(ILogger customLogger) build 04-Nov-2020 18:57:16 at Mono.Linker.Driver.Execute(String[] args, ILogger customLogger) build 04-Nov-2020 18:57:16 at Mono.Linker.Driver.Main(String[] args) build 04-Nov-2020 18:57:16 /home/bamboo/.nuget/packages/microsoft.aspnetcore.components.webassembly.build/3.2.1/targets/Blazor.MonoRuntime.targets(326,5): error : ILLink failed with exit code 134. [src/Marvin/Client/Marvin.Client.csproj]

The reference up there SmartWorkflow.Application uses the same Mediatr version as this project.

as soon as I reverted back to 3.2.4 it worked fine again.

Guidance for singleton services

What would be your guidance for singleton services?

I tried to implement a simple handler that takes a depency on the singleton service instead of the scoped store.
Unfortunately the subscriptions are scoped as well.

Updates to .Net Core 3.0 Preview 8

Updated to Preview 8 and cannot build my project.

When running I get the following error:
2>Unhandled Exception: Mono.Linker.MarkException: Error processing method: 'System.Void BlazorState.BlazorStateComponent::ReRender()' in assembly: 'BlazorState.dll' ---> Mono.Cecil.ResolutionException: Failed to resolve System.Threading.Tasks.Task Microsoft.AspNetCore.Components.ComponentBase::Invoke(System.Action)
2>   at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference)
2>   at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference)
2>   at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction)
2>   at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
2>   at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)
2>   at Mono.Linker.Steps.MarkStep.ProcessQueue()

Most likely due to the fact that ComponentBase.Invoke needs to be changed to ComponentBase.InvokeAsync
per https://devblogs.microsoft.com/aspnet/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-8/

Might be other changes that need to be made as well.

Combine Features and Pages

Hi, I suggest combining the Features and Pages folders. The Counter.cshtml (and in my case the additional Counter.cshtml.cs) files should be placed beside the other code.

The whole concept of feature folders was to have exactly ONE place to look for one feature. Even CSS/SCSS and JS should be placed here IMHO.

You can just rename Pages to Features. Blazor will find the pages.

I would even move NavMenu and SurveyPrompt into the Features folder. They are components too.
The only exception has to be the MainLayout.cshtml, it seems to be a Blazor restriciton.

Feature Folder Structure in ASP.NET Core

preview 9: Runtime error adding BlazorState services in startup.cs

blazor.webassembly.js:1 Uncaught (in promise) Error: System.BadImageFormatException: Could not resolve field token 0x04000113, due to: Could not load type of field 'IN4SAdminClient.Startup+<>c:<>9__0_0' (1) due to: Could not resolve type with token 01000024 from typeref (expected class 'BlazorState.BlazorStateOptions' in assembly 'BlazorState, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null') assembly:BlazorState, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null type:BlazorState.BlazorStateOptions member:(null) assembly:IN4SAdminClient.dll type:<>c member:(null)

State not updating after an action is handled

I noticed that small state changes that happen while an action is being handled do not always trigger 'StateHasChanged'.

The IsLoading variable isn't flipping while we are in the 10 second 'Thread.Sleep' [designed to simulate loading data].

Another thing to note is that using the Redux Dev Tools the states respond out of order.

The reason I mentioned small state changes is when we are using this in a production app (that actually gets data from the DB) sometimes the IsLoading variable change is detected.

Source Code for Sample

The workflow I have implemented is as follows:

State:

    public partial class AppState : State<AppState>
    {
        public DateTime? InstanceTime { get; private set; }
        public DateTime? SecondInstanceTime { get; private set; }
        
        public bool IsLoading { get; private set; }

        public override void Initialize()
        {
            InstanceTime = null;
            SecondInstanceTime = null;
            IsLoading = false;
        }
    }

Action:

    public partial class AppState
    {
        public class GetTimeAction : IAction
        {
            
        }

        public class SetTimeAction : IAction
        {
            public DateTime timeObject { get;}
            public SetTimeAction(DateTime dt)
            {
                timeObject = dt;
            }
        }
    }

Handler:

public partial class AppState
    {
        public class GetTimeHandler : ActionHandler<GetTimeAction>
        {
            private readonly IMediator _mediator;
            private AppState AppState => Store.GetState<AppState>();
            public GetTimeHandler(IStore aStore, IMediator mediator) : base(aStore)
            {
                _mediator = mediator;
            }
            public override async Task<Unit> Handle(GetTimeAction aAction, CancellationToken aCancellationToken)
            {
                var dt = DateTime.Now;
                await _mediator.Send(new SetTimeAction(dt), aCancellationToken);
                AppState.InstanceTime = dt;
                AppState.IsLoading = true;
                return await Unit.Task;
            }
        }

        
        public class SetTimeHandler : ActionHandler<SetTimeAction>
        {
            private readonly IMediator _mediator;
            private AppState AppState => Store.GetState<AppState>();
            public SetTimeHandler(IStore aStore, IMediator mediator) : base(aStore)
            {
                _mediator = mediator;
            }
            public override async Task<Unit> Handle(SetTimeAction aAction, CancellationToken aCancellationToken)
            {
                Thread.Sleep(10000);
                AppState.SecondInstanceTime = aAction.timeObject;
                AppState.IsLoading = false;
                return await Unit.Task;
            }
        }
    }

Index base:

    public class IndexBase : BlazorStateComponent
    {
        protected AppState AppState => GetState<AppState>();

        protected long DateTicks = DateTime.Now.Ticks;
        
        protected async Task GetTimes()
        {
            await Mediator.Send(new AppState.GetTimeAction());
        }
    }

Index.razor

@page "/"
@inherits IndexBase


<button class="btn btn-info" @onclick="GetTimes">
    Go!
</button>

<p>Page Load Time: @DateTicks</p>
<p>Page Is Loading: @AppState.IsLoading</p>

<br />

@if (AppState.InstanceTime.HasValue)
{
    <p>First Time Ticks: @AppState.InstanceTime.Value.Ticks</p>    
}
else
{
    <p>First Time Ticks:</p>
}


@if (AppState.SecondInstanceTime.HasValue)
{
    <p>Second Time Ticks: @AppState.SecondInstanceTime.Value.Ticks</p>    
}
else
{
    <p>Second Time Ticks:</p>
}

Redux Dev Tools Screenshot:
Redux DevTools Screenshot

Cannot jump to a specific state in redux-dev-tools

Hello,

When trying to jump to a specific state in redux-dev-tools we got the following error in the debug console:

Unhandled Exception:
System.Text.Json.JsonException: The JSON value could not be converted to System.Int32. Path: $.id | LineNumber: 0 | BytePositionInLine: 338. ---> System.InvalidOperationException: Cannot get the value of a token type 'String' as a number.
  at System.Text.Json.Utf8JsonReader.TryGetInt32 (System.Int32& value) <0x3056c08 + 0x0001e> in <filename unknown>:0
  at System.Text.Json.Utf8JsonReader.GetInt32 () <0x3056b30 + 0x00008> in <filename unknown>:0
  at System.Text.Json.Serialization.Converters.JsonConverterInt32.Read (System.Text.Json.Utf8JsonReader& reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) <0x3054370 + 0x00004> in <filename unknown>:0
  at System.Text.Json.JsonPropertyInfoNotNullable`4[TClass,TDeclaredProperty,TRuntimeProperty,TConverter].OnRead (System.Text.Json.ReadStack& state, System.Text.Json.Utf8JsonReader& reader) <0x317a730 + 0x0003c> in <filename unknown>:0
  at System.Text.Json.JsonPropertyInfo.Read (System.Text.Json.JsonTokenType tokenType, System.Text.Json.ReadStack& state, System.Text.Json.Utf8JsonReader& reader) <0x2f20268 + 0x00088> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.HandleValue (System.Text.Json.JsonTokenType tokenType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& state) <0x2f1fe10 + 0x000a6> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x2f1f738 + 0x0008e> in <filename unknown>:0
   --- End of inner exception stack trace ---
  at System.Text.Json.ThrowHelper.ReThrowWithPath (System.Text.Json.ReadStack& readStack, System.Text.Json.Utf8JsonReader& reader, System.Exception ex) <0x31d1828 + 0x00028> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x2f1f738 + 0x00320> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.ReadCore (System.Type returnType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader) <0x30659a8 + 0x0002e> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.Deserialize (System.String json, System.Type returnType, System.Text.Json.JsonSerializerOptions options) <0x3065338 + 0x0017a> in <filename unknown>:0
  at BlazorState.Features.JavaScriptInterop.JsonRequestHandler.Handle (System.String aRequestTypeAssemblyQualifiedName, System.String aRequestAsJson) <0x310ed78 + 0x0014c> in <filename unknown>:0
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) <0x31d55c8 + 0x0000c> in <filename unknown>:0
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x31d5578 + 0x00022> in <filename unknown>:0
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x285dbf8 + 0x00100> in <filename unknown>:0
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x285d9b8 + 0x00010> in <filename unknown>:0
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x31d5508 + 0x00038> in <filename unknown>:0
  at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x2f625b8 + 0x00102> in <filename unknown>:0
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x2f62220 + 0x00000> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Text.Json.JsonException: The JSON value could not be converted to System.Int32. Path: $.id | LineNumber: 0 | BytePositionInLine: 338. ---> System.InvalidOperationException: Cannot get the value of a token type 'String' as a number.
  at System.Text.Json.Utf8JsonReader.TryGetInt32 (System.Int32& value) <0x3056c08 + 0x0001e> in <filename unknown>:0
  at System.Text.Json.Utf8JsonReader.GetInt32 () <0x3056b30 + 0x00008> in <filename unknown>:0
  at System.Text.Json.Serialization.Converters.JsonConverterInt32.Read (System.Text.Json.Utf8JsonReader& reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) <0x3054370 + 0x00004> in <filename unknown>:0
  at System.Text.Json.JsonPropertyInfoNotNullable`4[TClass,TDeclaredProperty,TRuntimeProperty,TConverter].OnRead (System.Text.Json.ReadStack& state, System.Text.Json.Utf8JsonReader& reader) <0x317a730 + 0x0003c> in <filename unknown>:0
  at System.Text.Json.JsonPropertyInfo.Read (System.Text.Json.JsonTokenType tokenType, System.Text.Json.ReadStack& state, System.Text.Json.Utf8JsonReader& reader) <0x2f20268 + 0x00088> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.HandleValue (System.Text.Json.JsonTokenType tokenType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& state) <0x2f1fe10 + 0x000a6> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x2f1f738 + 0x0008e> in <filename unknown>:0
   --- End of inner exception stack trace ---
  at System.Text.Json.ThrowHelper.ReThrowWithPath (System.Text.Json.ReadStack& readStack, System.Text.Json.Utf8JsonReader& reader, System.Exception ex) <0x31d1828 + 0x00028> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x2f1f738 + 0x00320> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.ReadCore (System.Type returnType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader) <0x30659a8 + 0x0002e> in <filename unknown>:0
  at System.Text.Json.JsonSerializer.Deserialize (System.String json, System.Type returnType, System.Text.Json.JsonSerializerOptions options) <0x3065338 + 0x0017a> in <filename unknown>:0
  at BlazorState.Features.JavaScriptInterop.JsonRequestHandler.Handle (System.String aRequestTypeAssemblyQualifiedName, System.String aRequestAsJson) <0x310ed78 + 0x0014c> in <filename unknown>:0
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) <0x31d55c8 + 0x0000c> in <filename unknown>:0
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x31d5578 + 0x00022> in <filename unknown>:0
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x285dbf8 + 0x00100> in <filename unknown>:0
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x285d9b8 + 0x00010> in <filename unknown>:0
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x31d5508 + 0x00038> in <filename unknown>:0
  at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x2f625b8 + 0x00102> in <filename unknown>:0
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x2f62220 + 0x00000> in <filename unknown>:0
Uncaught ExitStatusLe thread 0x1268 s'est arrêté avec le code 0 (0x0).

Just before this error message, we got the following log:

ReduxDevTools.MessageHandler
Redux Dev tools type: START maps to BlazorState.Pipeline.ReduxDevTools.StartRequest
Dispatching request of Type BlazorState.Pipeline.ReduxDevTools.StartRequest: {"type":"START","source":"@devtools-extension"}
ReduxDevTools.MessageHandler
Redux Dev tools type: DISPATCH maps to BlazorState.Pipeline.ReduxDevTools.JumpToStateRequest
Dispatching request of Type BlazorState.Pipeline.ReduxDevTools.JumpToStateRequest: {"type":"DISPATCH","payload":{"type":"JUMP_TO_ACTION","actionId":1},"state":"{\"BlazorApp1.Client.Features.Counter.CounterState\":{\"count\":8,\"guid\":\"c2eed289-fda1-494f-883a-c2245eee0284\"},\"BlazorState.Features.Routing.RouteState\":{\"route\":\"https://localhost:5001/\",\"guid\":\"2331cb89-6ee1-4a78-8f6e-24ecdf85aab5\"}}","id":"1","source":"@devtools-extension"}

Here the json formatted:

{
  "type": "DISPATCH",
  "payload": {
    "type": "JUMP_TO_ACTION",
    "actionId": 1
  },
  "state": "{\"BlazorApp1.Client.Features.Counter.CounterState\":{\"count\":8,\"guid\":\"c2eed289-fda1-494f-883a-c2245eee0284\"},\"BlazorState.Features.Routing.RouteState\":{\"route\":\"https://localhost:5001/\",\"guid\":\"2331cb89-6ee1-4a78-8f6e-24ecdf85aab5\"}}",
  "id": "1",
  "source": "@devtools-extension"
}

From my understanding, this is because of DispatchRequest and the property Id

  internal class DispatchRequest<TPayload>
  {
    public int Id { get; set; }
    public TPayload Payload { get; set; }
    public string Source { get; set; }
    public string State { get; set; }
    public string Type { get; set; }
  }

Indeed Id is an integer and on the JSON it's a string.

I'm using the redux-dev-tools version 2.17.0

Error_Blazor-state

FieldAccessException although IClonable is implemented

Hi,

I'm using Blazor-state with the UseCloneStateBehavior enabled.

Everything worked fine until I introduce a value object in my state. This change throws a FieldAccessException when calling my reducer. I think this is because blazor-state doesn't know how to clone this value object, so I have implemented the IClonable interface for it, but that doesn't fix the issue.

Is there a way to make it work ?

thank you !

libman.json?

Hi

When i add your Nuget package "Blazor-State" (preview-6), a linked file "libman.json" appears in the project.
Is this file needed / intended?
It can not be deleted.

Cheers

Initialize state from BlazoredLocalStorage

Hi,

I am starting now my journey with Blazor. Is there any practice how to initialize the state from local storage?

public partial class UserProfileState : State<UserProfileState>
    {
        public string DisplayName { get; private set; }
        public override void Initialize()
        {
            // here I would like to use local storage to check if I can init state from local storage
            DisplayName = "";
        }
    }

More flexibility with cloning state

blazor.state 1.0.0-preview6.19307.2-20190710-124031
.NET Core 3.0.100-preview6-012264

I found some time to experiment with the current Blazor preview and blazor.state. I seem to have ironed out most of the glitches but I have one problem, still:

I need to use IOrderedEnumerable<KeyValuePair<string, int>> but AnyClone does not support this format.

Until now, I just implemented public override object Clone() => new TilesState(this); but this does not work any longer.

One solution would be to have the Clone method optional. Use only if overridden.
If you have a better Idea, I am all ears.

Error:

AnyClone.TypeException: Unsupported IEnumerable type: OrderedEnumerable`2
   at AnyClone.CloneProvider`1.

Preview 6

Hi there

thanks for the great library

Are there any plans to upgrade to support the latest preview?

thanks

Julian

Updating other components after CounterState change

Hi,

I played a bit with the code in the tutorial (https://timewarpengineering.github.io/blazor-state/Tutorial.html).
After that, I injected a IStore inside the NavMenu template.

In the code, I wrote the following: int Count => Store.GetState().Count;
Based on that, I am able to present the count value behind the Counter link in het NavMenu:

Counter (@count)

It initializes correctly when the application starts up.
Although the value is not updated on each click on the button on the Counter page but only after routing to another page.

How can I implement live updates on the NavMenu after every change in CounterState?

Thank you for your reply and help!

Regards,

Folkert

How to enable ReduxDevToolsBehavior

Hi, first of all thanks for sharing your work.
Hi, I want to try ReduxDevTools with blazor-state, but didn't found sample in docs

services.AddBlazorState(conf => {
    conf.Assemblies = new[]{
        typeof(Startup).Assembly,
    };
    conf.UseReduxDevToolsBehavior = true;
});

And that I see in firefox:
ReduxDevTools

p.s. a prefix for args name in public methods is annoing

Making the Weather Forecast Service call an actual API instead of returning mock data does not work

I was having a play around with your timewarp-blazor template and I noticed an issue if you were to make the weather forecast service call an actual API instead of returning mock data.

In .\MyTimeWarpBlazorApp\Source\Server\Features\WeatherForecast\GetList\GetWeatherForecastsHandler.cs if you were to inject HttpClient, the noticeable error you'd see is "Error constructing handler for request of type MediatR.IRequestHandler" but in the InnerException you'd see the actual problem is "RemoteNavigationManager' has not been initialized".

To reproduce the error, you can just add a constructor in the above mentioned file with HttpClient as parameter to be injected.

I've done it in the below way following a thread about this problem:

private readonly IServiceProvider _provider;

public GetWeatherForecastsHandler(IServiceProvider provider)
{
  _provider = provider;
}

public async Task<GetWeatherForecastsResponse> Handle
(
  GetWeatherForecastsRequest aGetWeatherForecastsRequest,
  CancellationToken aCancellationToken
)
{
  HttpClient client = _provider.GetRequiredService<HttpClient>();
}

This is not a problem with Blazor-State itself (as I understand) but I'd like to see how differently you'd structure the api calls to get this working.

Thanking you in anticipation.

Cannot get current state

For all of these examples I am using Client-Side hosting of the Blazor application and I have a BreakpointManagementDisplay component that I am using to explore state management. So in index.razor I have

...
<BreakpointSummaryDisplay/>
...

One of the options to get current state is apparently moving the GetState function into the component as outlined on the main web page.. But this has some problems
GetState
The first is apparently 'this' needs to derive from a specific class which cannot be done as I understand it in the clients code-behind
GetState1
The second is the protection level will no allow access
GetState2

The other option for getting current state is to inherit from BlazorStateComponent. So I have the code in BreakpointSummaryDisplay.razor

@using BlazorState
@inherits BlazorStateComponent

Then in BreakpointSummaryDisplay.razor.cs

        private BreakpointManagementState BreakpointManagementStateState => GetState<BreakpointManagementState>();

        private BreakpointProjectSummary currentProject => BreakpointManagementStateState?.Project;

image

BlazorHostingLocation HasMono not working under net5.0

Apparently checking for Mono.Runtime is not useful anymore to check whether the blazor app is hosted serverside or clientside.

public bool HasMono => Type.GetType("Mono.Runtime") != null;

How can we check for running clientside / WASM under net5.0?

How to avoid a mass rerendering of everything that depends on only unchanged parts of a State object?

Anytime a handler mutates the state, any component that gets state properties and inherits from BlazorStateComponent will automatically rerender. Right?

So that means that any component that depends on one part of that state but not another part will still rerender regardless of what part of the state they need. In other words, if my component shows MyState.A but not MyState.B, and there is a change to MyState.B, my component will rerender even though it doesn't need to.

Suppose I enable a rather complex domain object to be edited piecemeal. So the user might edit a CommentsPanel that internally uses CurrentOrderState.OrderComments and a RushShippingPanel that internally uses CurrentOrderState.IsRushShipping, along with dozens of other properties. So now any change anywhere in the state will result in dozens of components being rerendered when it is more desirable that only one part at a time needs to be rerendered. Is there any way to get more granular with rerendering of components that inherit from BlazorStateComponent? It strikes me that rerendering everything that depends on a state object when anything in that state object changes (because it's a whole new state each time) is a very blunt approach.

I am thinking there should be a way to avoid rerendering for unchanged parts of the state, as it is inevitable that even the simplest properties on a state object will themselves have properties, many of which won't change.

Side note: I am using the term "rerender" for the process by which .NET (in WebAssembly) runs the C# code to figure out the overall presentation state of each component in memory. After that, OnAfterRender is called, then manipulating the DOM is a subsequent process. I try to avoid using the term "render" to mean "manipulating the DOM", since it seems Microsoft uses it to mean running the C# code.

For pages of significant scope, rerendering can be the source of much slowness. If I am showing a 30x10 cell table, and each cell has 1-3 components in it, it can be quite burdensome to rerender (run the C# code to determine what the DOM should become) hundreds of components. So it would be nice if there was a way to avoid rerendering a component if the parts of the state it depends on have not changed. I have written a small package to do this apart from state management, but I was hoping that changes due to state management wouldn't need such a thing (nor do I see a way to make them collaborate together).

Vue and React seem to automagically handle this (I think internally they compare previous state to new state on a per-property basis), but not so with Blazor (hence the need for StateHasChanged at all).

Save state over authentication redirects

Hi @StevenTCramer

I've just started testing your library - great effort! appreciate your work!

Have you considered saving the user's state into session so that it's not lost due to authentication redirects when their token expires?

The ASP.net team has some instructions here.

I guess you're already serializing/deserializing for the redux tools / time travel and you already have an id/guid for each state instance so its just a matter of saving/retrieving from session in a custom Authentication.razor... I think I could do it, but it would take me 100x longer than you!

Regards

Brett

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.