Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use local storage in favor of storing user profile in database? #96

Open
oneparameter opened this issue Dec 17, 2019 · 9 comments
Open
Labels
enhancement New feature or request suggestion Consider addid this

Comments

@oneparameter
Copy link

Local storage is great for storing the UserProfile's properties LastPageVisited, isNavOpen and isNavMinified. It's easily accessible through jsinterop and you'd also would save valuable resources on the server because it removes the call to the server and the database.

@enkodellc
Copy link
Owner

@oneparameter Yes I have researched it a bit but it was several months ago.

Do you have a component to recommend?

It looks like they have updated the ProtectedSessionStore in 3.1.. https://docs.microsoft.com/en-us/aspnet/core/blazor/state-management?view=aspnetcore-3.1

In any case I am open to discussions / changes for best practices for the UserProfile. I first put it in because there was not much out there and at the time I think the scoped UserProfile was Loaded Once from the DB if it was null and the user was logged in. Then when it needed to update it would call the DB.

The only caveat I have with other components is they tend to not keep up with the latest changes and then I have to rely on doing other people's PR's and fixes. I was really waiting for MS to come up with a Profile / Session for Blazor to replace my "hack"

@enkodellc enkodellc added enhancement New feature or request suggestion Consider addid this labels Dec 17, 2019
@oneparameter
Copy link
Author

oneparameter commented Dec 17, 2019

Do you have a component to recommend?

By component to recommend, do you mean a component that is developed by someone else and incorporate that into your app?

It looks like they have updated the ProtectedSessionStore in 3.1.. https://docs.microsoft.com/en-us/aspnet/core/blazor/state-management?view=aspnetcore-3.1

I'd argue that keeping UI related information in localstorage or sessionstorage without using dataprotection is perfectly fine and harmless. If a user wants to change those values, let him go ahead.

The only caveat I have with other components is they tend to not keep up with the latest changes and then I have to rely on doing other people's PR's and fixes. I was really waiting for MS to come up with a Profile / Session for Blazor to replace my "hack"

So my question about other components is still important because I don't exactly understand what it is you mean by them.

Also, I think Microsoft won't be providing such specific components.

To provide an example as to how easy access it is to access local storage:

@inject IJSRuntime js

code {

    async Task AddToLocalStorage(string value) 
    {
        await js.InvokeAsync<object>("localStorage.setItem", "some-key", value);
    }

}

@enkodellc
Copy link
Owner

@oneparameter Yes I have seen this pattern before. Are you suggesting that update the UserProfile class to use this pattern to get / set the UserProfile data and subsequently to the server asynchronously when appropriate? I like it. I can create a branch if you want to refactor and submit a PR?

The "other" components I spoke of are 3rd party components like this: https://github.com/Blazored/LocalStorage

I come from using Asp.net Webforms for a long time and used their Profile Property Provider for most of this type of information. It was a bit costly because it would access the DB but of course that is server side so that design pattern is not good for Blazor WebAssembly.

@oneparameter
Copy link
Author

oneparameter commented Dec 18, 2019

@enkodellc I'd happy to redesign the profile part, but do you still even prefer to keep the user profile data in the database at all? - I'm talking about the data mentioned in my first post of course.

I mean after all, besides being able to keep menu state when switching devices or browsers, does your portal boilerplate really benefit from this? It just feels a bit gimmicky. But maybe if the whole point of the portal is to add as many showcases or examples, then yes.

Personally, I see every addition like that as another obstacle that might prevent someone from using the boilerplate in their projects since the user profile gets really 'woven' into the whole thing especially when you store it in the database like that.

@enkodellc
Copy link
Owner

@oneparameter thanks for you feedback. For me the User Profile Settings stored in a persistent data store is very beneficial, the current fields are a bit gimmicky because that is a starting point. In the application I am refactoring into Blazor, which is why I created Blazor Boilerplate, I store well over a dozen user specific flags or settings that enhance user experience.

I do want to showcase examples and of course I want to be aware of feature creep. I do plan on putting as much in there as I personally use in my projects.

Here are some examples I use for my User Profile:

  • Menu settings: minified, full, and in the future I am planning on doing a horizontal menu option as well
  • Last page visited
  • FirmId - My app a user might have access to multiple firms so this maintains which firm they are working on
  • AccountId - My app a user has several accounts to manage and this store which account they are currently working on
  • Each Account has some different options / flags that will enable or disable Nav / UI features like table fields
  • My app has several Reports and Report Types. I store which Report the user was using for each report type so when the user goes to that Report it was pre-selected with their last selection to save time.

If you have an alternative solution to using this type of data or have additional questions let's discuss on Gitter: https://gitter.im/blazorboilerplate/community

I have no ego in this app so I am very open to design and architecture opinions. Thanks!

@VR-Architect
Copy link

As you start to tackle this, please keep in mind the need for offline storage with auto-sync to server when reconnected to the internet feature. The user profile could be the first object for this. If I get to it first, I will add it back to the repository if desired.

@MaxLaurieHutchinson
Copy link

ever thought of using options.UseInMemoryDatabase("Database")); and a data persistence layer, that way it can be easier to getting setup for testing and having mock data.

This could be used with a DBContextFactory and and Data Initializer?

@enkodellc
Copy link
Owner

Honestly @Maximus258 I have been too busy with maintaining BB, updating MatBlazor, and my real job to do more features. That is where I was hoping more contributors would step in and do some advanced features / functionality since I have provided a ton of the UI / foundation for BB. If you wish to contribute to BB it would be greatly appreciated.

@prvit
Copy link

prvit commented Nov 7, 2020

Not sure if it needs to be implemented as someone can just take a package, for example Blazored.LocalStorage configure DI and inject when needed. In the box, it still will call

await js.InvokeAsync<object>("localStorage.setItem", "some-key", value);

but you have a great c# wrapper that's already covered by tests etc. That's how it would look like :

await localStorage.SetItemAsync("name", "John Smith");
var name = await localStorage.GetItemAsync<string>("name");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request suggestion Consider addid this
Projects
None yet
Development

No branches or pull requests

5 participants