Tag Archives: Tutorial

A C# Developer’s Guide to: ReactJS – Part 3 – Conditionally Rendering HTML in React

This is the third in a series of posts on interesting things I’ve discovered about React; the first of these can be found here.

One of the things that tripped me up early on while I was learning React (not that I’m a fully-fledged expert now or anything) was how to display HTML elements based on a given criteria. For example, say you only want to display a label while the form is loading, or you want to display a message based on other information on the screen.

If you were using a desktop binding architecture, say MVVM, you would bind the visibility to a visible property. Likewise in HTML, you may have a conditional style based on the bound model property. Let’s see how you might do that in React.

Create a new React Application

Let’s start by creating a new React application (using bash here):

This isn’t a particularly fast process, so maybe it’s time to get a brew.

Once it’s done, and assuming you have VS Code installed (if you don’t then go and install it from here), type:

code testreactapp

And as if by magic, VS Code appears!

You should be able to run this straight out of the box. Start a new terminal in VS Code, and type npm start:

The displayed screen is of a little animated spiragraph. Let’s add a button and, where the user presses the button, hide or show the spinning spiragraph.

State

As I have previously written about here state is one of the key concepts in React. Let’s create a state object that will determine the visibility of our animation.

In order to introduce state, we need to change the default app.js to be a class, as functions cannot have state. Note that, were this a real application, you would probably move this out into a separate component; but let’s change our app.js to be a class:

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';

export default class App extends Component {
	render() {
		return (
			<div className="App">
				<header className="App-header">
					<img src={logo} className="App-logo" alt="logo" />
					<p>
						Edit <code>src/App.js</code> and save to reload.
					</p>
					<a
					className="App-link"
					href="https://reactjs.org"
					target="_blank"
					rel="noopener noreferrer"
					>
						Learn React
					</a>
				</header>
			</div>
		);
	}
}

All I’ve done here is change the function to a class, and added `import {Component}`.

Now let’s add some state. At the top of the class, add a constructor:

constructor(props) {
	super(props)
	this.state = {
		showSpiragraph: true
	}
}

Let’s now add the button, so we can change the value of the state; first, we’ll need the button itself:

. . .
	<a
		className="App-link"
		href="https://reactjs.org"
		target="_blank"
		rel="noopener noreferrer"
	>
		Learn React
	</a>
	<button onClick={this.toggleShow}>Hide/Show</button>
</header>
. . .

Then the function that we’re calling (toggleShow):

toggleShow = () => {
  this.setState(state => ({showSpiragraph: !state.showSpiragraph}));
}

If you run this now, it will allow you to press the button until your finger aches, but it won’t actually do anything.

Conditionally Displaying an Element

Okay, so we come to the crux of the entire post; we can conditionally render our image by using the following syntax:

. . .
<header className="App-header">
  {this.state.showSpiragraph &&
    <img src={logo} className="App-logo" alt="logo" />
  }
. . .

You should now be able to click the button and have the Spiragraph show and hide at will.

References

https://medium.freecodecamp.org/quick-guide-to-understanding-and-creating-reactjs-apps-8457ee8f7123

https://reactjs.org/docs/handling-events.html

A C# Developer’s Guide to: ReactJS – Part 1 – Create & Run

I thought it might be time for another of my patented “C# Developer’s Guide to…”. Basically, a guide to React for someone that understands programming (C# ideally), but doesn’t know anything about ReactJs.

There are a couple of VS templates for React; however, after working with it for a while, you realise that most of the React people live in the command line; there’s a tool called create-react-app:

You can use Powershell or Bash as your command line of choice. Start by installing the tool:

npm i -g create-react-app

This assumes that you have installed npm.

Create

To create a new application, navigate to the directory that you wish to create the application in and type:

create-react-app [app-name]

For example:

create-react-app context-menu-test

Once created, it tells you how you can start the app:

Run

First navigate into the directory that it’s just created (otherwise you’ll get errors when you run).

npm start

Will launch the server, and navigate to the Url with the default browser:

cd context-menu-test
npm start

This runs on port 3000 by default, so if you run a couple of instances then you might get the error:

Something is already running on Port 3000

To fix this, in VS Code, open the folder:

node_modules/react-scripts/scripts/start.js

Find the following line (at the time of writing):

const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;

You can change the port 3000 to something that’s free.

Edit App.js:

class App extends Component {
  render() {
    return (
      <div className="App">
        <div>
          <p>Test</p>
        </div>
      </div>
    );
  }
}

Save and see the updated screen appear (which I think you’ll agree is much better than the default screen).

A C# Programmer’s Guide to Installing, Running and Messaging with RabbitMQ

Following this year’s trip to DDD North I got speaking to someone about Rabbit MQ. I’d previously done some research on Active MQ, however, given that there are, realistically, only two options in this market, I thought I should have a look at the competition.

Install from here.

You also need to install Erlang.

After the install… nothing happens. No matter how long you wait, assuming it’s just your slow laptop (don’t want to talk about that anymore). Navigate to:

rabbitmq1

C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.0\sbin

In a DOS prompt, type:

rabbitmq-plugins enable rabbitmq_management

rabbitmq2

Rabbit will now run as a service, which also feels much cleaner that ActiveMQs console app style interface.

Now, log-in to http://localhost:15672/, and log-in as guest/guest:

rabbitmq3

Code

Just like with ActiveMQ, there is a NuGet package that you can use for interacting with the exchange:

https://www.nuget.org/packages/RabbitMQ.Client. Your project needs .Net 4.5.1 or higher; otherwise, you’ll see this:

rabbitmq4

If it’s not, upgrade your project to 4.5.1:

rabbitmq5

Okay, so now we’re up and running, here’s the code for the send:

static void Main(string[] args)
{            
    while (true)
    {
        string msg = Console.ReadLine();
        if (string.IsNullOrWhiteSpace(msg))
        {
            break;
        }
 
        SendNewMessage(msg);
    } 
    
}
private static void SendNewMessage(string message)
{
    var factory = new ConnectionFactory() { HostName = "localhost" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
        var result = channel.QueueDeclare("NewQueue", true, false, false, null);
        Console.WriteLine(result);
 
        channel.BasicPublish("", "NewQueue", null, Encoding.UTF8.GetBytes(message));                
 
    }
}

Just like with ActiveMQ, you can now just look at the queue:

rabbitmq6

A quick caveat here:

var result = channel.QueueDeclare("NewQueue");

Doesn’t work because exclusive defaults to ‘true’, meaning that only your session can see it.

Receiving a Message

static void Main(string[] args)
{
    while (true)
    {
        ReceiveNextMessage();
 
        string exit = Console.ReadLine();
        if (!string.IsNullOrWhiteSpace(exit)) break;
    }
 
}
 
private static void ReceiveNextMessage()
{
    var factory = new ConnectionFactory() { HostName = "localhost" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
        var result = channel.QueueDeclare("NewQueue", true, false, false, null);
        Console.WriteLine(result);
 
        EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
        consumer.Received += Consumer_Received;
 
        channel.BasicConsume("NewQueue", true, consumer);
 
        System.Threading.Thread.Sleep(1000);
 
    }
}
 
private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
{
    var body = e.Body;
    var message = Encoding.UTF8.GetString(body);
    Console.WriteLine(message);
}

rabbitmq7

Why the Thread.Sleep? The reason is that, because the message consumer is event based, you need to stop tidying up the objects until you’re done. Obviously, sleeping for 1 second has its issues. I suspect this could be better achieved using a TaskCompletionSource, of even just a Console.ReadLine(), but for the purposes of this post, it suffices.

Topics

The concept of topics seems to be the same as ActiveMQ; however, the implementation is different, and there were a few dead-ends to go down first.

The following code, for example:

var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
    channel.ExchangeDeclare("NewTopic", "testTopic");
    
    channel.BasicPublish("NewTopic", "test", null, Encoding.UTF8.GetBytes(message));
 
}

Gives the error: COMMAND_INVALID – unknown exchange type ‘testTopic’

rabbitmq8

RabbitMQ seems to have some magic strings that determine the message type. This works:

 
private static void SendNewTopic(string message)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
    channel.ExchangeDeclare("NewTopic", "topic"); // topic is a magic string
    
    channel.BasicPublish("NewTopic", "test", null, Encoding.UTF8.GetBytes(message));
 
}

The “test” is a routing code. These seem to be quite an involved system; however, it basically tells the exchange where the message is going.

rabbitmq9

Receive

private static void ReceiveNextTopic()
{
    var factory = new ConnectionFactory() { HostName = "localhost" };
    using (var connection = factory.CreateConnection())
    using (var channel = connection.CreateModel())
    {
        channel.ExchangeDeclare("NewTopic", "topic");
        var queueName = channel.QueueDeclare().QueueName;
 
        channel.QueueBind(queue: queueName,
                        exchange: "NewTopic",
                        routingKey: "test");
 
        EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
        consumer.Received += Consumer_Received;
 
        channel.BasicConsume(queueName, true, consumer);
 
        Console.ReadLine();
    }
}

private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
{
    var body = e.Body;
    var message = Encoding.UTF8.GetString(body);
    Console.WriteLine(message);
}

Notice the routing key; this (broadly speaking) needs to match the sender’s routing key. The purpose seems to be to allow a complex mapping between publisher and subscriber.

Conclusion

In comparison to ActiveMQ, RabbitMQ seems to be a more actively maintained code base; a quick comparison of the GitHub repo of each reveals more activity in Rabbit. Rabbit also seems a little cleaner in the way it’s run and installed; however, it also seems to have more moving parts.

There are a number of companies that offer support for ActiveMQ commercially; however, the company that wrote RabbitMQ offer commercial support, should you need it.

Can you run Active and RabbitMQ together?

No. No, you can’t. They both seem to want to use the same resources, and so if you want to use them both on the same machine, you can, but only one at a time.

Acknowledgements

I used the following websites extensively in this article:

http://arcware.net/installing-rabbitmq-on-windows/

https://www.rabbitmq.com/tutorials/tutorial-one-dotnet.html