Categories: Web Dev Training

Reactive Programming with JavaScript, Ruby and Python – Part 1

Reactive programming is a concept that is finally gaining some popularity among programmers. It makes it easier to think in data flows and to manage and work with them. Instead of imperative programming, you’re thinking about code as a series of processes that take place on streams.

This is similar to the conceptual shift to map/reduce thinking. But it takes those ideas further. You’re doing a map/reduce and then connecting the data to other filters and maps and creating multiple pipelines so that the right data gets to the right place.

For example, when a user clicks a button in a web app (or desktop app), that click event can be propagated through the system to all the subscribers that are listening and waiting for that event.

When working with the Angular frontend web framework, that latest versions are now using RxJS, the reactive programming library for JavaScript. It is the underlying framework for working with events. Previously in AngularJS 1.x you would use the broadcast and emit system to act on events. With Reactive, you have a generalized library for working with observables and subscribers which can work well with other libraries and other JavaScript code.

In Ruby and Python, other concepts have held sway for a long time, so here are some examples on how to do reactive programming Ruby and how to do reactive programming in Python.

These are basic examples of filtering and creating observables, think of them as the equivalent of “Hello World”, in part 2 we will explore more advanced usages.

You can find a list of other languages that are supported with a reactive library on the ReactiveX website.

Reactive Programming: JavaScript Example

Let’s begin by creating an observable:

var numbers = [1,2,3,4,5];
var all = Rx.Observable.from(numbers);

This observable is being created from a list of numbers. It’s possible to convert other types of lists into Observables.

Next we want to print out all of the numbers. We do this by subscribing to the observable with a function:

all.subscribe(function(number) {
 console.log("The number is " + number);
});

Right now this looks like a for loop, but remember that observables are meant for events in time. There could be milliseconds or seconds or minutes between each event that the observable is emitting to the subscriber.

Next, let’s create a new flow of data by filtering all of the numbers so we only receive even numbers in our subscriber:

var only_evens = all.filter(function(number) {
  return number % 2 === 0;
});

Again we print out the numbers and you will notice that we only print out even numbers:

only_evens.subscribe(function(number) {
   console.log("This number is even: " + number);
});

That was a simple example of creating two flows; one with all values, and a filtered flow of values.

Now imagine in your next web app, a user does any action. That action is sent through an observable and we can have a subscriber that waits for a specific button click action or subscribes to any button click.

Then imagine a 3rd party API or REST API whose response you’re waiting on, you are subscribing to the observable and filtering for certain responses straight for display in your user interface.

There is a lot of power in reactive programming and it makes diagramming the process of UI event flow much easier. Each new user interaction or display is just another flow of events to be filtered and subscribed to.

Reactive Programming: Ruby Example

Now let’s do the same thing but this time in Ruby with RxRuby.

First we create the observable and print out all the numbers:

require 'rx_ruby'
numbers = [1, 2, 3, 4, 5]
all = RxRuby::Observable.from_array numbers
all.subscribe do |number|
  puts "The number is #{number}"
end

Then we filter the observable and print out the filtered values:

only_evens = all.select(&:even?)
only_evens.subscribe do |number|
  puts "This number is even: #{number}"
end

One interesting note when creating your observable, you should use from_array because simply using from will only emit the flow of values once. I’m not sure why RxRuby has this particular behaviour.

Reactive Programming: Python Example

And now let’s do it all over again but with Python and RxPy.

We create the observable with all values and print them out:

import rx
numbers = [1, 2, 3, 4, 5]
all = rx.Observable.from_(numbers)
all.subscribe(lambda number: print('The number is {}'.format(number)))

And again we filter the observable’s values to a subset and print those out as well:

only_evens = all.filter(lambda number: number % 2 == 0)
only_evens.subscribe(lambda number: print('This number is even: {}'.format(number)))

Please note that in the JavaScript example we used the operator “filter” and in the Python example. But in the Ruby example we used “select”. If you try and use “select” in the Python example you will get a list of boolean values instead of properly filtering the list. There are a few differences like this between each library.

Conclusion

This was a short introduction into reactive programming. There’s a lot more you can do and here I wanted to demonstrate that it’s possible to use Rx with more than just JavaScript. I’ve only seen it used in Java and JavaScript and thought it was time to write more examples of Ruby and Python so others can see that those languages can also benefit from Rx and Reactive programming.

Categories: Web Dev Training

One Easy Way To Speed up your Rails Tests and RSpec

There comes a time in the life of every Ruby on Rails project where you and your team will end up with long running tests. Rails tests can contain factories, fixtures and lots of setup procedures before tests are executed, and all of these can contribute to major slowness in the test runs.

I’ve seen four ways of dealing with slow running tests in Rails:

  1. start deleting tests (or mark them as skip-able): the drawback is your test coverage drops and you may end up with more bugs
  2. use more integration tests rather than unit tests: this exercises a lot of code paths so test coverage won’t drop too much but in the end most developers will write integration tests that exercise the “happy path”
  3. Run your tests in parallel
  4. Run only the tests that were most likely to be affected by recent code changes

The latter two methods are much better than the first two.

My favourite so far is #3 because it still runs all of the integration and unit tests that you have but makes use of the fact that you can offload the work of running tests to multiple machines. Everyone now has access to multiple machines through AWS (Amazon Web Services) or Microsoft Azure or RedHat’s cloud. You can even run tests in parallel on your local development machine.

Run Your Ruby on Rails Tests In Parallel

The idea is that each test file will be run in separate processes.

If you have 5 tests that have a duration 2 minutes, in sequential runs it will take 10 minutes to run the whole test suite. If you have 5 processes available for parallel runs, it will only take 2 minutes to run the whole test suite.

That’s a huge difference and means you can make 30 test runs in an hour rather than 6 test runs.

Splitting RSpec test files into multiple files

However, some of your Rails tests may take longer; within the spec you could have multiple test cases and contexts that are taking too long. For example, one test context with a few tests could be taking 1 minute while the rest of the test cases in that file only take 10 seconds. At that point, you can split the long-running test context into multiple files.

Here’s an example of how that might look like:

# spec/my_controller_spec.rb
describe MyController do
  context 'Slow tests' do
    it 'runs slowly #1' do
      # ...
    end
    it 'runs slowly #2' do
      # ...
    end
  end

  context 'Faster part of the test suite' do
    it 'runs in 10 seconds or less' do
      # ...
    end
  end
end

And now here’s how we could split that controller rspec test file into multiple files.

# spec/my_controller_spec.rb
describe MyController do
  context 'Faster part of the test suite' do
    it 'runs in 10 seconds or less' do
      # ...
    end
  end
end

# spec/my_controller_slow_1_spec.rb
describe :MyControllerSlow1 do
  def self.described_class
    MyController
  end

  include_context 'my controller helpers'

  it 'runs slowly #1' do
    # ...
  end
end

# spec/my_controller_slow_2_spec.rb
describe :MyControllerSlow2 do
  def self.described_class
    MyController
  end

  include_context 'my controller helpers'

  it 'runs slowly #2' do
    # ...
  end
end

The reason this works is because we override the class method described_class. This method is used by the rspec-rails extensions that make it easier to test Rails classes with RSpec.

By using shared contexts and helpers and by splitting files, you can optimize your Rails tests even further.

(If you liked this article, I have written about using mocks with Django and Python unit and integration tests and using Protractor with AngularJS and how you can take screenshots with Selenium during test runs.)

Categories: Web Dev Training

3 Great Videos about GraphQL

Since GraphQL is a hot topic and a new way of creating APIs for client devices and applications, it helps to learn what it is, how it’s used and why it’s becoming quickly adopted for new projects. So here are 3 great videos on YouTube that explain why your team should explore GraphQL and consider it as a viable technology for your next project.

Lessons From 4 Years Of GraphQL

A reflection on GraphQL’s successes and its evolution within Facebook, the company at which it originated.

Connect Your Angular App To Any GraphQL Backend

At Facebook they use React (it was created there too!) but a lot of companies use AngularJS and now are adopting Angular 2/4/5+. This video shows you how to use it with an Angular app. Angular offers a more complete framework in contrast to React; so if you’re already using it, it’s definitely possible to use it with APIs such as GitHub.

Implementing & Using GraphQL at GitHub

GitHub started to use it for their API in 2016 and revealed it at their yearly event GitHub Universe. They show how they implemented part of the API and then show the client-facing portion through the query explorer. The query explorer is a powerful way to construct and test different API queries.

Home » Blog » Web Dev Training
Categories: Portfolio, Web Dev Training

GraphQL with Node.js and Mongoose/MongoDB

In March 2016, as part of an exploratory project, I worked on an example implementation of GraphQL using MongoDB and Node.js: graphql-server. While at the time, the company decided not to go with GraphQL, it was only a year later that they revisited the idea and started to make it part of their core technology strategy (they had multiple mobile apps and 3rd party clients that needed a more performant interface than the REST API, which had some performance issues).

Example of a GraphQL Schema

Here’s an example of how to define a schema. The advantage for clients/consumers is that they can select only the fields they need from the API.

import {
  GraphQLObjectType,
  GraphQLNonNull,
  GraphQLSchema,
  GraphQLString,
  GraphQLInt,
  GraphQLList,
  GraphQLID,
  GraphQLBoolean
} from 'graphql/type';
import co from 'co';
import mongoose from 'mongoose';

import models from './models';

var makeGQLString = function(desc) {
  return {
    type: GraphQLString,
    description: desc
  };
};

var makeNonNullGQLString = function(desc) {
  return {
    type: new GraphQLNonNull(GraphQLString),
    description: desc
  };
};

var makeGQLBoolean = function(desc) {
  return {
    type: GraphQLBoolean,
    description: desc
  };
};

var makeGQLInt = function(desc) {
  return {
    type: GraphQLInt,
    description: desc
  };
};

var listingType = new GraphQLObjectType({
  name: 'Listing',
  description: 'An event listing',
  fields: function() {
    return {
      id: makeNonNullGQLString('The id of the listing.'),
      slug: makeNonNullGQLString('slug'),
      title: makeGQLString('The title of the listing.'),
      description: makeGQLString('description'),
      description_html: makeGQLString('description_html'),
      category_id: GraphQLID,
      category_key: makeGQLString('category_key'),
      hashtag: makeGQLString('hashtag'),
      location: makeGQLString('location'),
      website: makeGQLString('website'),
      show_count: makeGQLInt('show count'),
      show_avatars_of_bookers: makeGQLBoolean('show_avatars_of_bookers'),
      show_tickets_sold_count: makeGQLBoolean('show_tickets_sold_count'),
      hide_date: makeGQLBoolean('hide_date'),
      capacity: makeGQLString('Capacity of the listing'),
      state: makeNonNullGQLString('State of the listing')
    };
  }
});

var eventType = new GraphQLObjectType({
  name: 'Event',
  description: 'An event',
  fields: function() {
    return {
      id: makeNonNullGQLString('Event id'),
      start_stamp: makeNonNullGQLString('Start of the event, timestamp'),
      end_stamp: makeNonNullGQLString('End of the event, timestamp'),
      city_name: makeGQLString('Event that the city is in')
    };
  }
});

var rootQueryType =  new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    listings: {
      type: new GraphQLList(listingType),
      resolve: function(parent, args, ast) {
        return models.Listing.find().limit(10);
      }
    },
    listing: {
      type: listingType,
      args: {
        id: {
          name: 'id',
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: function(parent, args, ast) {
        return models.Listing.findOne({ _id: args.id });
      }
    },
    events: {
      type: new GraphQLList(eventType),
      args: {
        listing_id: {
          name: 'listing_id',
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: function(parent, args, ast) {
        return models.Event.find({ listing_id: args.listing_id });
      }
    }
  }
});

var schema = new GraphQLSchema({
  query: rootQueryType
});

export var getProjection;
export default schema;

We declare a root query that contains certain fields that are resolved by particular functions. The type of each field can be a list, non-null or other types. The resolve function is what fetches data from the database (or whatever caching layer(s) you have).

Within the GraphQLObjectType we can define a structured object with more fields and define the types of those fields. This is in contrast to most REST APIs which provide no schema.

It’s also possible, as you define the fields, to provide descriptions of them. These descriptions can appear in a GraphQL API explorer and since they are built-in and supported as part of the GraphQL specification, the descriptions can be supported by multiple libraries. In contrast, most REST APIs do not place descriptions near the fields within the code; they provide the descriptions (if at all) within separate documentation.

When building this prototype to provide a GraphQL interface to a MongoDB database, it was very easy to declare the schemas for the models and then to provide them as part of the interface.

Click here to see more code for a GraphQL server made with Node, Express and Mongoose.

Want to learn more about GraphQL?

Click here to see a list of 3 excellent videos explaining how GraphQL works.

Here are some questions on GraphQL at StackOverflow:

It is an exciting technology that promises to make it easier for clients to consume APIs and only receive exactly the data that they need.

Categories: AngularJS, Web Dev Training

How to use Local Storage for Caching in AngularJS 1.6

After we talk about window.localStorage and caching, I discuss the state of the Angular web framework with respect to AngularJS 1.6 and Angular 2/4/5+.

Local Storage and Caching in AngularJS 1.6

Let’s get to the fun stuff, Local storage in AngularJS 1.6!

Window Local Storage is an HTML5 web api that can be used to store data in the browser. The data is stored in a bucket for the current domain name (click here to view the Storage API).

An awesome developer created the angular-local-storage module for AngularJS 1.6 which gives you a nice API to work with in AngularJS for local storage.

What’s cool about is that you can listen for notifications whenever the local storage has been changed (with setItem or removeItem). It also lets you set the storage to use local storage or session storage. Session storage is great for quick caching while local storage is more long-term.

AngularJS API for Local Storage

The API for angular-local-storage is easy to use:

  • isSupported – whether the browser supports local storage
  • setPrefix – prefix used when setting keys
  • getStorageType – the type of storage used
  • set – set a value
  • get – get a value
  • keys – the list of keys that have been set in local storage (very very convenient!)
  • remove – remove a value
  • clearAll – remove all values set
  • bind – binds a value from local storage to a variable in the $scope

The most important API functions for angular local storage are: set, get, and bind.

Here’s an example of how it’s used:

var myApp = angular.module('myApp', ['angular-local-storage']);
myApp.controller('HomeCtrl', ['$scope', 'localStorageService', 'someApiService', function($scope, localStorageService, someApiService) {
  
  function $onInit() {
    console.log('the keys! ' + localStorageService.join(', '));
    console.log('storing a value from an API call');
    someApiService.fetchValues(function(values) {
      localStorageService.set('valuesFetched', values);
    });
    localStorageService.set('formSubmitted', false);
  }

  function submitForm() {
    if (localStorageService.get('formSubmitted')) {
      console.log('form already submitted!');
    } else {
      localStorageService.set('formSubmitted', true);
    }
  }
}]);

In the example you can see that angular local storage is used to fetch values when the controller HomeCtrl is initialized with $onInit. After the value is fetched, we use the localStorage service to set the initial value for formSubmitted.

When the form is submitted through the submitForm method, we check the value of formSubmitted through localStorage and then set its value. The idea is to prevent resubmission of the form. Of course this is just for the frontend and it’s a good idea to check for resubmission on the server backend.

Angular local storage is simple to use and highly valuable as a cache for AngularJS web apps.

The State of Angular 2/4/5+

After the last year of keeping up with Angular 2/4/5+ development, it seems that they’re still gearing up. In my eyes, they have taken on a lot of work and have shifted the ground underneath developers quite a bit. The full adoption and support for TypeScript is welcome news, but there are still many development shops that will use JavaScript and ES6 with Babel. The documentation and examples do not seem to support JavaScript as much as they support TypeScript. This is also true for Dart, which is used by Google for one of the larger Angular projects, but even they cannot count on full support from the Angular team.

There’s also the rapid rate of change. Angular has an upgrade path however it is not fun to upgrade dependencies and change code every few months because the API of the framework has changed.

The state of Angular 2/4/5+ at this point is similar to the state of the Django web framework before it was version 1.0. Before 1.0 of Django, every single week seemed to bring new changes in the codebase. It was fun to be on the cutting edge and the latest and greatest but Django before 1.0 was not ready for production. This cycle is happening to Angular 2/4/5+. If you want to be on the cutting edge, use Angular and be careful when deploying and maintaining a production app.

When should you consider using Angular 2/4/5+?

If you are starting a new project, you should consider Angular 2/4/5+

If you want to develop a mobile app using Angular, use NativeScript with Angular 2./4/5+

If your web development team has at least 3 developers, consider using Angular 2/4/5+

When should you consider using AngularJS 1.6?

If you have an older AngularJS 1.x project, consider upgrading it to AngularJS 1.6 (don’t attempt a rewrite in Angular 2 until you do that!)

If your web development team has 1 to 3 developers, consider AngularJS 1.6 because you will find a lot of modules that have been production-ready and are well-tested. You will be able to ship the project into production and support it for years to come. As I pointed in the last Learning AngularJS issue about Siberian CMS, they are using AngularJS 1.3 for mobile apps and it still works just fine for them.

Thanks for reading!

Thanks for reading! If you’re still using AngularJS 1.6, don’t worry you are not alone, there are thousands of projects out there also using it and the modules are well-tested and production-ready! If you ever wanted to use local storage in AngularJS, now here’s your chance with angular-local-storage.

Click here to read more Learning AngularJS.

Categories: AngularJS, Web Dev Training

SiberianCMS: make amazing mobile AngularJS apps

SiberianCMS, a mobile AngularJS CMS, is a content management system. Much like Drupal or WordPress it is easy to manage a lot of content and to produce a mobile app.

Its most unique feature is that it makes mobile apps. The code will compile into a native Android or iOS/iPhone app with all of the content managed by the SiberianCMS backend. If you ever wanted to quickly create a mobile app, this might be the tool for you. I’m considering using it to lower the effort and cost required to create a mobile shopping app and to use it for hackathons.

Continue reading “SiberianCMS: make amazing mobile AngularJS apps”

Categories: Web Dev Training

Developer Feedback Loop: Elm Vs React article published on CodeMentor.io

I have published another article on CodeMentor.io, this time comparing Elm vs React for web development, click here to read it.

The article covers the elm vs react developer feedback loop which is highly important when developing software and web applications. It is also one of the hardest things to get right for web development with the rise of tools like Webpack and Rollup.js and SystemJS.

Continue reading “Developer Feedback Loop: Elm Vs React article published on CodeMentor.io”

Categories: Portfolio, Software Development, Web Dev Training

Stylelint: Lint your CSS

When working with CSS, developers usually don’t think about running a linter on the stylesheets. We usually use linters on C or C++ or JavaScript codebases. However, we don’t often think about whether or not it’s even possible to lint a CSS stylesheet and enforce certain coding standards and rules on it.

With Stylelint, you can lint your CSS and make sure it’s in line with common standards, more powerful than that is writing your own stylelint rules.

CSS Needs Linting Tools Just Like Other Languages

Here’s a few reasons why you would want to write your own custom rules for a linting tool:

  • You can make sure the code base is readable and consistent (a necessity for CSS!)
  • You can prevent some mistakes from happening (for example, always using parens around method calls in Ruby or CoffeeScript, or making sure every method has a comment explaining what it does)
  • Linters can warn you of potential issues (to take a Ruby on Rails or Django example, when you’re using the wrong method to get the count of items in the database)

So I sat down and read through the CSS stylelint guide on writing plugins and rules and came up with a basic example that other developers can build upon to lint their own CSS code.

Continue reading “Stylelint: Lint your CSS”

Categories: Portfolio, Web Dev Training

Instagram clone in Elm

CodeMentor has published the first part of my tutorial on creating an Instagram clone in Elm. It covers how to create nested components and the basic life cycle and architecture of Elm frontend web apps.
I am seeing more power and usability in the Elm programming language and it has been great to compare it with how AngularJs, Ember.js and React & co. work. The performance is really quite something, the virtual dom is very cool and it is neat to see how the DOM changes in the developer tools of Chrome and Firefox.

What I love is the syntax which has sensible import and export module declarations, cleaner and almost completely optional type annotations (excellent type inference), all data structures are immutable by default, and the compilation speed is quick.

The frontend web development world has changed a lot in the last 5 years and it is wonderful to see developers using ES6 and Flow or TypeScript and realizing the value of type checking and of great tools like webpack.

The reason I am writing about Elm and exploring the language and its libraries is because it is so unlike the typical JavaScriot syntax and is much more integrated than the alternatives (such as React). The other reason is to see what ideas and design patterns can be brought back into the usual JavaScript development. That was why I explored Sweet.js which is a way to have compile-time macros that are modeled after Lisp integrated with JavaScript.

It is exciting to be a frontend web developer with all these good tools, frameworks and libraries.

click here to check out the first part of Building An Instagram Clone in Elm.

Categories: Web Dev Training

Top 3 Reasons You Need to Hire a Tech Career Coach

In your software development or IT career, you’re going to eventually get to a point where you don’t quite know what to do next, or how to get to the next stage of your career. It can be hard to figure out what sorts of projects you want to work on next, or what kind of work environment would best suit you. In interviews, it’s common to ask what your plans are for the next 5 years, but what about the next 10 years? What about for next month? And what tech should you learn next? How can you best prepare for your next interview? This is where a tech career coach comes in. They can help you figure out those hard questions about your career, your current job, and your future jobs.

Here are the top three reasons you need to hire a tech career coach.

Continue reading “Top 3 Reasons You Need to Hire a Tech Career Coach”

NeverFriday Software Expertise Proudly powered by WordPress , Theme designed by FancyThemes