The Fairway Technologies Blog

blog

Recent Posts

May 1, 2014 | Jeff Treuting

Test from live writer

Summary

angular.module('ucopag.manage.submission', [])
.config(['$stateProvider', function($stateProvider) {
$stateProvider.state('submission', {
url: '/submission',
views: {
"main": {
templateUrl: '/Features/Manage/app/shared/body.tpl.html'
}
},
data: {
pageTitle: 'Course Submission',
accessAbility: UcopAgAbilities.SubmissionDraftCourse
}
})
.state('submission.index', {
url: '/step/1',
views: {
"body": {
controller: 'SubmissionStep1Ctrl',
templateUrl: '/Features/Manage/app/submission/step1.tpl.html'
}
},
resolve: {
programs: ['$http', 'enums', function ($http, enums) {
return $http.get('/api/institution/programtype/' + enums.programType.program, {})
.then(function (res) {
return res.data;
});
}],
ropcs: ['$http', 'enums', function ($http, enums) {
return $http.get('/api/institution/programtype/' + enums.programType.rOPC, {})
.then(function (res) {
return res.data;
});
}],
publishers: ['$http', 'enums', function ($http, enums) {
return $http.get('/api/institution/programtype/' + enums.programType.onlinePublisher, {})
.then(function (res) {
return res.data;
});
}],
years: ['$http', function ($http) {
return $http.get('/api/academicyear/currentandlastthree', {})
.then(function (res) {
return res.data;
});
}],
olderYears: ['$http', function ($http) {
return $http.get('/api/academicyear/older', {})
.then(function (res) {
return res.data;
});
}],
schools: ['$http', function ($http) {
return $http.get('/api/institution/schools', {})
.then(function (res) {
return res.data;
});
}],
districts: ['$http', 'enums', function ($http, enums) {
return $http.get('/api/institution/type/' + enums.institutionType.schoolDistrict, {})
.then(function (res) {
return res.data;
});
}]
}
})
.state('submission.step2', {
url: '/{courseId}/step/2',
views: {
"body": {
controller: 'SubmissionStep2Ctrl',
templateUrl: '/Features/Manage/app/submission/step2.tpl.html'
}
},
resolve: {
model: ['$http', '$stateParams', function ($http, $stateParams) {
var url = '/api/submission/' + $stateParams.courseId + '/step/2';

return $http.get(url, {})
.then(function (res) {
return res.data;
});
}],
courseId: ['$stateParams', function ($stateParams) {
return $stateParams.courseId;
}],
allSubjectAreas: ['$http', function($http) {
return $http.get('/api/subjectarea', {})
.then(function (res) {
return res.data;
});
}],
allDisciplines: ['$http', function ($http) {
return $http.get('/api/discipline', {})
.then(function (res) {
return res.data;
});
}],
courseLengths: ['$http', function ($http) {
return $http.get('/api/courselength', {})
.then(function (res) {
return res.data;
});
}],
allLanguages: ['$http', function ($http) {
return $http.get('/api/language', {})
.then(function (res) {
return res.data;
});
}],
cteIndustries: ['$http', function ($http) {
return $http.get('/api/cteindustry', {})
.then(function (res) {
return res.data;
});
}],
}
})
.state('submission.step3', {
url: '/{courseId}/step/3',
views: {
"body": {
controller: 'SubmissionStep3Ctrl',
templateUrl: '/Features/Manage/app/submission/step3.tpl.html'
}
},
resolve: {
courseId : ['$stateParams', function($stateParams) {
return $stateParams.courseId;
}],
model: ['$http', '$stateParams', function ($http, $stateParams) {
return $http.get('/api/submission/' + $stateParams.courseId + '/step/3', {})
.then(function (res) {
return res.data;
});
}]
}
})
.state('submission.step4', {
url: '/{courseId}/step/4',
views: {
"body": {
controller: 'SubmissionStep4Ctrl',
templateUrl: '/Features/Manage/app/submission/step4.tpl.html'
}
},
resolve: {
courseId : ['$stateParams', function($stateParams) {
return $stateParams.courseId;
}],
model: ['$http', '$stateParams', function ($http, $stateParams) {
return $http.get('/api/submission/' + $stateParams.courseId + '/step/4', {})
.then(function (res) {
return res.data;
});
}]
}
})
.state('submission.step5', {
url: '/{courseId}/step/5',
views: {
"body": {
controller: 'SubmissionStep5Ctrl',
templateUrl: '/Features/Manage/app/submission/step5.tpl.html'
}
},
resolve: {
courseId: ['$stateParams', function ($stateParams) {
return $stateParams.courseId;
}],
model: ['$http', '$stateParams', function ($http, $stateParams) {
return $http.get('/api/submission/' + $stateParams.courseId + '/step/5', {})
.then(function (res) {
return res.data;
});
}]
}
})
;
}])

April 25, 2014 | Jeff Treuting

Simplifying AngularJS form validation with a custom directive - Part 1. client side

Summary

When I started using AngularJS I quickly came across the need to do form validation and display appropriate error messages to the user.  Naturally I did some searching of the interwebs to find examples and tutorials on how to get this done quickly and easily.  All of the examples I found seemed to show the same basic approach which was to have multiple error message divs for all of the possible error messages attached to a particular field, and use ngShows to control which, if any, is displayed.  This works great, but it felt like a lot of redundant code to me and it also didn't take care of displaying any server-side validation messages for me.  I decided to create a custom directive to handle this for me so that I could be more productive, and my inspiration was the ASP.NET MVC Html.ValidationMessageFor() single call that handles multiple error messages within an MVC view.

March 28, 2014 | Jeff Treuting

Making C# Enums Available Within Your Javascript

What's the problem that I'm trying to solve?

In my current project, I have a set of Enums on my server that represent certain lookup data.  For example, I have a PhoneType and AddressType Enums that I use instead of using the specific integer that is used in the database.  This makes the code more readable and there aren't a bunch of "magic ints" (tm/patent pending) thrown around throughout the code.  This is a fairly standard practice.

January 17, 2014 | Jeff Treuting

Soft-Delete As a Cross-Cutting Concern With SharpRepository

Overview

Doing soft deletes is a very common requirement or preference used in software development and it has many benefits including the main one of not accidentally losing data since it is never actually deleted from the database.  The main approach to doing this is to add an IsDeleted flag to the database table and setting that to true instead of doing a hard delete.  Simple enough and it works pretty well.  The annoying part of using this approach comes when you have to add !IsDeleted to every single query you run against each table where you have implemented soft-deletes.  Casey, a fellow Fairway-er (or Fairway-ian, Fairway-ite, ???) pointed this out as we started working on a new project.  So we decided to treat this as a cross-cutting concern and implement it as an attribute that we can apply to the entities that we want to be soft-deleted.  While we are still early on in using this new approach, so far so good.

January 17, 2014 | Jeff Treuting

Simple Auditing As a Cross-cutting Concern With SharpRepository

Depending on the exact needs of your application a very simple audit trail might be all you need.  If that is the case here, there is a simple way to handle that within SharpRepository.  If you need to know the history of who changed what and when, then this solution will not work for you as we are just storing the last user to make changes.

January 17, 2014 | Jeff Treuting

Getting Your Hooks Into SharpRepository

Overview

A little while back I noticed that a GitHub user had forked SharpRepository and added some simple hooks into it in order to automatically index entities into Lucene when they are added, updated or deleted through SharpRepository.  This was such a good idea that I knew we needed to get some proper hooks into the library itself.  We decided to use an Aspect Oriented Programming approach and allow developers to decorate their entities with attributes that would hook into the proper part of SharpRepository to give them the controls they need.

September 20, 2013 | Jeff Treuting

Formatting Diff Output Into A Word Document

Why would you ever want to do that?

One of my recent projects involved optimizing an existing application and squeezing out as much performance as possible.  In a development environment, we started with the current code and made changes, tweaks, and fixes until we ended up with an application that performed much better.  One of the deliverables for this project was to document all of the code changes that were made, which is a perfect job for source control.  We used Git to output all of the differences from when we started to present, and got a wonderfully ugly text file output that would not be legible to our clients.  Hence the need to take this diff output and format it  into a pretty Word document that our client could easily understand.  Naturally the question became, how do we do that?

September 6, 2013 | Jeff Treuting

Using A Common Base Class Across Entity Framework Database First Entities

Background

Recently I've been working on adding the ability to hook separate cross-cutting concerns into SharpRepository, and the latest version of this code has these concerns added to the entities themselves as attributes.  Since this is looking like a promising approach, it got me thinking about how I could easily add a logging concern (a very common cross-cutting concern) to all of my entities without having to manually add an attribute to each entity. While this would work, I try to be lazy when I can so I'd rather not go through all that manual work.  So I began to wonder how I would do this using Entity Framework 5 and the database first approach since that is what I find myself using quite often.

June 14, 2013 | Jeff Treuting

Simple Scheduled Task Runner For a .NET Web Application

While developing a web application, a common requirement is to run some sort of code every night or every hour to do some processing behind the scenes.  For example, let's say you need to pull content from an external web service every hour.  There are many different ways to accomplish this, but depending on your exact needs and how "mission critical" the tasks are, some ways are better than others.

In the past, I've developed custom Windows Services, used the "Cache Expiration" technique, setup a Task Scheduler to send NServiceBus messages, and more.  There are pros and cons for each of these.  In this post, I'll show a simple console application that you can use to schedule multiple tasks within Windows Task Scheduler.

Overview

Here is my example scenario:

  • Every hour pull content from a third party web service
  • Every night send a usage report to administrators
  • Every night send membership expiration warning emails
June 1, 2013 | Jeff Treuting

Benchmark Testing C# Code

Each week at Fairway a bunch of the developers get together for "Code Club," and talk through the various solutions we each came up with for the weeks coding problem.  Recently, we've been going through the Project Euler problems. Each developer uses a language of their choice and goes about solving it however they see fit.  I decided that I would try solving the problem in various ways to compare the performance of each, and hopefully learn something interesting in the process.

In order to do this, I needed a good way to get benchmarks for each different algorithm I implemented. Most of the code I found online wasn't easy to reuse.  It was basically just getting the current time at the beginning, and the current time at the end, and calculating the difference yourself.  Thus making you repeat this code for each block you wanted to test.

This seemed too manual to me, so I decided to create a Benchmarker class to handle everything for me.

New Call-to-action

Sign Up For Our Monthly Newsletter

New Call-to-action