Why Upgrade Angular?

Just a few thoughts I wanted to throw out there. Feel free to provide feedback. I’ll probably add to this over the next few months.

Angular 2 (now known as just Angular) is a complete rewrite of Angular 1 (now known as AngularJS). Here’s a few pros and cons around upgrading to the latest version of Angular (4.x):

Pros:

  • Typescript – Angular was created to work, first and foremost, with Typescript. Typescript speeds up the development process by allowing editors to provide better tooling; autocompletion, code navigation, etc. Simple code errors are caught early on, in the editor, before running the app. Developers can also take advantage of decorators (annotations), arrow functions, destructuring, async/await and a myriad of other ES Next/Typescript features.
  • ES Modules – you can import other libraries in a way a similar to node. ES modules provides ways to optimize your code, such as tree shaking, which allows you to remove code that your app ultimately doesn’t use and thereby decrease the size of the app’s javascript bundle.
  • Forms – the latest version of Angular introduces model driven forms, as opposed to AngularJS‘ template driven forms. This allows forms to be easier to unit test which leads to more stable forms.
  • Components – Angular’s focus is on composing components. Advantages include more modularized code, creating well defined and contractual api’s around directives/components and how they interact with each other. This, along with the other items mentioned above enforces better application architecture and design.
  • Performance – change detection is completely different, no longer relying on a digest cycle. Instead zones are used to determine when asynchronous actions have been completed. The concept of unidirectional data flow allows components to interact with one another without causing side effects.
  • Official Support and Security – Official support for AngularJS will eventually end (see AngularJS 1.x Support Lifecycle). Upgrading to the latest Angular appears to be the only sustainable path to continue to receive support and security updates for Angular in the future. The Angular team has provided tools to support running AngularJS and Angular simultaneously to encourage upgrading parts of your current AngularJS app a little at a time until it is completely up to date.

Cons:

  • The initial learning curve for the team. Although, developers will most likely be able to pick up the concepts rather quickly, there are a number of concepts that are different coming from AngularJS and Angular; Typescript, component architecture, observables and RXJS, to name a few.
  • Refactoring code always carries an element of risk. Hopefully most issues can be mitigated with proper unit tests and code coverage, but inevitably, things could (and probably will) break while migrating to the latest version of Angular.
Advertisement

Deploying a WCF Data Service to a server that has WebDAV installed

Here’s a simple one, that was fairly annoying:

I deployed a WCF Data Service to a site today, and while I was testing all of the operations I found that both the PUT and DELETE verbs weren’t working. At first, a 405 Method Not Allowed was being returned. I placed the service within an Umbraco site so I just figured that was where the conflict was.

After some digging around on the internet, I came across across ASP.NET MVC got 405 error on HTTP DELETE request?, from Stack Overflow, which it stated that the issue was related to WebDAV. The solution was to remove the WebDAVModule. That got rid of the 405, but unfortunately didn’t resolve the issue.

The requests started returning a 200 status code, which was good, but the page that was coming back was a 500 error. Because I wasn’t testing the service on the actual machine, I wasn’t seeing the actual error. So I logged on to the server and the tests showed the following error:

HTTP Error 500.21 – Internal Server Error
Handler “WebDAV” has a bad module “WebDAVModule” in its module list

(Gotta’ love more detailed errors.) From there I found How can I get OData DELETE to work?, also from Stack Overflow, which gave a good explanation of what was happening and how to solve it. Apparently, WebDAV blocks the DELETE and PUT requests (thanks a lot WebDAV…) and so the solution is to remove WebDAV or disable it on your site. You can completely disable WebDAV as follows:

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>

Thank you to Stack Overflow and all those that contribute to it!

Cross Domain Requests with WCF Data Services and datajs

I have been developing a project that uses WCF Data Services 5.0 and datajs 1.1.0. Everything was working fine until I decided to move the client and service into separate projects. Once they were in separate projects, when I would launch them, they would, as expected, run on different localhost ports and therefore be running on different domains.

It was at this point the client stopped working. I noticed via fiddler that instead of making a GET request to the OData service, the browser based client was instead using the OPTIONS verb and the service was responding with a “501 – Not Implemented”.

I figured that this had something to do with the browser cross-domain policy, but wasn’t quite sure what to do. It was amazing to me that there didn’t appear to be a built-in/simple way to resolve this seemingly common issue. After a bit of googling, I found an MSDN blog post entitled, Getting JSON Out of WCF Data Services, by Glenn Gailey, that mentions a couple ways to get a service to format its response in JSONP (JSON with Padding).

I figured that the option involving the WCF Data Services Toolkit would be the easiest and attempted that first. The toolkit is available via nuget, so it was easy to install. But I ran into problems surrounding assembly conflicts. After struggling a while with that, I gave up and attempted the other option, JSONP and URL-controlled format support for ADO.NET Data Services.

After working with this next solution, I discovered that it didn’t work for WCF Data Services 5.0. I wish I would have taken the time the read the comments on the project’s page, because I had to learn the hard way why it didn’t work. The solution allows you to add the JSONPSupportBehavior attribute to your service class, which then attaches an inspector to the service to check for the $format and $callback query string parameters and then modifies the HTTP headers accordingly. For versions less than 5.0, the accepts header can be “application/json, text/plain;q=0.5” but I eventually learned that version 5.0 requires the header to be “application/json;odata=verbose”. I updated the JSONPSupportBehaviour.cs file accordingly.

WCF Data Service:

[JSONPSupportBehavior]
public class SampleService : DataService<SampleEntities>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        // ...
    }
}

JSONPSupportBehaviour.cs:

// replace the Accept header so that the Data Services runtime
// assumes the client asked for a JSON representation
httpmsg.Headers["Accept"] = "application/json;odata=verbose";
httpmsg.Headers["Accept-Charset"] = "utf-8";

Once I got all that figured out, I realized that datajs wasn’t including the $callback and $format parameters in the query string. Eventually I came across a post from the datajs project forum which gave some clarification on this whole issue and stated that the enableJsonpCallback needed to be set to true on the OData.read request. After making this final change, my client and service were able to communicated together just fine.

OData.read({
    requestUri: url,
    enableJsonpCallback: true
},
function (data, response) {
    // success
},
function (error) {
    // failure
});

Killing Connections to MSSQL Database

Every once in a while when I’m trying to restore a backup for a database on Microsoft SQL Server Management Studio (SSMS), I get something like the following error:

Title: Microsoft SQL Server Management Studio

Restore failed for Server ‘[server name]’.  (Microsoft.SqlServer.SmoExtended)

Additional information:

System.Data.SqlClient.SqlError: Exclusive access could not be obtained because the database is in use. (Microsoft.SqlServer.Smo)

From what I understand, this means that some process is holding on to a connection to the database and, therefore, I can’t do anything drastic. Because my job deals with the web, I usually find that the culprit holding on to the database connection is IIS. Typically, if I stop the application pool of the site that’s using the database, or the site itself, I’m able to complete my restore. But sometimes I can’t track it down or I’m just too lazy to do anything about it.  So I wrote a little script that kills the connections to a database by putting the database in single user mode and then back into multi-user mode. Here it is for reference:

DECLARE @DB VARCHAR(255)
SET @DB = 'databaseName'

DECLARE @SINGLE_USER VARCHAR(MAX)
DECLARE @MULTI_USER VARCHAR(MAX)

SET @SINGLE_USER = 'ALTER DATABASE {DB} SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
SET @MULTI_USER = 'ALTER DATABASE {DB} SET MULTI_USER WITH ROLLBACK IMMEDIATE'

DECLARE @SCRIPT VARCHAR(MAX)

USE MASTER

SET @SCRIPT = REPLACE(@SINGLE_USER, '{DB}', @DB)
EXECUTE(@SCRIPT)

SET @SCRIPT = REPLACE(@MULTI_USER, '{DB}', @DB)
EXECUTE(@SCRIPT)

I found this concept on an MSDN forum post and I borrowed the idea of using a variable for the the database name from stackoverflow.

Using CSS Classes for Image Alignment in TinyMCE

I had a problem with aligning images in the TinyMCE editor in Umbraco 4.7.1.1. There are two ways a user can align images: a) Using the paragraph alignment button, and b) Using styles defined for the editor. We wouldn’t need option b) at all except that, when you have margins automatically applied to the images, things can get messy. Even then, annoyingly enough, option b) doesn’t always work, depending on what tag the image is nested in. So I searched for a better solution. I wanted the user to be able to still use the alignment tool, but I wanted the tool to apply class instead of using the style attribute to the float the image.

Eventually, I found a blog post, Patching TinyMCE For Better Left/Right Aligned Images, by Gareth Senior, that included a simple solution to my problem. Gareth included code for a simple patch that made all my TinyMCE dreams come true. I’ll include the same code here, only I’ll also document how I implemented the changes in Umbraco.

The simple change is made to the tiny_mce_src.js. Normally, you make the changes to tiny_mce_src.js, then minify the file and use the minified version. The Umbraco installation includes a minified version of the file, but apparently it’s not used. I made the following changes to umbraco_client/tinymce3/tiny_mce_src.js, and it fixed things for me really nicely:

3469    case 'float':
3470+      tinymce.DOM.removeClass(n, 'align-left');
3471+      tinymce.DOM.removeClass(n, 'align-right');
3472+      if (v != "") tinymce.DOM.addClass(n, "align-" + v);
3473       isIE ? s.styleFloat = v : s.cssFloat = v;
3474       break;

This will add the class “align-left” or “align-right” to the image when the alignment options are used from the tool bar. You can then use those to create styles that will compensate for the margins.

NOTE: Be sure to clear the browser cache, or the browser will hold on to the old version and it will seem like it did nothing. Oh and remember that you’ll have to make this change again when you upgrade Umbraco as the upgrade will replace the edits.

Edit: 5/16/2012 – This also works in Umbraco 4.7.2.

Using The TinyMCE Color Picker in Umbraco

The Umbraco folks, for whatever reason, decided to strip out the text color picker in TinyMCE. I found that many of my users still need it, and I would rather not create custom styles for each of them. After a lot of blundering around, I found this Our Umbraco forum post which outlines how to add the color picker back in. I took it a little further and found it was real easy to limit the palette of colors available to the user. This can all be done in the tinyMceConfig.config. I’ve only used this on Umbraco 4.7.1.1.

Steps are as follows:

1.) Open config/tinyMceConfig.config in a text editor.

2.) To add the color picker button back to toolbar, add the following command to the <commands> node:

<command>
    <umbracoAlias>mceForeColor</umbracoAlias>
    <icon>images/editor/forecolor.gif</icon>
    <tinyMceCommand value="" userInterface="true" frontendCommand="forecolor">forecolor</tinyMceCommand>
    <priority>21</priority>
</command>

NOTE: Customize the priority based on where you’d like the button to be placed. I gave mine a “21” and I adjusted the others accordingly.

3.) To remove the “More Colors” link from the color picker, add the following to the <customConfig> section:

<config key="theme_umbraco_more_colors">false</config>

4.) Then to limit the palette available to the user, also add this key to the <customConfig> node:

<config key="theme_umbraco_text_colors">000000,0079E3,FF0033</config>

NOTE: Include your own RGB colors here. In my case, I’ve only decided to make these three (000000,0079E3,FF0033) available.

5.) “Touch” the web.config to recycle the application so the changes will take effect.

6.) Log in to the Umbraco backend and in the TinyMCE/Rich Text Editor/wysiwyg data type, enable the color picker button.

Presto! That’s it, the editor should now show the color picker.

C# with Mono

I’ve been wanting to learn C#. It seems everything is done in C# these days. But I have a Mac. I thought that the only way to program with C# would be on Windows XP via WMWare, but after a bit of research I found I was mistaken.

Enter Mono. (Mono, as in the prefix meaning “one,” not as in the disease.) Mono is an open source, cross platform implementation of the .Net Framework. It is available on a large number of platforms, including Mac OS X, Windows and Linux. Sounds cool, eh? That’s what I thought anyway. So I was excited to download and try it. It even comes with it’s own little IDE, MonoDevelop.

After I installed Mono and MonoDevelop, I was able to compile a quick “Hello World” console application. That was fun and easy. I wondered if I would be able to do the same with a Windows.Forms application. This is where I ran into some complications.

Whenever I tried to use System.Windows.Forms, I would get the following error:

The type or namespace name ‘Windows’ does not exist in the namespace ‘System’. Are you missing an assembly reference?

I searched all around to see what this could possibly mean. The Mono Project website said they supported Windows.Forms on Mac OS X. I had the full version of Mono. I reinstalled Mono and MonoDevelop several times. Unfortunately, since Mono is so new and there isn’t much of a Mac community for it, I was lost.

Finally, I stumbled on the Edit References window in MonoDevelop and found what I was missing. To find it:

  1. In the Project menu, select Edit References.
  2. On the Packages tab, scroll down to and select the assembly you wish to include (mine was System.Windows.Forms).
  3. Click OK.

And that’s all there is to it. My “Hello Form” project compiled just fine. It is important to note, that in order for the Edit References option to be available in the Project menu, you need to be working in an active project, or solution. When I was first trying to compile my “Hello Form” program, I had opened it as a single file and that was a mistake.

It might be best to note here also that System is another available assembly in the list. If you ever get a “missing assembly reference” error, check that list!

The code for my “Hello Form” program was very simple:

using System;
using System.Windows.Forms;

namespace HelloForm
{
    public class HelloForm : Form
    {
        public static void Main()
        {
            Application.Run(new HelloForm());
        }
    }
}

Blundering Dev

Definition of blunder by Oxford Dictionaries:

Blunder: Move clumsily or as if unable to see.

Most of what we do as developers is poke around in the dark. Often we make mistakes and that’s good, if we learn from them. Hopefully we’re not making the same ones over and over (that would be insane).

You just have to dive in and get your hands dirty. Most of the time, it’s awkward and clumsy. Here’s my blundering process:

  1. Google
  2. Refactor
  3. Compile
  4. Repeat as needed…

This site documents some of my blunderings while developing. (At least, the ones I wasn’t too lazy to write about.)

Hope you find it helpful!

 

BIOS Update

I’ve been working on a project to turn an old computer into a file server for backup purposes. The plan is to eventually run a script from my laptop which will start the server up and backup all my pictures, movies, music, etc. to the server. One of the hiccups I have run into is trying to figure out if my old Compaq Presario 7PL295 supports wake-on-lan.

Apparently, wake-on-lan is a BIOS setting, but what with my BIOS being so old, I didn’t find the option anywhere. So I went to the HP Customer Care website to see if they had any updates available. I found 3 updates, or ROMPaq’s as they call them. One of them (sp18768, released 2001-11-30) mentioned something about “Added support to show F12 Network boot message” which led me to believe that wake-on-lan was an option. After a bit a blundering, which I’ll go into at greater detail, I eventually installed the ROMPaq, unfortunately without any desired results. The “F12 network boot message” didn’t exist.

I’ve never performed a ROM firmware update before, so I have no idea whether the updates should be applied cumulatively in order. So that’s what I’ll try next, but allow me to document the steps I took to install my first firmware update. First let me explain a little of the situation.

My laptop is a MacBook Pro and therefore has no disk drive. The only way these ROMPaqs work is through a floppy disk. I’ve installed Ubuntu Linux on my Compaq and I don’t have any floppy diskettes anymore. I haven’t used one for years! So the question was, how to run a Windows executable to write to a non-existent floppy disk to update my Compaq’s BIOS?

On my Mac, I opened terminal and entered the following command:

dd bs=512 count=2880 if=/dev/zero of=floppy.img

This creates a image for a blank, unformatted floppy disk. From here I cheated and used VMWare to load Windows XP. I mapped the floppy image in VMWare, formatted the disk and then ran the SoftPaq executable. It placed the ROMPaq on the disk. Magic! But the problem at this point was how to get my virtual disk to load on my non-virtual computer.

I figured there had to be some way to burn the image to CD. After a bit of googling, I found a great article by Mark Alexander, I believe, which details how to do just that.

Using his instructions, I performed the following:

1.) I mounted the floppy image:

hdid floppy.img

2.) I created a temporary folder and copied the contents of the floppy disk to it:

mkdir tmp
cp -Rp /Volumes/<volume name>/* tmp/
cp -p floppy.img tmp/

3.) I created an ISO image using mkisofs. (Since I have a  Mac, I had to install mkisofs through Fink in order to get this one to work.)

mkisofs -pad -b floppy.img -R -o cd.iso tmp

4.) I burned the new ISO to a CD with Disk Utility.

5.) I placed the newly burned floppy disk qua CD into the tray and installed the firmware update.

This actually took me several attempts with several CD’s being burnt up in the process. But I finally got the process down pat. Now I just have to see what happens when I install the rest of the updates.

By the way, I would recommend using CD-RW’s as the medium and leaving the ISO’s on your computer (they’re only a couple megabytes). Especially if you’re applying multiple ROM updates like I am. That way you don’t have to burn up so many CD’s.