09 Aug 2021, 15:42

Bolero
XXX lists XXX

What do you think about blazor?

What about Elm?

What if Elm architecture was running in blazor, but in F#?

Well, that is what bolero is about.

Fsharp

Getting started

  1. Install dotnet if you haven’t already
  2. go to https://fsbolero.io/ and follow the 3 easy steps to have your app up and running
  3. Continue following this guide.

Understanding the Elm architecture

Bolero is based on the elm architecture.

this is divided in 3 items:

  • Model: it represents the current state of the app.
  • update: this function is the only way to change your model.
  • render: it is how your html will be rendered.

Well, there is also the init function, where you give the initial state of the application.

But that is it. Anything else is built on top of this 3 items.

Simple, no?

Elm architecture

Model

there is only one model, it is global (inside the component) and it contains every detail in the application. your working data, cached values, state of the dropdowns and popups… everything

Example:

type Model =
    {
				page: Page
				date: DateTime
				error: string option
				items: Item list
				others: Other list
				touchInfo: TouchInfo
    }

Update

Nothing can change in the model without being part of this method. It is a blessing and a curse. It is much easier to find out where something is being updated, but you end up with huge update methods. Then you can start passing the update to another function. This helps with the size, and it is ok if you are well organized. but it could also mess up your codebase.

let update message model =
    match message with
    | SetPage page -> { model with page = page }, Cmd.none
    | Error exn -> { model with error = Some exn.Message }, Cmd.none
    | ClearError -> { model with error = None }, Cmd.none
		...

View

The view is called on every update to the model. You can use functions to represent the html, and also include some logic to hide or display items based on the model.

Example:

let view model dispatch =
    div [attr.``class`` "columns"] [
        div[][text " x "]
        div[attr.``class`` "has-text-centered"][
            button[attr.classes ["button"; "is-small"]; on.click (fun _ -> dispatch PreviousDay)][text "<"]
            span[attr.classes ["dashboard-date"]][text (model.date.ToString("yyyy-MM-dd"))]
            button[attr.classes ["button"; "is-small"]; on.click (fun _ -> dispatch NextDay)][text ">"]
        ]

Understanding monads

Nah, just kidding I believe having this basics of functional programming everywhere is one of the reasons of why people never go deep into it. Nobody needs yet another “let me explain functional for dummies” If you are like me, you rather start a project and learn along with it.

aha moments

There are a few moments where I got stuck, but then it all make sense

Any update to the model is automatically reflected in the GUI

yes, you dont have to add any function

The ONLY way to update the GUI is by changing the model

That means anything you want to change must be in the model. Even state of your dropdown, popup, etc

You can use anything from C#

But please don’t overuse it. Try to keep consistent using F# types and functions.

I can modify the default functions

Just because the update function doesn’t have a parameter I want, it doesn’t mean it cannot have.

In this example I was stuck for 2 days trying to access the JavaScript runtime from the client side.

Then I found out I can pass my own update method with that parameter:

let update = update this.JSRuntime Program.mkProgram init update view

I can easily interop with javascript from bolero client

The interop will not only call functions passing integers/strings It will pass objects between javascript and bolero.

let LoadCheckins (js:IJSRuntime) (date:DateTime) = Cmd.OfJS.either js "FromStorage" [| "checkins_" + date.ToString("yyyy-MM-dd") |] CheckinsLoaded Error

24 Mar 2012, 17:31

PetaPoco. Said whaaaat?
XXX lists XXX

So, maybe some of you guys checked out my dead database project, the dNet.Db. It is free and open source @ http://dnetdb.codeplex.com/ I started developing that framework because I always thought it is important to automatize the simple and boring part of database. And by this I mean that it load an object values should be as easy as object.load(), or object.LoadList() if you want an array. And it was working fine. But we all know how a project like that requires a lot of maintenance, adding new databases support, fixing bugs and things like that.

A few weeks ago I was talking about this to a friend and he told me about the project massive. Massive is nice, but it doesn’t support everything I needed (mainly because of the stored procedures), so trying to go further into that, I found the PetaPoco(http://www.toptensoftware.com/petapoco/).

This is the kind of framework I consider that fit all my needs:

  • really easy to install
  • easy to fetch objects from the db
  • supports sqlite
  • allows you to use plain old SQL for all the other situations.

So I’ve been using it for a bit now, and it hasn’t let me down. I am not thinking about using my framework anymore. So I decided to write a little tutorial of how it works.

Install: There is a nuget for that. If you don’t know what a nuget is, here is a link, probably I’ll talk about this someday, but this is really cool, check it out.

Model:

[PetaPoco.PrimaryKey("Id")]
public class Project
{
      public int Id { get; set; }
      public string Name { get; set; }
}

Voil’a… Easy as pie… then you could say:-Hum… the loading part might be tricky…. not really… this is the code:

var db = new PetaPoco.Database(“Base”); ViewBag.Projects = db.Fetch<Models.Project>("");

and that’s it. Ok, that’s not it. Well it is if you have a really simple object, but you don’t. So… now comes the tricky part? Yes. Compared to the other part it is. but not so much

The loading bit is exactly the same, but now I’ll add some more code to the model:

   [PetaPoco.PrimaryKey("Id")]
    public class Feature
    {
        public int Id { get; set; }
        public int ParentId { get; set; }
        public int ProjectId { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        [PetaPoco.ResultColumn]
        public Project project { get; set; }
    }
    [PetaPoco.PrimaryKey("Id")]
    public class Project
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [PetaPoco.ResultColumn]
        public Dictionary<long, Feature> Features { get; set; }
    }
    class ProjectFeatureRelator
    {
        Dictionary<long, Feature> features = new Dictionary<long, Feature>();

        public Project MapIt(Project p, Feature f)
        {
            Feature fExisting;
            if (features.TryGetValue(f.Id, out fExisting))
                f = fExisting;
            else
                features.Add(f.Id, f);

            f.project = p;
            p.Features = features;
            return p;
        }
    }

Now, this looks a lot, but let’s understand what happened there: 1 - I’ve added a new class (feature). This class have a primary key Id, and I want it to load the project associated with it. 2 - I’ve added a new property to the project class:Features. this is because I want the list of features to be loaded as well. Note that I’ve annotated the [PetaPoco.ResultColumn] to make the connection. 3 - So far so good, but now comes the ugly part: the join. I admit it is not an elegant code as the rest, but it is not so bad, and it is very easy, you just have to copy it, and use it in your code.

I don’t know if it is a good idea to use this in a big project, but for the small ones, I will definitely use it.

23 Mar 2012, 17:37

Aspnet_mvc
XXX lists XXX

So seems like asp.net mvc is finally popular? That’s perfect, I mean, this is how it should have been since the beginning.

Let’s start with what is mvc: Mvc is to build the application as model, view and controller. What does that means? It means that the view should be only responsible for showing the interface, the data access should be in the model layer, and everything else should be done by the controller.

Sounds nice, right? Old but gold… But the thing is… and how about the web? Usually we had a asp / aspx / php / jsp / etc file. This file is requested, and then, from this point on you can call your controller logic. But this isn’t the proper way to do it. This way your view is mixed with the controller.

And then, there was the light! true MVC to the web applications. Is this hard to implement? off course not, my little grasshopper…. You just have to think your application in a different way. and what is that way? Routes!

And your routes file should look like this:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

    }

And how do you use it? Easy: you set it as your controller name, and action, so every time the user types that address the method defined as action is called. so when the user types website/home/index, the method index inside the controller home is called.

Ok, we’ve got the code, but how to display it to the user? In the controller method, there should be a return View(). You can return View(“name-of-the-view”)

Now you have the request processed in the right place, and you have your view. Sweet! :D Buuuuuuuuut, something is still missing… and that’s because you have to connect those 2. And this is called the mighty ViewBag!

View bag - speaking like mr jobs would say - is a magical, fantastic… the better ever created object to carry values between controller and view. So how do you use this thing? Easy:

ViewBag.YourVariable = "The title";

and in the view you can use it like this:

By the way, this brings up another topic:RAZOR

Once again: this is magical, fantastic, amazingly simple. you can put C# code in the view just by adding a @ in front of it. And, if you want to put a chunk of code, just use

@{
  //several lines of code
}

and how about the model? Well… the model is the same as before, I won’t talk about it here. But that’s it for now. I’ll write more about razor.