Hyston blog
About • RSS

Hello World for D3JS + SignalR + MobX (+ react?)

2022-06-29 22:35

As I mentioned previously, I was thinking about creating series of posts about different technologies, that I use currently at work. I even created small home project, that contains them all, but as it turned out, it was much more funnier to write code than to write blog post about code. And my explanation was not complete enough, even inaccurate, I guess, because it was already a month since I wrote that proof of concept.
So I decided just to share a link into it here, as an example of simple use of:

Hope this examples would be usefull for someone. At least, it would be for me, when a couple years later I would try to recall, what have I done.
Link to repo: github


D3Signal: npgsql and dotnet

2022-05-31 22:52

Intro

Recently I created a small application, that contain most of technology stack, that I’m using at work and/or learned recently: dotnet, react, mobx, d3js & signalR. So I decided to make small series of posts, in which I add some tips for each of these frameworks. I’ll update this list as soon as posts would be available.

Docker

Postgress is one of the famous db in the world of software development. Although my knowledge does not allow me do dig deep in differences between databases, I prefer to use postgress for my dotnet projects, because it require less resources than MsSQL and allow db migrations unlike SQLite. Simpliest way to install it would be, of course, official installer on local machine, but I prefer to use docker. This way it’s easier to support multiple versions, add plugins and throw away data, that is not needed. To run postgreSQL from docker:

docker run -e POSTGRES_USER=user -e POSTGRES_PASSWORD=pass -e POSTGRES_DB=d3signal_db -p 5432:5432 -v db:/var/lib/postgresql/data -d postgres:14

-e flags used to set environment, especially user name, pass and db name, that would be used. -p is mapping container port to local port. In this case it’s the same, but if I run local Postgres in addition to one in docker, ports can be remapped to avoid confusion. The most interesting param here is -v, which creates docker volume db (if it’s not existed) and mounts it into container. When container would be stopped, this volume persisted and data can be saved this way between reboots.

Dotnet

There are many ways to connect dotnet to sql (as well as there are many types of dotnet application). I usually use EntityFramework and include same steps:

public interface ICirclesContext
{
    DbSet<Circle> Circles { get; }
    Task Save();
}

Name here is better to be pointed to application name, like MyAppContext. In this case the whole application is about circles 🙂 Implementation:

public class CirclesContext: DbContext, ICirclesContext
{
    public CirclesContext(DbContextOptions options) : base(options) { }

    public DbSet<Circle> Circles => Set<Circle>();

    public async Task Save() => await SaveChangesAsync();
}
var connectionString = builder.Configuration.GetConnectionString("db");
builder.Services.AddDbContext<CirclesContext>(ops => 
    ops.UseNpgsql(connectionString));
builder.Services.AddScoped<ICirclesContext>(p => p.GetService<CirclesContext>()!);

Of course, config file should contain connection string (although, in production it usually goes from environment variable where it appear by CI/CD pipeline):

{
  "ConnectionStrings": {
    "db": "Host=localhost;Username=user;Password=pass;Database=d3signal_db"
  }
}
app.Services
    .CreateScope()
    .ServiceProvider
    .GetService<CirclesContext>()?
    .Database
    .Migrate();

More about migrations and how to create them can be found in microsoft documentation


Without any other details about .net application type, these are simplest steps to add postgreSQL support to our application.


How to make gif?

2022-02-15 22:41

I need to add new feature to my site - posts-links with simple commentary. I was going to write how to use ffmpeg to create amazing gifs, but guys from GIPHY already described everything that I know (and more!) here: How to make GIFs with FFMPEG
With combination of youtube-dl & ffmpeg the only limits are imagination and free time. I, as example, finaly created by myself this gif with medic from TF2, that I could not find anywhere.
medic


Dynamic

2022-02-14 22:51

I’m writing on C# for 5 years now and keep finding things, that are not widely used, but they are exist already for a long time. Just recently I found the need of dynamic keyword. Usually new variables are defined with var or with value type directly:

Foo foo = new Foo();
var foo = new Foo();

These are actually two identical lines, compiler would define actual type on second lane from right-hand operator.

But what if type is unknown in compile type? I have met a problem, where actual type is created by external parameter - and there is no common interface that can be used to aggregate possible types. In these uncommon scenarios dynamic can be very handy.

Suppose, we have a three types:

public record TypeA(string A);
public record TypeB(string B);
public record TypeC(string C);

Then we can declare a function, which return any of this types by random:

dynamic GetRandomType(Random random) => random.Next(3) switch
{
    0 => new TypeA("a"),
    1 => new TypeB("b"),
    2 => new TypeC("c"),
    _ => throw new Exception("out of random range")
};

By making dynamic return type, we tell a compiler, that he should not care, which type it actually is. Problem here in that compiler agreed and skip any further compile-time checking:

var random = new Random();
var result = GetRandomType(random);
result.DoSomething(); // We would get runtime error here

A good thing is, that actual type is available in run time and overloading works even with dynamic type:

public class Foo
{
    public static void Do(TypeA obj) => Console.WriteLine($"Do a: {obj.A}");
    public static void Do(TypeB obj) => Console.WriteLine($"Do b: {obj.B}");
    public static void Do(TypeC obj) => Console.WriteLine($"Do c: {obj.C}");
}
Foo.Do(result); // correct function would be called, based on result type

This can be very handful for places, where actual behaviour is unknown beforehand. As example, I wrote a event parser, where each event contain a enum with event type and object payload. And for each actual event the payload would be a completely different DTO, as well as event handlers would have completely different behaviour.


Svelte

2022-01-03 18:24

Most of current frontend frameworks are build upon making virtual DOM. All UI changes are applied to this structure, then it is getting compared to real DOM and only then framework adjust actual page. Just before Christmas, when there were not a lot of stuff to do, one collegue mentioned to me Svelte framework, that use different approach and I decided to give it a try.
TLDR: using virtual DOM is slow; All changes can be made manually, and code can be generated in compile-time. Svelte moves complexity from client browser realtime into dev machine compile time.
All code is written in html-like files with .svelte extension. On building (svelte-kit build) all code in <script> get compiled into javascript, <style> goes into css. I have not made any real comparisons with big projects, but for small hello worlds it loads really fast and generates a lot of "compiled" javascript code that became unreadable really fast.
For me, actually, the biggest benefit was a flat learning curve. This is component-based framework, that is really start with. I'm using react lately and I find that there are too much conventional boilerplate code. For example, here is hello-click-me-world example in svelte:

<script>
	let count = 0;

	function handleClick() {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

Html can be enchanced with conditional statements and loops:

{#each values as value}
	<li>{value}</li>
{/each}

Input elements can be binded by attributes bind:value. Even regular variables can be "reactified" by adding $: before declaration.

<script>
	let count = 0;
	$: double = count * 2;
</script>

<button on:click={e => count += 1}>Click</button>
<p>{count}</p>
<p>{double}</p>

In this example after clicking button second label would not be updated without $: statement. As I understood, first label is getting updated anyway because it is already used in handler.
DOM gets updated on each assignment operator, not by anything else. So, if you need to update array, then use spread syntax: values = [...values, { name: newName }];

I think it is a nice framework to play around with, very easy to start, however, it's conventions were broken by moving to each major version and it's unclear (as with every new js-framework) how popular would it be and how many support will it get. May be it can be used for small dev-related project, where react or angular would be overkill.
And for my purposes I'll continue to explore react in my free time, since this seems to be the most popular frontend. Although typescript is very painfull and unfriendly after years of writing in C#.1


Previous →