0

I need to read user id and some more data from session which is crucial to get specific data from the server, check permissions and rendering the screen.

I use Blazored.SessionStorage nuget to do that and use the following code line:

curData = await sessionStorage.GetItemAsync<CurrentData>("CurrentData");

At start I set the following line in OnInitializedAsync procedure but since session reading is async, the code proceeds and try loading data when there is no value in curData variable.

Then I tried to move session reading to SetParametersAsync which seems to be a better approach since this is the first procedure in the lifecycle. Same problem here.

So I tried some methods to wait for the await session to end but it did not work and it stuck the code and the code will not continue.

Bottom line I need help to find a way to load session data in SetParametersAsync and wait for it to finish reading before continue the component lifecycle.

Thanks all

4
  • What Identity provider do you use ? Why do you need to store the user id in the session storage? Are you acquianted with a similar library by Microsoft ? Commented Apr 18, 2022 at 9:23
  • See this: learn.microsoft.com/en-us/aspnet/core/blazor/… Commented Apr 18, 2022 at 9:30
  • I use my own app identity Commented Apr 18, 2022 at 10:47
  • Why are you using client side sessionStorage? On any browser one can open up dev tools and modify the user id and permissions. Commented Apr 19, 2022 at 9:39

3 Answers 3

4

At start I set the following line in OnInitializedAsync procedure but since session reading is async, the code proceeds and try loading data when there is no value in curData variable.

That's not the issue... The issue is that in Blazor Server you can't perform any JS interop before your app is rendered.

Use the OnAfterRender{Async} lifecycle methods instead.

Note: The above answer is relevant only if your Blazor Server App has prerendering enabled. However, if prerendering is disabled, you should use OnParametersSetAsync, not OnInitializedAsync

UPDATE:

After previewing your code once again, I believe that the setting of CurentData had been successful, right? Without knowing wether pre-rendering in your app is enabled or not, you may do the following:

This code snippet may be used with pre-rendering disabled:

I believe this is the thing you're looking for...

@if (curData == null)
{
     @* Display here a spinner to indicate that data is being  
        loaded*@
     <p>Loading...</p>
}
else
{
   // put here your code that should be render when CurrentData 
   // is available 
}

@code {
    
  
    private CurrentData curData;

    protected override async Task OnInitializedAsync()
    {
         curData = await sessionStorage.GetItemAsync<CurrentData> 
                                               ("CurrentData");
    }

}

This code snippet may be used with pre-rendering enabled:

@if (isConnected)
{
    // put here your code that should be render when CurrentData 
    // is available
}
else
{
    <p>Loading...</p>
}

@code {
    
    private bool isConnected;
    private CurrentData curData;

    protected override async Task OnAfterRenderAsync(bool 
                                                   firstRender)
    {
        if (firstRender)
        {
            isConnected = true;
            await LoadStateAsync();
            StateHasChanged();
        }
    }

    private async Task LoadStateAsync()
    {
       curData = await sessionStorage.GetItemAsync<CurrentData> 
                                               ("CurrentData");
    }

}
Sign up to request clarification or add additional context in comments.

7 Comments

I will try that later on ...
Incidentally, what you do is wrong; I mean using the session storage. Session Storage is also not secure. Instead you should use in-memory state container service, which should be scoped to the circuit (connection), and injected into client components. חג שמח, חביבי
Tx, any link to a code sample ? חג שמח גם לך
Link to a code sample ? That do what ? Create in-memory state container service ? This may help you how to create a service used by components: stackoverflow.com/a/62042629/6152891 And this is how you can pass values from the _Host.cshtml file to the Server Blazor App itself: stackoverflow.com/a/59538319/6152891, and then add the values to a state container service that you can inject into your components. You may also add services to the DI container with data retrieved at the same time. There are various ways to do things,
and what mehtod you choose depend on various constraint, including your design and knowledge. I wouldn't like to add more content here, but if you have more questions, please email me: [email protected]
|
1

I need help to find a way to load session data in SetParametersAsync

No, do not use SetParametersAsync() , it is very tricky and time-sensitive. Doing an await there will probbaly derail your normal paramter setting.

since session reading is async, the code proceeds and try loading data when there is no value in curData variable.

When you put the 'loading' in OnInitialziedAsync, after getting curData then that problem is solved.

But your markup section will have to deal with null in the first render though. Keep it simple and use @if(curdata != null) ...

1 Comment

I do deal it in the markup but it is not enough because I need to pull data based on that curData value regardless the markup
0

This works for me. I am using Blazor server

<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />

<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.