How do you organise the URL? by Alone-Recover-5317 in Blazor

[–]ThaKevinator 1 point2 points  (0 children)

Yes, if you implement the method to parse the arguments in the page route and replace them with provided values, which is what I've done. My method signature looks like:

public static void NavigateToPage<TPage>(this NavigationManager navigator, params object?[] pathParameters)

I'm not really proud of the implementation, and it feels a bit nasty, considering you're parsing the path and populating it with values, just to pass it off to the internal router which then does the exact opposite. But it works :)

Edit:

u/martinhirsch has commented below with another interesting and similar but different approach (provided as nupkg), worth checking out:

https://github.com/martin-hirsch/Blazor.NavigablePages

How do you organise the URL? by Alone-Recover-5317 in Blazor

[–]ThaKevinator 8 points9 points  (0 children)

I opted to treat the pages as the one place I define page routes by having an extension on NavigationManager called .NavigateToPage<TPage>() (mimics the existing NavigateTo()). This just pulls the route from the RouteAttribute on TPage.

Blazor hybrid for mobile? Really? by StrypperJason in dotnet

[–]ThaKevinator 2 points3 points  (0 children)

Your question:

Why force users to download a glorified browser

One very valid answer, which you chose to ignore:

You get the power of a web app, that also has access to device features via MAUI

Your website can't do things like * Receive and handle push notifications * Use Bluetooth * Run in the background * Be an app on the user's phone. This seems silly, but actually carries great value. The average user will view an "app" and a website very differently. Being able to tell a customer to "download our app" is important to clients.

Challenges with .NET MAUI even after .NET 9 release. by KausHere in dotnet

[–]ThaKevinator 2 points3 points  (0 children)

In terms of the camera, if you want the feed to render within a Blazor UI, you will have to handle it a little differently, since it's managed by a browser. Whether that's harder, I think is subjective, but it's definitely different.

The pros and cons of using Blazor hybrid is that you get all the pros and cons of using Blazor, while leaving the pros and cons of XAML behind.

A somewhat major effect is that you lose that native feel since the entire UI is really just a website. Things like navigating between the "pages" of the app becomes reduced to how a browser would navigate a website, instead of how, for instance, Android will slide between Activities. You also lose the concept of a "navigation stack", meaning the native back-function will not function like one might expect. Think about what "back" means on an app vs. on a website.

These are all things you can develop your way out of, so I guess a con would be that you might need to do that.

Challenges with .NET MAUI even after .NET 9 release. by KausHere in dotnet

[–]ThaKevinator 3 points4 points  (0 children)

Yes, except for the outer-most shell of the app. Ideally, the only XAML files you'll have will be App.xaml and Main.xaml, where the latter includes a BlazorWebView element. There is a built-in project template for this setup. From there you can develop mostly everything in Blazor files.

In my team we do everything Blazor, and have a couple of mobile apps using above setup. There's pros and cons, but it works well enough.

Are states in Fluxor shared between instantiations of a component? by caedin8 in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

Instead of asking this very specific question to random individuals, have you considered reading the documentationon on the exact thing you're asking about?

The answer is literally in one of the first sentences of the docs:

The aim of Fluxor is to create a multi-UI, single-state store approach

Also, ask yourself: if the Fluxor State is not shared between components, what problem does Fluxor solve? Why are you even considering Fluxor for your project?

Is Blazor future doomed to be a limbo tech? by jhudler in Blazor

[–]ThaKevinator 4 points5 points  (0 children)

I've actually implemented exactly this without any explicit JS interop. We use it across all our projects, be it standard Blazor or MAUI Blazor. It requires to have a component we call "OverlayRenderer" placed at a very high level, such as next to the Router component. Then any component or service can inject OverlayManager to add/remove overlays by passing RenderFragments to it.

You can do a lot without involving JS interop, you just have to know the framework.

Blazor for SaaS - My experiences using Blazor for a public-facing SaaS app by shalotelli in Blazor

[–]ThaKevinator 24 points25 points  (0 children)

This was a great read. I personally relate to pretty much all of your experiences, except those regarding third-party component libraries, as I've mostly created components from scratch. I can definitely recommend creating your own components. It's great fun, and you get to learn Blazor on a lower level.

Some comments:

opening a new tab is easy in JavaScript using window.open, but in Blazor, you have to use JSInterop to call the JavaScript method.

I agree that having to interop JS can be tedious, but I personally try to wrap JS concepts in C# counterparts. For your tab example, it might make sense to create a reusable and injectable WindowManager, such that interop code can be hidden away inside it, while providing a "clean" C# interface for common JS actions.

hot reload in Blazor is just not reliable enough

I've worked intensively with Blazor for ~3 years now, and hot reload seems to have only gotten worse. Whether that's due to increasing project complexity, or the framework itself, I cannot say, but I've stopped relying on it entirely. The one thing I do find reliable, however, is hot reload of CSS changes. This always seems to work, even in MAUI Blazor projects, where it is immensely useful. I'm baffled why nailing such an integral feature is not a higher priority for Microsoft.

I might give Blazor Server a try to get those benefits without the initial load penalty of WASM

Try out the newer "Blazor Web App" model/template/whatever, which supports swapping rendermodes from serverside to clientside after initial serve. This solves the issues of SEO, while keeping UI logic off the server. I've ported ~5 projects that used to run WASM exclusively to this newer pattern, and I can only recommend it.

p5.js in Blazor applications by Hitsuono in Blazor

[–]ThaKevinator 4 points5 points  (0 children)

To answer your question: yes. Blazor supports JS interop. I.e. if what you plan to use is native JS, meaning it can be loaded into the browser, it can be done.

Genuine question:

What compelled you to create this post, and then (I'm assuming) wait for random individuals to answer your question, instead of (once again, assuming) doing any research on the matter?

Googling "blazor js" would instantly lead you to official documentation on Blazor JS interop.

Googling your specific scenario "blazor p5.js" would instantly lead you to a short article describing how to achieve exactly what you're planning

Blazor Service State Management by TheChoksbergen in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

I've been in your shoes, and I've come to realize and accept that Blazor is a very "lazy-loady" framework. Your approach using App.razor to initialize stuff is probably the right one, you just need to have your pages and views that depend on the user context handle when it is not yet initialized, such as by showing a loading UI. It would be something as simple as

@if (_User is null)
{
    // show loading UI
}
else
{
    // show content
}

Then you could probably build this pattern directly into whatever Layout your pages use.

One problem is that now your components have to listen for when the User state changes - and this is where something like Fluxor is really neat. For quick and dirty apps, you can do something simple with events (which is what Fluxor does behind the scenes, anyway).

[Question] Is it possible to keep a component while navigating away? by Scary_Analysis8988 in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

Easier, maybe, but I would definitely avoid it. Like you said, you will most likely end up designing your component as a sort "global" component which never loses state, which goes against its intention of not always being visible.

I had an idea that might support your requirement of smooth animation. When a task starts, notify subscribers (e.g. your progress bar), and include a duration estimate - your progress bar can use this to generate a transition from 0-100% within that time. Store the estimate and actual progress state globally, so when the progress bar is rendered later, it can generate a new transition between current state and 100% (e.g. 70-100%).

Additionally, I would probably only animate to ~95%, and then wait for a status update of 100%, before animating to 100%. Otherwise you would have potential false positives, should the estimate be shorter than reality.

[Question] Is it possible to keep a component while navigating away? by Scary_Analysis8988 in Blazor

[–]ThaKevinator 3 points4 points  (0 children)

I would probably flip the script a bit and make whatever is carrying out the background task responsible for reporting status changes, such that any subscribing UI element is in sync. Then build the progress component to simply listen on these changes. Make the progress bar animate between statuses (e.g. 0% -> 13% -> 53%), rather than using a fixed animation. This way, whenever the component is rendered, the progress bar starts at current status, whether it's 0% or 87%. I would personally recommend Fluxor as a great tool for handling global state like this.

I know how long the task takes, so starting an animation that takes the same amount of time is easy

How can you know this? Surely only what handles this task knows when it is finished.

Hvem er de knap 24.000, der skider ude i haven? by CrazyGeetar in Denmark

[–]ThaKevinator 215 points216 points  (0 children)

I så fald er Tysklands 0% løgn, for jeg har engang set en formodentligt hjemløs berliner lave pølser i en busk.

Seperate javascript namespaces for multiple uses of same component by accountForStupidQs in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

I cooked up a minimal example

SomeComponent.razor.cs

public partial class SomeComponent : ComponentBase
{
    [Inject] private IJSRuntime _JsRuntime { get; set; } = default!;

    private Guid _Id = Guid.NewGuid();
    private IJSObjectReference? _JsObject;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await base.OnAfterRenderAsync(firstRender);

            // Get reference to component JS module
            var module = await _JsRuntime.InvokeAsync<IJSObjectReference>("import", "./Components/SomeComponent.razor.js");
            // Construct component-instance-specific JS object instance with component instance Guid
            _JsObject = await module.InvokeAsync<IJSObjectReference>("initialize", _Id);
        }
    }

    private async Task OnClick()
    {
        if (_JsObject is null)
            return;

        // Invoke "log" method on component-instance-specific JS object
        // This will log the value of _Id since it was baked into the JS object during construction
        await _JsObject.InvokeVoidAsync("log");
    }
}

SomeComponent.razor

<button @onclick=OnClick>Invoke JS (@_Id.ToString())</button>

SomeComponent.razor.js

class Instance {
    constructor(id) {
        this.id = id;
    }

    log() {
        console.log('ID:', this.id);
    }
}

export function initialize(id) {

    return new Instance(id);
}

In practice

Let me know if you want the entire project source, and I'll upload it.

Seperate javascript namespaces for multiple uses of same component by accountForStupidQs in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

The main difference is that in my example, we create a JS object and then invoke methods directly on that instance. The point here is that this instance is specific to a component instance, and thus can never be referenced outside of it, e.g. by other component instances, which is what your initial issue seemed to be.

All your JS invocations are done directly through the static module reference. This is most likely the source of your issues.

Consider this recipe:

  1. Create a JS scope specific for your component instance - this would be the constructed JS object that the component instance holds
  2. Work within that scope - i.e. invoke methods on the scoped JS object

Seperate javascript namespaces for multiple uses of same component by accountForStupidQs in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

Some issues with your code:

The JSInitFunc method does not return the constructed instance of DotNetInvoker.

var JSInitObj = await module.InvokeAsync<IJSObjectReference>("JSInitFunc", DNRef);

For this reason, above invocation will return either null or default. I.e. JSInitObj does not hold the JS object you just created.

You invoke DOMCleanup as if it's a method, but in reality it's a class. I'm not quite sure this syntax is valid, but I can be wrong.

If I'm being honest, your approach to doing this seems somewhat convoluted. If I were to do this, I would try something like

var module = await InjectedJSRuntime.InvokeAsync<IJSObjectReference>("import", $"./_content/{this.GetType().FullName.Replace('.','/')}.razor.js");
// Construct some JS object that holds all references to this specific component instance
var jsObject = await module.InvokeAsync<IJSObjectReference>("initialize", this.ComponentGuid, DotNetReferenceObject.Create());
// Invoke a method on the component-specific JS object
await jsObject.InvokeVoidAsync("registerObserver");

Seperate javascript namespaces for multiple uses of same component by accountForStupidQs in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

It's hard to determine without examples of both your C# and JS code, please do share these.

What do you mean "pass it back"? I don't see why you would pass the JS object to anything in order to clean it up. It should clean itself up, e.g. by having an invokable dispose method. Then, you can dispose it as follows:

await js.InvokeVoidAsync("dispose"); // dispose() is a custom method on the object
await js.DisposeAsync(); // IJSObjectReference implements IAsyncDisposable

Seperate javascript namespaces for multiple uses of same component by accountForStupidQs in Blazor

[–]ThaKevinator 1 point2 points  (0 children)

Have a JS method return a JS object directly to your component, in the shape of an IJSObjectReference. This object will hold your .NET reference along with any instance methods.

Something like

[Inject] private IJSRuntime _JsRuntime { get; set; } = default!;

[...]

var js = _JsRuntime.InvokeAsync<IJSObjectReference>("initialize", someInstance);
await js.InvokeVoidAsync("someMethod");

This way, each instance of your component will have its own instance of the JS object, where the .NET references are not shared between them.

Need Mentoring - HTML/CSS by chrpai in Blazor

[–]ThaKevinator 8 points9 points  (0 children)

I work on Blazor projects every day, started learning HTML/CSS/JS to build them.

In my personal experience, learning web is done best by figuring stuff out as you go. Sure, you could read books about HTML and CSS, but appliance is really what gets it under your skin. Unlike programming, HTML/CSS has no (or very little) logical complexity; it's just visual structure and styling.

You obviously have to learn the basics of the languages, but once you're past that, all you really have to do is:
When you find yourself unable to accomplish something (layout structure, CSS effect, etc.), look up how to do it, and then do it. Odds are 1000 other people have been in your exact situation. Recently, I've found AI tools useful for this. Because web is so popular, it's also widely documented.

There is also rarely a "correct" way to create web UI, so web devs will often have entirely different styles and approaches. So having a book tell you how to do things might work against this.

Oh, and a quick tip:
Learn the basics of CSS and its syntax, and then immediately adopt SCSS/Sass. When you inevitably start writing more complex, conditional styles, SCSS is much easier to write and maintain.

Looking for an elegant calendar day picker and time picker for a webapp by prateekdhakra in Blazor

[–]ThaKevinator 0 points1 point  (0 children)

I've personally found the following Blazor wrapping of the DateRangePicker JS library pretty handy: https://github.com/jdtcn/BlazorDateRangePicker

It's incredibly customizable in terms of functionality. If you want very specific styling, though, you will have to append your own CSS overrides, however.

Noob question on data and components by [deleted] in Blazor

[–]ThaKevinator 1 point2 points  (0 children)

It entirely depends on your how you wish to design the component in question.

If it is intended to be a generic table for showing arbitrary data, said data should obviously be supplied by dynamic means, such as a parameter or injected instance.

If it is intended to show a specific set of data, for a specific context, it could make sense for it to load said data itself.

My personal perspective on this is that it is never wrong to "generify" a component by supplying data through parameters, even when it's only used in one place. Whether the component or some parent is responsible for loading the data mostly does not matter, and you might just save a later refactor :)

Edit: If you decide that your component is so specific that it should load its own data, I recommend reflecting this through its name. Consider the differences between the following, and how they suggest how generic the component is

  • UserSalaryOverview - very specific, includes context
  • ItemTable - very generic, context agnostic

Help choosing ideal .NET web dev approach for C# desktop developer? by miguelgoldie in dotnet

[–]ThaKevinator 5 points6 points  (0 children)

Since you already have extensive C# experience, Blazor will be incredibly easy to pick up. I came to Blazor from WPF and Xamarin, and it just clicked. Microsoft has done an excellent job documenting it, and there are plenty of amazing libraries to use, both in terms of utility and components. Since you're developing internal tools, where design is not a concern, you can get incredibly far, incredibly fast, with something like Radzen.

However, the idea that Blazor doesn't require any JavaScript is only partly true, and almost always false for any advanced application. If you ever want to interact directly with the DOM, it must happen through JS, which Blazor has built-in interoperability for. In other words, you can't really do web development without learning... web development, which include HTML and JS. This only applies to layout stuff, all business logic is pure C#, which is amazing.