Sorted By: Tag (javascript)

React with Redux: A Stable, Powerful and Scalable Combination - Part 1

React and Redux has been my go-to UI tools for a while now and I wanted share the fundemental benefits of adopting this type of architecture on your web applications. This is the first part of the blog post series I will publish on this.
2016-10-22 14:25
Tugberk Ugurlu


For the last a few months, I have been using React and Redux. I successfully converted a small application from Aurelia to React + Redux combination. Actually, it's a lie that that application is small. I told you it's small because it was less than halfway done at the time I started converting. That Web application is meant to be complex and has complicated data needs. Besides that application, we started building a completely new web application on top of React and Redux: SQL Clone Web Client. We haven’t shıpped ıt yet but we are approaching there.

This is an interesting move from someone like me who hated and thought React was bad.

However, I must admit that it was a premature thinking. I had my reasons but those reasons blocked me to look further to see the actual benefıt and power of React. In this post, I am going to hopefully answers the "why" question behind React and I will take it further to mix it with Redux.

I also suggest you to have a look at the short video of Cory House answering the "Why React" question.

React

If you don't know already, React is a library from Facebook to help you create user interfaces. It's important to make the distinction here that React is not a framework like Angular or Aurelia. You can see React as the V in MVC. However, this doesn't mean that you cannot create full-blown applications with React. There are a few other tiny libraries which you can plug into React like react-router, react-redux and they close the React's gap to build scalable Web applications.

React takes a declarative and component based approach on creating user interfaces. For example, the below is the well-known "Hello World" example of React:

var HelloMessage = React.createClass({
  render: function() {
      return <div>Hello {this.props.name}</div>;
  }
});

ReactDOM.render(<HelloMessage name="John" />, mountNode);

mountNode is just an element here which you can get a hold of through document.getElementById or similar APIs to that.

This will print "Hello John" inside the mountNode. At this point, it's OK to be puzzled with all the buzz about React because this is not something which blows your mind and if you are seeing this for the first, it's also OK to go "WTAF" here because you have something HTML{ish} inside your JavaScript code. This is neither HTML nor part of Javascript. That is JSX and it needs transpiling. As stated, you go "WTF" over this (well, at least I did) because it might go against the "separation of concerns" thinking you have been holding onto. I have been there and done this. I stopped looking at React at that point and convinced myself that it's not something that would scale in terms of maintenance.

Do you have the same reaction? If so, let me tell something which I wish someone would told me when I had this reaction and I think deserves to be emphasized over and over again. The above "Hello World" example is not the place where you should start learning React. It should be "Thinking in React" documentation that you should start with. It's such a good documentation explaining what the mindset you should be in while you are working with React. However, you might be dealing with another challenge in our mind now while this direction can put you into a different situation:

This kind of has a point. I believe the amount of boilerplate code which you write with React to get your application running is higher than any of its opponents. However, small applications is probably not going to highlight the value of React that well. You see the value it brings when you think in terms of the whole application. Let me tell you a few things about this.

To me, most valuable thing about an evolvable application (doesn't have to be a web application, any sort of it) is to be able to reason about its behaviour at any point during its evolution. Whenever, you see some unexpected behaviour, you should able to say "this is happening because this part in my application is doing something wrong". This is also valid for expected behaviours as well as you will be contributing to its evaluation by adding new features to it and you should know exactly where you need to apply the changes to add those features.

The other point I want to make here is based on amazing Brian Holt's talk at Dev Day: "React: Learn Once Write Anywhere". If my memory is not failing me, he stated a very important fact about a React application: its constant complexity level. I accept that a typical React application starts complex but that complexity mostly stays the same during the entire evolution of the web application unless you go outside the boundaries of the structure. However, if you go with a simple approach at the begging, your complexity will grow as you grow your web application codebase. I have witnessed this several times and I will tell you that it’s not fun to apply changes after a certain point.

If you are struggling with the React getting started process, there is an approach which I see very efficient that will ease your process. You can start working without thinking about the separation of your application into smaller components. With this way, you can write your components as big, fat components. Once you have two or three like that, you will start seeing patterns which will make you think about isolations. That's where you can start drawing mockups like this one. I went this way at the start where I was really fuzzy about React but now, it's a set mindset for me that I start with a mockup.

Final point I want to touch on is about stability and problem solving, I think one of the biggest values of React is its stability and adoption. I can assure you that the most of your Web UI problems have an answer in React and it is also highly likely that someone has already written up a blog post, put a sample somewhere or answered a Stackoverflow question on that. Also, Facebook and some other big companies rely on React. So, the evolution of React is a fairly safe progress in this fast evolving JavaScript ecosystem.

Conclusion

In this post, I just wanted cover the React part of the story and I should admit that it's not much. However, my aim here is to convince you to give React a chance. I can understand that you may have questions about how to handle the data at this stage (e.g. how to react to the changes that happens behind the background, etc.). This is probably a good time for you to look at what Flux application architecture is all about and have a go with one of the state management libraries like Redux. This is the exact topic that I will touch on the second part of this blog post series, which will also highlight the practical strength of React along with Redux.

Further Resources

First Hours with Visual Studio Code on Mac and Windows

Today is one of those awesome days if you build stuff on .NET platform. They announced bunch of stuff during Build 2015 keynote and one of them is Visual Studio Code, a free and stripped down version of Visual Studio which works on Mac OS X, Linux and Windows. Let me give you my highlights in this short blog post :)
2015-04-29 21:15
Tugberk Ugurlu


Today is one of those awesome days if you are building stuff on .NET platform. Microsoft announced bunch of stuff at Build 2015 keynote a few hours ago and one of them is Visual Studio Code, a free and stripped down version of Visual Studio which works on Mac OS X, Linux and Windows. It leverages bunch of existing open source software like OmniSharp, Electron. Most of all, this was my #bldwin wish :)

First of all, you should definitely install Visual Studio Code and start checking the documentation which is very extensive. I followed those steps and as I am very excited about this new tool, I wanted to share my experience thus far which is not much but very promising.

First thing I noticed was the top notch support for ASP.NET 5. The documentation for ASP.NET 5 support is pretty good but some features are not highlighted there. For example, you are getting the IntelliSense for dependencies:

Ekran Resmi 2015-04-29 19.26.46

When you add a dependency, you get nice notification telling that you should restore:

Ekran Resmi 2015-04-29 19.59.55

Pretty nice! So, how would you restore? Hit ⇧⌘P to get the command pallet up and you can see the restore command there:

Ekran Resmi 2015-04-29 21.45.20

It will run the restore inside the terminal:

Ekran Resmi 2015-04-29 21.48.30

You can also invoke your commands defined inside the project.json:

Ekran Resmi 2015-04-29 20.09.09

Ekran Resmi 2015-04-29 20.10.14

Obviously, you can change the theme.

Ekran Resmi 2015-04-29 20.18.35

Writing C# code is also very slick! You currently don’t have all the nice refactoring features you have in full fledged Visual Studio but it’s still impressive:

Ekran Resmi 2015-04-29 20.19.57

Ekran Resmi 2015-04-29 20.22.43

We even have some advanced stuff like Peek Definition:

Ekran Resmi 2015-04-29 20.02.29

Check out the documentation for all coding editor features.

As mentioned Windows is also fully supported as you might guess :)

Screenshot 2015-04-29 20.35.16

Screenshot 2015-04-29 21.18.29

Screenshot 2015-04-29 21.23.36

I want to touch on the Git integration as well. I generally use Git bash and this won’t change for me but having the diff view inside the editor in a very nice way is priceless!

image

How about old/current .NET applications? I managed to get one up and running easily and managed to get the build working by defining a task for that:

{
	"version": "0.1.0",
	
	// The command is tsc.
	"command": "msbuild",

	// Show the output window only if unrecognized errors occur. 
	"showOutput": "silent",
	
	// Under windows use tsc.exe. This ensures we don't need a shell.
	"windows": {
		"command": "C:\\Program Files (x86)\\MSBuild\\14.0\\Bin\\msbuild.exe"
	},
	
	// args is the HelloWorld program to compile.
	"args": []
}

image

I was expecting this to work without any further configurations but it could be just me not being able to get it working.

As said, it’s very early but I am sold for this editor! Also, this is a fantastic time to build products on .NET platform. I would like to thank all the people at Microsoft and open source community who are making our lives easier and enjoyable. I will leave you all now and enjoy my new toy! :O

Bootswatch and Gulp as a Stepping Stone for Your Theme Switch Feature

This short blog posts shows you a way of combining bootswatch and gulp together to have an easily useable theme switching support for your web application.
2014-10-15 17:06
Tugberk Ugurlu


Bootswatch has awesome themes which are built on top of Bootstrap. To integrate those themes to your web application, you have a few options. One of them is to build the css file by combining bootstrap.less file with the less files provided by bootswatch. This is the way I chose to go with. However, what I actually wanted was a little bit more complex:

  • Install bootswatch with bower and have every theme available for me to use.
  • Compile each bootswtch theme to CSS.
  • Concatenate and minify each generated bootstrap file with my other CSS files and have separate single CSS file available for me for each theme.

With this way, switching between themes would be just as easy as changing the filename suffix. I achieved this with gulp and you can find the sample in my GitHub account: gulp-bootswatch-sample. To get the sample up and running, run the following commands in order:

// install bower globally if you don't have it already
npm install bower -g

// install gulp globally if you don't have it already
npm install gulp -g

// navigate to my sample projects root folder and run the following commands
npm install
bower install

// finally run gulp the tasks
gulp

Here is how my gulpfile.js file looks like:

var gulp = require('gulp'),
    minifycss = require('gulp-minify-css'),
    concat = require('gulp-concat'),
    less = require('gulp-less'),
    gulpif = require('gulp-if'),
    order = require('gulp-order'),
    gutil = require('gulp-util'),
    rename = require('gulp-rename'),
    foreach = require('gulp-foreach'),
    debug = require('gulp-debug'),
    path =require('path'),
    merge = require('merge-stream'),
    del = require('del');

gulp.task('default', ['clean'], function() {
    gulp.start('fonts', 'styles');
});

gulp.task('clean', function(cb) {
    del(['assets/css', 'assets/js', 'assets/less', 'assets/img', 'assets/fonts'], cb)
});

gulp.task('fonts', function() {
    
    var fileList = [
        'bower_components/bootstrap/dist/fonts/*', 
        'bower_components/fontawesome/fonts/*'
    ];
    
    return gulp.src(fileList)
        .pipe(gulp.dest('assets/fonts'));
});

gulp.task('styles', function() {
    
    var baseContent = '@import "bower_components/bootstrap/less/bootstrap.less";@import "bower_components/bootswatch/$theme$/variables.less";@import "bower_components/bootswatch/$theme$/bootswatch.less";@import "bower_components/bootstrap/less/utilities.less";';

    var isBootswatchFile = function(file) {
        var suffix = 'bootswatch.less';
        return file.path.indexOf(suffix, file.path.length - suffix.length) !== -1;
    }
    
    var isBootstrapFile = function(file) {
        var suffix = 'bootstrap-',
            fileName = path.basename(file.path);
        
        return fileName.indexOf(suffix) == 0;
    }
    
    var fileList = [
        'client/less/main.less', 
        'bower_components/bootswatch/**/bootswatch.less', 
        'bower_components/fontawesome/css/font-awesome.css'
    ];
    
    return gulp.src(fileList)
        .pipe(gulpif(isBootswatchFile, foreach(function(stream, file) {
            var themeName = path.basename(path.dirname(file.path)),
                content = replaceAll(baseContent, '$theme$', themeName),
                file = string_src('bootstrap-' +  themeName + '.less', content);

            return file;
        })))
        .pipe(less())
        .pipe(gulp.dest('assets/css'))
        .pipe(gulpif(isBootstrapFile, foreach(function(stream, file) {
            var fileName = path.basename(file.path),
                themeName = fileName.substring(fileName.indexOf('-') + 1, fileName.indexOf('.'));
            
            return merge(stream, gulp.src(['assets/css/font-awesome.css', 'assets/css/main.css']))
                .pipe(concat('style-' + themeName + ".css"))
                .pipe(gulp.dest('assets/css'))
                .pipe(rename({suffix: '.min'}))
                .pipe(minifycss())
                .pipe(gulp.dest('assets/css'));
        })))
});

function escapeRegExp(string) {
    return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

function replaceAll(string, find, replace) {
  return string.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

function string_src(filename, string) {
  var src = require('stream').Readable({ objectMode: true })
  src._read = function () {
    this.push(new gutil.File({ cwd: "", base: "", path: filename, contents: new Buffer(string) }))
    this.push(null)
  }
  return src
}

End result :)

image

I wished I had something like this when I started doing this so I hope this was helpful to you somehow. Enjoy!

Order of Fields Matters on MongoDB Indexes

Order of Fields Matters on MongoDB Indexes. Let's see how with an example.
2014-04-12 18:52
Tugberk Ugurlu


As my MongoDB journey continues, I discover new stuff along the way and one of them is about indexes in MongoDB. Let me try to explain it with a sample.

First, create the below four documents inside our users collection:

db.users.save({ 
	_id: 1, 
	name: "tugberk1", 
	login: [
		{ProviderName: "twitter", ProviderKey: "232"}, 
		{ProviderName: "facebook", ProviderKey: "423"}
	]
});
	
db.users.save({ 
	_id: 2, 
	name: "tugberk23", 
	login: [
		{ProviderName: "twitter", ProviderKey: "3443"}
	]
});

db.users.save({ 
	_id: 3, 
	name: "tugberk4343", 
	login: [
		{ProviderName: "dropbox", ProviderKey: "445345"}
	]
});

db.users.save({ 
	_id: 4, 
	name: "tugberk98", 
	login: [
		{ProviderName: "dropbox", ProviderKey: "3443"}, 
		{ProviderName: "facebook", ProviderKey: "768"}
	]
});

Let’s query the users collection by login.ProviderKey and login.ProviderName:

db.users.find({
	"login.ProviderKey": "232", 
	"login.ProviderName": "twitter"
}).pretty();

image

It found the document we wanted. Let’s see how it performed:

db.users.find({
	"login.ProviderKey": "232", 
	"login.ProviderName": "twitter"
}).explain();

image

Result is actually pretty bad. It scanned all four documents to find the one that we wanted to get. Let’s put an index to ProviderName and ProviderKey fields:

db.users.ensureIndex({
	"login.ProviderName": 1, 
	"login.ProviderKey": 1
});

Now, let’s see how it performs the query:

image

It’s better as it scanned only two documents. However, we had only one matching document for our query. As the chances that the providerKey will be more unique than the ProviderName, I want it to first look for the ProviderKey. To do that, I need to change the index:

db.users.dropIndex({
	"login.ProviderName": 1, 
	"login.ProviderKey": 1 
});
db.users.ensureIndex({ 
	"login.ProviderKey": 1, 
	"login.ProviderName": 1 
});

Let’s now see how it’s trying to find the matching documents:

db.users.find({
	"login.ProviderKey": "232", 
	"login.ProviderName": "twitter"
}).explain();

image

Boom! Only one document was scanned. This shows us how it’s important to put the fields in right order for our queries.

Resources

A C# Developer's First Thoughts on MongoDB

After working with RavenDB over the year, I just started looking into MongoDB. I worked with MongoDB a year ago or so in a small project but my knowledge was mostly rusty and I don't want that to happen again :) So, here I'm, documenting what my second thoughts are :)
2014-04-12 14:22
Tugberk Ugurlu


After working with RavenDB over the year, I just started looking into MongoDB. I worked with MongoDB a year ago or so in a small project but my knowledge was mostly rusty and I don't want that to happen again :) So, here I'm, documenting what my second thoughts are :) The TL;DR is that: I'm loving it but the lack of transaction sometimes drifts on a vast dark sea. It's OK through. The advantages generally overcomes this disadvantage.

Loved the Mongo Shell

First thing I liked about MongoDB is its shell (Mongo Shell). 

3d6f5fdd4be53096b6992d5b84b0d7be

It makes it insanely easy for you to get used to MongoDB. After running the mongod.exe, I fired up a command prompt and navigated to mongo.exe directory and entered the mongo shell. Mongo Shell runs pure JavaScript code. That's right! Anything you know about JavaScript is completely valid inside the mongo shell. Let's see a few things that you can do with mongo shell.

You can list the databases on your server: show dbs

2

You can see which database you are connected to: db

3

You can switch to a different database: use <database name here>

4

You can see the collections inside the database you are on: show collections

5

You can save a document inside a collection: db.users.save({ _id: "tugberk", userName: "Tugberk" })

6

You can list the documents inside a collection: db.users.find().pretty()

7

You can run a for loop:

for(var i = 0; i < 10; i++) { 
	db.users.save({ 
		_id: "tugberk" + i.toString(), 
		userName: "Tugberk" + i.toString() 
	}) 
}

8

You can run the code inside a js file

9

saveCount.js contains the following code and it just gets the count of documents inside the users collection and logs it inside another collection:

(function() {
     var myDb = db.getSiblingDB('myDatabase'),
         usersCount = myDb.users.find().count();
         
     myDb.countLogs.save({
          count: usersCount,
          createdOn: new Date()
     });
}());

All of those and more can be done using the mongo shell. It's a full blown MongoDB client and probably the best one. I don't know if it's just me but big missing feature of RavenDB is this type of shell.

Loved the Updates

Update operations in MongoDB is just fabulous. You can construct many kinds of updates, the engine allows you to do this fairly easily. The one I found most useful is the increment updates. Increment updates allows you to increment a field and this operation will be performed concurrency in-mind:

db.books.update(
   { item: "Divine Comedy" },
   {
      $inc: { stock: 5 }
   }
)

The above query will update the stock filed by 5 safely.

Not much Love for the .NET Client

MongoDB has an official .NET client but MongoDB guys decided to call this "C# driver". This is so strange because it works with any other .NET languages as well. I have to say that MongoDB .NET client is not so great in my opinion. After coming from the RavenDB .NET client, using the MongoDB .NET client just feels uncomfortable (However, I’m most certainly sure that I’d love its Node.Js client as it would feel very natural).

First of all, it doesn't support asynchronous requests to MongoDB server. All TCP requests are being done synchronously. Also, there is no embedded server support. RavenDB has this and it makes testing a joy. Let's look at the below code which gets an instance of a database:

MongoClient client = new MongoClient("mongodb://localhost");
MongoServer server = client.GetServer();
MongoDatabase db = server.GetDatabase("mongodemo");

There is too much noise going on here. For example, what is GetServer method there? Instead, I would want to see something like below:

MongoClient client = new MongoClient("mongodb://localhost");
using(var session = client.OpenSession("myDatabase"))
{
     // work with the session here...
}

Looks familiar :) I bet it does! Other than the above issues, creating map/reduce jobs just feels weird as well because MongoDB supports JavaScript to perform map/reduce operations.

var map =
    "function() {" +
    "    for (var key in this) {" +
    "        emit(key, { count : 1 });" +
    "    }" +
    "}";

var reduce =
    "function(key, emits) {" +
    "    total = 0;" +
    "    for (var i in emits) {" +
    "        total += emits[i].count;" +
    "    }" +
    "    return { count : total };" +
    "}";

var mr = collection.MapReduce(map, reduce);
foreach (var document in mr.GetResults()) {
    Console.WriteLine(document.ToJson());
}

The above code is directly taken from the MongoDB documentation.

Explore Yourself

MongoDB has a nice documentation and you can explore it yourself. Besides that, Pluralsight has a pretty nice course on MongoDB: Introduction to MongoDB by Nuri Halperin. Also, don't miss the Ben's post on the comparison of Map-Reduce in MongoDB and RavenDB.

Tags