Quantcast
Channel: Jeffry Houser's Blog
Viewing all 497 articles
Browse latest View live

Select a Color -- Build a Color Picker in Angular 2 - Part 3

$
0
0
This section will show you how to run Angular code when the canvas is clicked on. Then it will process the image inside the canvas to determine the color and display the results out to the user. It will display results in two different ways; the first is to output the RGB values of the image. The second will be to display another canvas which is colored based on what we selected.

Modify the External Template

Open up the external template, canvas.html. We'll make a few changes here. First, add a cross hair cursor to the canvas using CSS. This will let people know the canvas can be clicked on: style="border:1px solid #d3d3d3;cursor: crosshair;" This might be better put in an external CSS file, but for simplicity I defined all styles in-line. The canvas will need to do something when the image is clicked, so add a click event: (click)="pickColor($event)" We'll create the pickColor() method inside our main app's component in the next section. Notice the click event is passed to the pickColor() method. Now, create a section to output the selected color:

Selected Color

RGBA: {{RGBA}}

Your browser does not support the HTML5 canvas tag.
The first thing it does is output a variable named RGBA. This includes the red, green, blue, and alpha values that make up the selected the color. We'll create that variable in the pickColor() event method. The second element in the template is a new canvas. This will do nothing but display the selected color of the canvas.

Modify the Script

Now move to the JavaScript code. All this code will modify the colorpicker-app component. First, we need a hook to get access to the selectedColorCanvas. Modify the queries property of the component: queries : { imageCanvas : new ng.core.ViewChild('imageCanvas'), selectedColorCanvas : new ng.core.ViewChild('selectedColorCanvas') } The imageCanvas was there from previous samples, but the selectedColorCanvas uses the same approach. The selectedColorCanvas variable will be accessible inside the class constructor. Inside the class constructor, create a variable for the selectedColorCanvas context: var selectedColorCanvasContext; Inside the image onload() method, inside the onInit() method, save the selectedColorCanvas 2D context: selectedColorCanvasContext = selectedColorCanvas.getContext('2d'); Also, create a variable to include the RGBA value: this.RGBA = '' This variable is put in the 'this' scope. This is similar to the $scope of an AngularJS 1 application, and using 'this' allows the value to be accessed inside the view template. Now, implement the pickColor() method. Here is the stub: this.pickColor = function(event){ } The event is passed in so we can get the x and y position that was clicked on the image: var data = imageCanvasContext.getImageData(event.layerX, event.layerY, 1, 1).data; This loads all the image data using the getImageData() method on the imageCanvasContext. The values into this method are the x value, the y value, the width, and height. layerX and layerY values from the event object specify the location that was clicked. By specifying 1, 1, for the width and height we get all the information for the single pixel which was clicked. The data object contains an array with four elements, representing the red, green, blue, and alpha properties on the pixel that was clicked. Now, let's draw that color on the selectedColorCanvas: selectedColorCanvasContext.fillStyle = "rgba(" + data[0] + "," + data[1] + "," + data[2] + "," + data[3] + ")" selectedColorCanvasContext.fillRect(0,0,250,250); First the fillStyle is defined, as a string, using the rgba() method along with the RGBA data. Then the fullRect() is called. The fullRect() method accepts four arguments, similar to the getImageData() method. The first two values are the x and y values to start the rectangle. The third and fourth values are the height and width, respectively. Our rectangle draws all over the selected canvas. Finally, set the RGBA value using the same data: this.RGBA = data[0] + "," + data[1] + "," + data[2] + "," + data[3] ; Now, run the code and start clicking away: You can play with the app here, but because of cross domain issues with the image I couldn't upload it to a Plunker.

Final Thoughts

It was nice to delve into the canvas functionality of HTML5 as I don't get to deal with that in normal enterprise level development for most of my clients. I'm starting to get deeper into Angular 2 development.
Sign up for DotComIt's Monthly Technical Newsletter

@types/node is not found in the npm registry

$
0
0
I'm trying to run through the Angular 2 Quickstart with TypeScript. When I try to run the npm install command I am getting a ton of errors like this: npm ERR! 404 Not Found npm ERR! 404 npm ERR! 404 '@types/node' is not in the npm registry. npm ERR! 404 You should bug the author to publish it npm ERR! 404 It was specified as a dependency of 'angular-quickstart' npm ERR! 404 npm ERR! 404 Note that you can also install from a npm ERR! 404 tarball, folder, or http url, or git url. npm ERR! System Windows_NT 6.2.9200 npm ERR! command "C:\\Program Files\\nodejs\\\\node.exe""C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js""install" npm ERR! cwd C:\quickstart npm ERR! node -v v0.10.29 npm ERR! npm -v 1.4.14 npm ERR! code E404 npm ERR! npm ERR! Additional logging details can be found in: npm ERR! C:\quickstart\npm-debug.log npm ERR! not ok code 0 It is very frustrating to jump into something new only to find their quick start documentation does not work. The solution appears to be to update NodeJS and npm. I downloaded a new version of NodeJS from the NodeJS.org web site. After it was installed, you can update npm like this: npm install npm@latest -g Check your versioning like this: node -v npm -v This upgrade appears to have solved my issues.

Building HTML5 Applications with TypeScript and Gulp - Part 1

$
0
0
TypeScript is a newish language for application development on the web. It is a superset of JavaScript, and supports things like static typing and class based object oriented programming. Static typing, particularly, can offer improved tooling over what is currently available for simple JavaScript programming. TypeScript can be used for any web application, or even on the server side with NodeJS. It is the recommended language for Angular 2 applications. TypeScript is compiled to regular JavaScript for deployment and testing. This white paper will explain the infrastructure we use to make this happen.

The TypeScript Application

Before we start to look at the build process, let's look at a super simple TypeScript application. We'll need some code to compile. This code borrows heavily from the official TypeScript tutorials. It will add a 'hello world' message to the body of an HTML page. Create a directory for this setup. The final directory setup will look something like this: This is a description of each directory:
  • TypeScriptAndGulp_Article: The root directory will contain the script files for running Gulp and config file for NodeJS.
    • build: This directory will contain the final, processed, build.
    • node_modules: This directory will contain the NodeJS package, such as Gulp and TypeScript, to needed to perform the actions.
    • src: This directory will contain the application's source files.
We will create most of these files and directories as we move through the process. For now, I named the project directory TypeScriptAndGulp_Article. Start by creating the src directory. I always separate the source code, compiled code, build scripts, and NodeJS modules. Inside the src directory, create an index.html file: TypeScript Sample for DotComIt Article This is a simple index.html file. There is one item I want to draw attention to. The script tag which imports a JavaScript file named sample.min.js. This is the file we will generate from the TypeScript code. Next, create a file named greeter.ts. The ts extension is the standard extension for TypeScript files, similar to how 'js' is the standard extension for JavaScript files. For this sample I'll put all the files inside the root of the src directory, however in a more complex application, I may categorize the files under a descriptive directory structure. This is the greeter.ts: export function sayHello(name: string) { return `Hello from ${name}`; } This file exports a function named sayHello(). The export is not something you'll commonly see in browser JavaScript, but is used when creating NodeJS Modules. It, basically, says that "This is an API I Want people to use to access code in this file." The sayHello() method has a single parameter, name. The type of the name is specified, something that doesn't happen in JavaScript but adding it allows for type checking at the compiler level. The body of the method returns a string, referencing the name variable inside the string. The syntax is very similar to JavaScript, so learning TypeScript should not be a big hurdle for you to climb. Now create a file named main.ts. This is the entry point to our application. Back in my school days we'd call the routine that ran the app a main routine, so this is a similar approach. The first thing the main.ts does is import the greeter file: import { sayHello } from "./greeter"; This makes all the code from the greeter.ts file available to use in the main.ts file. Now, create a showHello() method: function showHello(name: string) { document.body.innerHTML = sayHello(name); } This method looks a lot like a JavaScript method definition, the only difference is that the name variable is given a type of string. The code accesses the innerHTML of the web pages body tags and outputs the results of the sayHello method, which will just be a string that says hello from the given name. Finally, call the showHello() method: showHello("World"); That completes the super simple TypeScript application. I could write a lot about TypeScript, however I wanted this article to focus on the build process of turning TypeScript into a JavaScript web application. As such, I'll leave the JavaScript there. When you finally compile the application, it should look something like this in the browser:

A Basic Compile Script

To compile TypeScript into JavaScript we are going to use NodeJS and a bunch of plugins.

Install and Setup NodeJS

The first step is to install NodeJS if you haven't already. The formal instructions will give you more detailed instructions if you haven't already done so. Then create a generic package.json configuration file. You can run this script: npm init And follow the instructions to create a simple package.json. You'll see something like this: My final package.json is listed below: {"name": "typescriptandgulp","version": "1.0.0","description": "A sample project to compile TypeScript with Gulp","main": "index.js","scripts": {"test": "echo \"Error: no test specified\"&& exit 1" },"author": "Jeffry Houser","license": "ISC","repository": {} }

Install Node Modules

Now we want to install some NodeJS plugins. First, we want to make sure Gulp is available. Gulp is the script runner we'll use to execute tasks to run our application. Run this command: npm install --save-dev gulp You'll see a screen similar to this: You can ignore the warnings. Your project directory will now have a node_modules directory. Next, install the TypeScript plugin: npm install --save-dev typescript The NodeJS TypeScript plugin will not be used directly in the gulp script, but is a required dependency: Next, install browserify. Browserify will combine all the JavaScript files into a single file. We also want tsify installed, a plugin that will allow browserify to compile TypeScript into JavaScript. First, install browserify: npm install --save-dev browserify You'll see results like this: Then install tsify: npm install --save-dev tsify Your screen should look like this: A Gulp stream object is named vinyl and is a virtual file format. To manipulate the output from Browserify with a Gulp script , we'll need to convert Browserify's object to the vinyl format. Thankfully there is a plugin for that, vinyl-source-stream module: npm install --save-dev vinyl-source-stream See the console results: It is a lot of setup, but we should have all the required plugins we need to get started now.

Create the Gulp Task

In the root directory of the project, create a file named gulpfile.js. It is the default Gulp configuration file. First, load the gulp module: var gulp = require("gulp"); From there, you can create a gulp task for compiling TypeScript: gulp.task("buildTS", function () { }); This is a blank task that does nothing. It calls the task() method on the gulp object. The task() method has two argument: the name of the task and a function to perform the task. You can execute this task by typing this into your console: gulp buildTS You should see something like this: The task does nothing yet, though. Let's make it do something. Import the rest of the libraries: var browserify = require("browserify"); var source = require('vinyl-source-stream'); var tsify = require("tsify"); Make sure these libraries are imported outside of the Gulp task. After the library import, still outside the Gulp task, let's define a few variables. The first is something I call appEntry: var appEntries = ['src/main.ts'] It is an array that contains the main TypeScript file. Browserify will analyze main.ts to find all other files it uses and will do recursively. This is a bit different than the process I used in an AngularJS JavaScript application; where I'd process all files ending with the js extension. Next, create a variable for the processed file name, and one for the final path: var javaScriptDestinationFile = 'sample.min.js'; var destinationPath = 'build'; The destination file is the final output after the TypeScript files are merged and compiled into a single one. We referenced this file name in the index.html document. The second variable specifies the final destination of the file. I could define these as part of the Gulp task, but prefer to define them as global variables so they are easily accessible across multiple tasks, and I can tweak how everything works just by changing the config values. Now go back inside the buildTS task and call the browserify() method: return browserify({ compilerOptions: { module: "commonjs", target: "es5", }, entries: appEntries }) This calls the browserify() method and passes in an argument. The argument object specifies the configuration for this browserify process. Let's go through them:
  • compilerOptions: This is another object that specifies how the TypeScript compiler will work.
    • module: Specifies how modules are loaded in UI code, in this case we are using the commonjs convention.
    • target: Specifies the ECMAScript version you want to output to; in this case I am specifying EcmaScript 5, however other versions are supported.
  • entries: Specifies an array of entry points to your application.
This is a very simple config, and it can be a lot more complicated if you need it to be. Next, tell Browserify to compile the TypeScript code: .plugin(tsify) Each successive command is daisy chained on the other with the dot syntax. This uses the Browserify plugin() method to call the tsify package to compile the TypeScript code into JavaScript. Next, call bundle() to merge all code into a single unit: .bundle() This one is simple. Then, specify the name of the new file: .pipe(source(javaScriptDestinationFile)) This uses the vinyl-source-stream module to turn the javaScriptDestinationFile name into something that can be accessed via Gulp. The pipe() method means that we are getting ready to output information, instead of processing input. Finally, specify the destination of the new file: .pipe(gulp.dest(destinationPath)); This uses the pipe() operator too; and the value is Gulp's dest() function. This, basically, tells the script to put all our files in the build directory. You can run the gulp script: Look at the directory structure after our first run: All the node modules we installed are in the node_modules directory. The source we looked at earlier is in the src directory. The JavaScript file built from the TypeScript files is in the build directory. The gulpfile.js and package.json are in the root application directory. I like this structure because it cleanly separates concerns. Things are not yet runnable in a browser, because the Index.html was not moved from the src directory to the build directory. For the sake of this article, you can move it manually. Runt he code in the browser, and you should see this: This isn't an interesting app, but it does prove that Gulp is successfully compiling TypeScript and copying the HTML files from the source directory into the build directory.

What's Next?

The next article in this blog series will focus on how to write a Gulp Script that will watch for any changes to your TypeScript files, and re-compile them as you change code. If you want a more in depth tutorial, sign up to get our full 30 page white paper on building TypeScript applications with Gulp.
Yes, I want to get your white paper on building TypeScript applications

Compile Code on the Fly - TypeScript and Gulp - Part 2

$
0
0
This is the second in a series of articles no compiling TypeScript applications with Gulp. Check out Part 1 which covers most of the setup; or sign up below to get our fully detailed white paper. Gulp allows us to automatically run a gulp task when a certain directory changes. This is built in and we don't need an additional plugin to make it happen. We're going to make a task which will watch for TypeScript files for changes, and then trigger the buildTS task again. First, let's create a variable to point at the TypeScript source: var typeScriptSource = [sourceRoot + "/**/*.ts"]; The sourceRoot variable was created in the previous article, and points to the src directory. The wild cards tell Gulp to look at all subdirectories inside the sourceRoot folder. Now create a gulp task called buildWatch: gulp.task('buildWatch', ['buildTS'], function(){ }); You'll notice that there are three arguments to this gulp task, something we hadn't seen before. The first is the task name, buildWatch. The second is an array of strings with each string represents a gulp task. These tasks will run before the third argument's function is executed. Here we are only running one task, buildTS, before starting the buildWatch task. Here is the function code: gulp.watch(typeScriptSource,['buildTS']).on('change', function(event){ console.log('Event Type' + event.type); console.log('File Path' + event.path); }) We use the watch() function on the Gulp object. It accepts two arguments. The first argument is a source array, in this case the typeScriptSource value. The second argument is a task array. In this case just the buildTS task. Reading this in English, it says watch for files that match typeScriptSource, and when something changes run the buildTS task. Dot notation is used to daisy chain an 'on' method to the watch. When the change event occurs, the type of event and modified files are output to the console. Run this script: gulp buildWatch You'll see something like this: The important thing to notice is that the console does not go back to a command prompt; the code is left running in the background. Change some code to see what happens: As you save files, the script automatically notices, and reruns the appropriate task. You'll get console information about the file that has changed. Overall, I find the watch task to be a very powerful development tool.
Yes, I want to get your white paper on building TypeScript applications

Building Angular 2 TypeScript Applications with Gulp and Browserify

$
0
0
I've been dealing a lot with build processes and build scripts lately. This blog post will show you how to build Angular 2 applications with Gulp discuss some of the limitations I found with the approach. When reading the TypeScript docs, Browserify is the tool of choice for compiling TypeScript with Gulp. I wanted to see if I could get it working when dealing with Angular applications. For the purposes of this post; I'm not going to review a TypeScript / Angular 2 application; I'm just going to use a simple Hello World from the Angular 2 docs.

The Setup

First, you'll need to install the required nodeJS Dependencies. Instead of installing everything independently, just copy this into a package.json file: {"name": "Angular2TypeScriptGulpBrowserifySample","version": "0.0.1","description": "DotComIt Project Sample for building Angular 2 Apps with TypeScript, Browserify, and Gulp.","author": "Jeffry Houser","license": "ISC","dependencies": {"@angular/common": "~2.4.0","@angular/compiler": "~2.4.0","@angular/core": "~2.4.0","@angular/forms": "~2.4.0","@angular/http": "~2.4.0","@angular/platform-browser": "~2.4.0","@angular/platform-browser-dynamic": "~2.4.0","@angular/router": "~3.4.0","angular-in-memory-web-api": "~0.2.2","systemjs": "0.19.40","core-js": "^2.4.1","reflect-metadata": "^0.1.8","rxjs": "5.0.1","zone.js": "^0.7.4" },"devDependencies": {"browserify": "^13.3.0","gulp": "^3.9.1","tsify": "^3.0.0","typescript": "^2.1.4","vinyl-source-stream": "^1.1.0" },"repository": {} } Run this command: npm install To install everything. The dependencies are all the relevant Angular 2 Modules. The devDependencies are all the node projects used in the gulp script:
  • Browserify: Browserify is a tool for concatenating JavaScript files into a single one.
  • Gulp: Gulp is our script runner tool.
  • tsify: A Browserify plugin to compile TypeScript files
  • TypeScript: The module used for compiling TypeScript.
  • Vinyl-Source-Stream: Vinyl is the format used by Gulp. This task will convert Browserify output into something Gulp can use.
With everything installed, we are ready to start writing our Gulp Scripts.

TypeScript Configuration

We'll want to configure the TypeScript compiler to make things work. Just create a file called tsconfig.json in the application's root directory: {"compilerOptions": {"target": "es5","module": "commonjs","moduleResolution": "node","sourceMap": true,"emitDecoratorMetadata": true,"experimentalDecorators": true,"lib": [ "es2015", "dom" ],"noImplicitAny": true,"suppressImplicitAnyIndexErrors": true } } I'm not going to expand on the details of this for the purposes of this sample. I think I borrowed it from one of the samples on the TypeScript web site.

The Gulp Script

Start with an empty Gulp Script, named gulpfile.js, and import the required libraries: var gulp = require("gulp"); var browserify = require("browserify"); var source = require('vinyl-source-stream'); var tsify = require("tsify"); Now, create a few variables. First, the source root: var sourceRoot = "src/"; For all my projects, I put the source in a directory named src. Also, define the final minimized JavaScript file: var javaScriptDestinationFile = 'app.min.js'; I named it app.min.js, but you can change it if you need to. Define the final destination path: var destinationPath = 'build'; I always build my projects into a directory named build. Finally, we are going to define something called the entry. This is the first TypeScript file that defines the application. All other TypeScript files will be referenced from the initial application entry point: var appEntries = [sourceRoot + 'main.ts'] The file is named main.ts. Let's create the gulp task: gulp.task("buildTS", function () { } I named the task buildTS, for Build Type Script. This is a common convention I use with a lot of project setups. Right now the task does nothing, let's add in browserify: return browserify({ entries: appEntries }) The Browserify task specifies the appEntry, but has no other properties in its configuration object. By default Browserify does not handle TypeScript. That is what we use the tsify plugin for. The dot notation is used to chain other commands off the browserify object, so let's add in the plugin: .plugin(tsify) The plugin will know to look for the tsconfig.json file for configuration options. That is all that is needed for Browserify to support TypeScript code. Next, create a bundle: .bundle() This is the browserify command to run the script and return the processed files. We need to turn that browserify return object into a Vinyl stream: .pipe(source(javaScriptDestinationFile)) Thankfully we had a NodeJS plugin just for that. Next, specify the final destination of the file: .pipe(gulp.dest(destinationPath)); This successfully creates the final file. Run the task, like this: gulp buildTS You'll see some results like this: Look in your application's directory and you should see a build directory like this:

Don't forget to copy the JavaScript and HTML libraries.

Even though Angular is primarily a TypeScript framework, it does rely on a few JavaScript libraries to run in the browser. We want to copy those from our node_modules directory to the build directory. This gulp script will do that: var htmlSource = [sourceRoot + '**/*.html']; var destinationPathForLibraries = destinationPath + '/js'; gulp.task('copyJSLibraries', function () { gulp.src(htmlSource) .pipe(gulp.dest(destinationPath)); gulp.src(['node_modules/core-js/client/shim.min.js']) .pipe(gulp.dest(destinationPathForJSLibraries + '/core-js/client')); gulp.src(['node_modules/zone.js/dist/zone.js']) .pipe(gulp.dest(destinationPathForJSLibraries + '/zone.js/dist')); gulp.src(['node_modules/reflect-metadata/Reflect.js']) .pipe(gulp.dest(destinationPathForJSLibraries + '/reflect-metadata')); }); I made it simple and it copies the three JavaScript files required by AngularJS in the browser: shim; zone; and reflect. An explanation of these libraries is beyond the scope of this article. This script also copies the HTML files from the src directory to the build directory. Run the script: gulp copyLibraries You should see simple results like this: Check the build directory to see the final files. The hello world should run now. That's awesome.

What's Wrong Here?

I didn't cover it here; we this approach does allow us to generate source maps and run the final JS code through a minimizer. However, I stopped moving down this path because the generated JS file includes all the Angular libraries. That made it very big. I tried some experimentation, but could not get the application working when separating the Angular framework libraries from the custom application code. I made the decision that the inability to separate the framework from my custom code was a deal breaker and abandoned this approach.

Final Thoughts

Since I gave up on this approach, what comes next? I'll be writing more about that in the coming weeks. Instead of using Browserify and tsify, I started using a Gulp TypeScript library directly to build the applications. This gave me the flexibility I needed to separate Angular and my custom code.

Open a Link in a New Window with AngularJS - Approach 1

$
0
0
I was working on a client project, built with AngularJS, and we wanted to open another application in a new window. This is a simple, common task, that you can accomplish with an href and a target. But we wanted to look for the most Angular way to accomplish it. Triggering the link in Angular gave us the option to do logging, or other functionality, before the click occurs. I decided to write a series about the different ways to make this happen.

The Setup

First, add Angular to your Application: Then, create an Angular Module and controller: angular.module('test',[]); angular.module('test').controller('someController',['$scope','$window', function($scope,$window){ }]); Two elements are injected into the controller. $scope is the common service used to communicate between the view and the controller. $window gives you an Angular reference to the browser's window object. We'll use $window to open the new page.

Open the new page

This method will open a new page: $scope.onButtonClick = function(){ $window.open('https://www.jeffryhouser.com'); } A function named onButtonClick() is saved to the $scope. Inside the button, the $window.open() method is called. This will force the window to open the URL in a new window. Now add some HTML:
The ngApp tag is put on the body. The ngController is put on a div. A button inside the div uses ngClick to call the onButtonClick() method. Load the app and you'll see something like this: A boring UI; but click the button: The link to my blog will open in a new tab, based on my default browser settings. Play with the code here.

What is Next?

The next entry in this series will show you how to use a similar approach to submit a form into a new window. Then, I'll write an entry about holding off on opening the new window until after an asynchronous call is complete. The last part is where things start to get complicated; but bear with me. We'll get there quickly.

Submit a Form Post to a New Window with AngularJS - Approach 2

$
0
0
I was working on a client project, built with AngularJS, and we wanted to use AngularJS to submit a form into another window. This could be done with a simple target on the form tag; but we wanted to be able to run other functionality at the time of the form post. I decided to write a series about the different ways to make this happen; and this is the second in the series. Check out the first.

The Setup

First, add Angular to your Application: Unfortunately, for this approach we'll need JQuery too: Then, create an Angular Module and controller: angular.module('test',[]); angular.module('test').controller('someController',['$scope', function($scope){ }]); The $scope service is injected into the controller. It is used to share data between the view and the controller. That is all the required setup.

Open the new page

First, I want to create the form that will be submitted. This is a hidden form with no visual elements:
An ID is specified, and we'll use this to get a hook to the form inside the angular code. Target is specified, and tells the form to submit to the window named 'myNewWindow'. The form action will post go back to my blog--however you could post it anywhere you want, even passing variables for processing. Add a button to trigger the form, which will open the link in the new window: Back to the JavaScript, this method will open a new page: $scope.onButtonClick = function(){ var form = angular.element('#myForm') form.submit(); } A function named onButtonClick() is saved to the $scope. Inside the button, the angular.element is used to get a handle to the form based on the form's ID. This uses JQuery under the hood, but did not work w/ the JQuery lite that is part of AngularJS, so that is why we had to use the full Jquery library earlier. Once we get a handle to the form, just submit it. Now add some HTML: Load the app and you'll see something like this: A boring UI; but click the button: A new tab will open with the form submit; in this case opening my blog: Play with the code here.

What is Next?

The next entry in this series will show you how to handle links that open inside an asynchronous call. By default browsers won't let you open new windows without user interaction; and that interaction has passed by the time the call is complete. I discovered a workaround, which I'll share.

Open a Link Asyncronously in a New Window with AngularJS - Approach 3

$
0
0
I was working on a client's AngularJS project. When the user clicked a button to open another application, we wanted to make a service call to log the request and make sure we redirected the user to the right place. Some users would see different versions of the other application, and the service call told us the proper variables to pass. Unfortunately, after we made the service call the link would not open. I started to research for more information as to what the problem may be. Basically, a browser won't open external pages if they aren't done in response to a user interaction such as clicking a button. The browser assumed user request was ended by the time our promise object resolved. This is how I solved the issue. By, the way, this is the third in the series about opening links through AngularJS. Check out the first and second.

The Setup

First, add Angular to your Application: Then, create an Angular Module and controller: angular.module('test',[]); angular.module('test').controller('someController',['$scope','$window','$q', function($scope,$window,$q){ }]); Three elements are injected into the controller. $scope is the common service used to communicate between the view and the controller. $window gives you an Angular reference to the browser's window object. We'll use $window to open the new page. Finally, $q is added. We are going to use $q to create a promise object to simulate an actual remote service call.

Open the new page

There are multiple steps that we took to create the new page. The new page must be open with user interaction, so let's create the buttons first:
This code contains two buttons; one that will successfully open the page and another that will not--as if the service call was rejected for reason. Both call the same onButtonClick method, passing in a Boolean value specifying whether the link should be open or not: Create the stub for the method: $scope.onButtonClick = function(openOrClose){ } The new window must be open in response to the click; so first open the window: var newWindow = $window.open('about:blank','myCustomWindowTitle'); This uses $window.open() to open the new window and it opens to a blank about page. Next, make the remote service call, in our case we simulate it using $q. Create the promise: var defer = $q.defer(); Write the success and failure functions: defer.promise.then(function(){ newWindow.location.href = 'https://www.jeffryhouser.com' }, function(){ newWindow.close(); }); The failure function will close the new window we created. The success function will change the location of the window, in essence opening the new page. Now, decide whether to resolve or reject the promise: if(openOrClose){ defer.resolve(); } else { defer.reject(); } The decision is made based on the value of the openOrClose argument passed into the onButtonClick() method. Load the app and you'll see something like this: A boring UI. Click the 'refuse' button and the service call is so quick and the window will close as quick as it would open. This is undesirable, but I don't know of another way. The user may see a blink. Click the open button, and you'll see this: The link to my blog will open in a new tab, based on my default browser settings. Play with the code here.

What is Next?

The final entry in this series will show you how to submit a form post after asynchronously making a call. That will be out next week.

Submit a Form Post Asyncronously to a New Window with AngularJS - Approach 4

$
0
0
I was working on a client's AngularJS project. When the user clicked a button to open another application, we wanted to make a service call to log the request and make sure we redirected the user to the right place. Some users would see different versions of the other application, and the service call told us the proper variables to pass to setup the secondary app. Unfortunately, after we made the service call the link would not open. I started to research for more information as to what the problem may be. A browser won't open external pages if they aren't done in response to a user interaction such as clicking a button. The browser assumed user request was ended by the time our service call ended and the promise object resolved. This is one solution we considered for the issue, which uses a form post to open the new link. By, the way, this is the fourth in the series about opening links through AngularJS. Check out the first and second, and third .

The Setup

First, add Angular to your Application: JQuery is also required for this approach: Then, create an Angular Module and controller: angular.module('test',[]); angular.module('test').controller('someController',['$scope','$window','$q', function($scope,$window,$q){ }]); Three elements are injected into the controller. $scope is the common service used to communicate between the view and the controller. $window gives you an Angular reference to the browser's window object. We'll use $window to open the new page. Finally, $q is added. We are going to use $q to create a promise object to simulate an actual remote service call.

Open the new page

There are multiple steps that we took to create the new page. The new page must be open with user interaction, so let's create the buttons first:
This code contains two buttons; one that will successfully open the page and another that will not--as if the service call was rejected for reason. Both call the same onButtonClick method, passing in a Boolean value specifying whether the link should be open or not. Remember to create the form:
An ID is specified, and we'll use this to get a hook to the form inside the angular code. Target is specified, and tells the form to submit to the window named 'myNewWindow'. The form action will post go back to my blog--however you could post it anywhere you want, even passing variables for processing. Create the stub for the click method: $scope.onButtonClick = function(openOrClose){ } The new window must be open in response to the click; so first open the window: var newWindow = $window.open('about:blank','myCustomWindowTitle'); This uses $window.open() to open the new window and it opens to a blank about page. Next, make the remote service call, in our case we simulate it using $q. Create the promise: var defer = $q.defer(); Next, get a link to the form tag: var form = angular.element('#myForm') The angular.element is used to get a handle to the form based on the form's ID. This uses JQuery under the hood, but did not work w/ the JQuery lite that is part of AngularJS, so that is why we had to use the full Jquery library earlier. Write the success and failure functions: defer.promise.then(function(){ form.submit(); }, function(){ newWindow.close(); }); The failure function will close the new window we created. The success function will submit the form to the new window we just opened. Now, decide whether to resolve or reject the promise: if(openOrClose){ defer.resolve(); } else { defer.reject(); } The decision is made based on the value of the openOrClose argument passed into the onButtonClick() method. Load the app and you'll see something like this: A boring UI. Click the 'refuse' button and the service call is so quick and the window will close as quick as it would open. The user may see a blink, or anomaly in the UI. This is undesirable, but I don't know of another way. Click the open button, and you'll see this: The link to my blog will open in a new tab, based on my default browser settings. Play with the code here.

Final Thoughts

This was an interesting experiment, and it suited my client's need at the time. I always have caution about opening and controlling third party windows on the client's browser; because I don't want to build apps that overstep their bounds.

Why doesn't Flex Remoting work with ColdFusion 10 and Apache Web Server?

$
0
0
I'm doing some maintenance on an AIR application with a ColdFusion backend. For testing purposes, I installed a brand new copy of ColdFusion 10 and Apache Web Server 2.2. My first step was to test this new setup the Flex Remoting connection between ColdFusion and Flex. It was borked! The flex2remoting URL would return a 404. What was wrong? I do not remember having problems in the past. ColdFusion 10 introduced a new version of Flex Remoting, so maybe that was somehow the cause. There are a few people complaining about errors they've encountered. I tried all the fixes. First, I tried tweaking ColdFusion's urlworkermap.properties file, as described by my good friend Joseph. That didn't work for me. I found another suggestion which recommended commenting out some lines of ColdFusion's web.xml file. No luck there either. I went over all of ColdFusion's Flex Remoting Configs in an attempt to find something amiss, no luck. I started grasping at straws and experimenting. I know that in IIS, there is a virtual directory called Jakarta which is a Java Mapping and helps Flex Remoting, among other things run. Does Apache have something similar and could the setup be wrong? Apparently the answer is yes! Open up the mod_jk.conf file. It was created when you used the ColdFusion Web Server Configuration Tool to configure the Apache web server. There are a bunch of 'jk' properties: LoadModule jk_module "C:\ColdFusion10\config\wsconfig\1\mod_jk.so" JkWorkersFile "C:\ColdFusion10\config\wsconfig\1\workers.properties" JkMountFile "C:\ColdFusion10\config\wsconfig\1\uriworkermap.properties" As best I can tell this is the Apache equivalent of the Jakarta mapping in IIS. I started researching the different options around the moduleloading. When using virtual hosts with Apache Web Server, the mappings do not trickle down. I added this command to my Apache config: JkMountCopy All And everything started working magically. There are reports of similar problems with CF11. It is frustrating that problems like this still exist.

Directories and SystemJS Config - Building Angular 2 Applications with Gulp - Part 1

$
0
0
I wrote an extended white paper on my Gulp process to compile Angular 2 TypeScript applications, and decided to turn some of it into a series of blog posts. The first part of this series will talk about the directory structure of the project, the initial setup, and SystemJS configuration. By the end of this series you'll have a good architecture for building Angular 2 applications with Gulp.

Directory Structure

You can find all the code for this series in our DotComIt GitHub Repository for project seeds. We structure our projects like this:
  • build: The directory where the compiled code is placed. The root will most contain the main index file.
    • com: Our compiled JavaScript code is put in a com directory, mimicking the package structure of a lot of Java package code. This may also include HTML Templates. For Angular 2 applications, I've seen this directory called 'app' in some uses
    • maps: Source Maps are placed in this directory, if they are generated.
    • js: JavaScript libraries are placed here, if any are required for the project. Some of these are copied over from node_modules, while others may be copied from the src directory.
  • node_modules: A directory that contains relevant modules installed by Node, such as Gulp, TypeScript, and the Angular libraries.
  • src: The directory where our source code goes. The root directory will contain the main index.html file, but not usually much else.
    • com: Our TypeScript code is put in a com directory, mimicking the package structure of a lot of Java package code.
    • js: JavaScript libraries are placed here, if any are required for the project. A default SystemJS Configuration is put in the source directory.
I am not going to examine a sample TypeScript application in detail as part of this series. The GitHub repository includes a simple Hello World application, which will suffice for our demonstration purposes.

Initial NodeJS Setup

Gulp runs on top of NodeJS, so you'll need that. After that, we need to create a package.json in the root directory of your project. Copy and paste this into the file: {"name": "TypeScriptAngular2Sample","version": "0.0.1","description": "TypeScript Angular 2 Sample for Article.","author": "Jeffry Houser","license": "ISC","dependencies": {"@angular/common": "~2.4.0","@angular/compiler": "~2.4.0","@angular/core": "~2.4.0","@angular/forms": "~2.4.0","@angular/http": "~2.4.0","@angular/platform-browser": "~2.4.0","@angular/platform-browser-dynamic": "~2.4.0","@angular/router": "~3.4.0","angular-in-memory-web-api": "~0.2.2","systemjs": "0.19.40","core-js": "^2.4.1","reflect-metadata": "^0.1.8","rxjs": "5.0.1","zone.js": "^0.7.4" },"devDependencies": {"gulp": "^3.9.1","typescript": "^2.1.5" },"repository": {} } This includes all the major Angular 2 libraries and dependencies in the dependency section. The devDependencies section includes Gulp and TypeScript. Install all this stuff with one command: npm install You'll see something like this: This creates the node_modules directory; and installs all the modules specified in the package.json, along with any related dependencies. This is the base we use for creating our build scripts. As we need Gulp plugins we'll install them individually in future installments.

SystemJS Configuration

Angular 2 uses a module loader system named SystemJS to give the browser require() functionality like you'd use on the server side with NodeJS. We need to provide a configuration to SystemJS so that it knows how to find our custom app code, and the required Angular libraries. I put this file in the src/js/systemJSConfig directory. Setup the file with an Immediately Invoked Function Express (IIFE): (function (global) { })(this); This is the JavaScript method to create a self-executing function. Inside the function, we want to configure SystemJS: System.config({ }); The config() method is used to configure the SystemJS library. It takes an object, which is currently empty. Add in a paths configuration: paths: {'js:': 'js/' }, This configuration object tells the library that the js path will point to the js directory. When we write build scripts, we'll put all the relevant Angular libraries in the JS sub-directory of our final build. Next, create a map configuration: map: { app: 'com','@angular/core': 'js:@angular/core/bundles/core.umd.js','@angular/common': 'js:@angular/common/bundles/common.umd.js','@angular/compiler': 'js:@angular/compiler/bundles/compiler.umd.js','@angular/platform-browser': 'js:@angular/platform-browser/bundles/platform-browser.umd.js','@angular/platform-browser-dynamic': 'js:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js','@angular/http': 'js:@angular/http/bundles/http.umd.js','@angular/router': 'js:@angular/router/bundles/router.umd.js','@angular/forms': 'js:@angular/forms/bundles/forms.umd.js','rxjs': 'js:rxjs','angular-in-memory-web-api': 'js:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' }, The map configuration tells the code 'when we reference 'x' in code; go look for this library. The main angular libraries are listed. Explanation of the Angular libraries are beyond the scope of this article. The important things to notice are that the js path is specified in the file location for most of the libraries. The second thing to notice is that the app map points to our com directory, where all our custom code is located. Next, specify the packages. A package is a collection of files that have shared functionality: packages: { app: { main: './dotComIt/sample/main/main.js', defaultExtension: 'js' }, rxjs: { defaultExtension: 'js' } } Two packages are specified. The first is app, which is our main application and custom code. It defines the main entry point, main.js--the name of the file that main.ts will be converted too. It also specifies the default extension of js. The second package specified is a package used by Angular, rxjs. I wanted to cover the SystemJS configuration as part of this article because it is specific to getting Angular to work, but has nothing to do with TypeScript or creating Index files required for the application.

Setup Node and install Angular Dependencies

What's Next

Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Linting TypeScript - Building Angular 2 Applications with Gulp - Part 2

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Check out Part 1 here. This section will build a Gulp task for Linting TypeScript. The lint tool is a syntax checker that looks for errors.

Install Dependencies

First, install a NodeJS Plugin, tslint and a gulp plugin, gulp-tslint. Run this code: npm install --save-dev tslint gulp-tslint You should see results like this: Once the install is complete, you're good to start creating your gulpfile.js

Create the Gulp Lint Task

If you don't already have one, create a file named gulpfile.js in the root directory of the project. Our first task to create is going to lint the TypeScript code. The first step is to import the gulp and gulp-tslint libraries: var gulp = require("gulp"); var tslint = require('gulp-tslint'); This will make them available for use within our gulp script. Next, I'm going to define the location of the typeScriptSource: var sourceRoot = "src/"; var typeScriptSource = [sourceRoot + "**/*.ts"]; This is split up into two variables. The first just points to the source directory and that will be used throughout our script. The second uses the sourceRoot to create a wildcard glob that will cover all existing type script files in the main directory. Now, create the gulp task to lint the TypeScript: gulp.task('tslint', function() { }); This is an empty task that does nothing. Use gulp.src() to tell gulp which items to process: return gulp.src(typeScriptSource) Then, run the tslint() task: .pipe(tslint({ formatter: 'prose' })) This will parse the TypeScript, and make a collection of any errors. Then, report the errors: .pipe(tslint.report()); That is the completed task. Before we run it, we'll need to configure it. Specific configuration options are beyond the scope of this article. Put this tslint.json file, in your root directory and you'll be fine. The file comes from the official Angular 2 Quickstart documentation. Run the task: gulp tslint You'll see something like this: No issues. What happens when there are issues? I removed a semi-colon and added some random characters to the main.ts file and reran the lint process: It correctly found the error. The lint process performs a syntax validation; it does not validate the code for accuracy of imports or other bugs; but those will be flagged as part of the compilation process which we'll tackle in part 3.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Compiling TypeScript - Building Angular 2 Applications with Gulp - Part 3

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Start with Part 1, and then read Part 2. This section will build a Gulp task for compiling TypeScript into JavaScript.

Install Dependencies

First, install a gulp plugin, gulp-typescript. Run this code: npm install --save-dev gulp-typescript You should see results like this: This makes the gulp-typescript plugin available for use in our gulpfile.js.

Compile TypeScript to JavaScript

Before we start the compilation task, let's create some variables. First, the destination path for the output files: var destinationPath = 'build'; I always put the processed files in a directory called build. Then, create an instance of the gulp-typescript module: var tsc = require("gulp-typescript"); Use the gulp-typescript library to create a project: var tsProject = tsc.createProject("tsconfig.json"); This refers to an external tsconfig.json file. I don't want to expand on the full details of the config file; but there are two important things I want to draw attention to. The first is a few items in the compilerOptions:"compilerOptions": {"target": "es5","module": "commonjs", } The module type is 'commonjs' which is the module type used behind the scenes by Angular 2. The second important thing here is the target, es5. This stands for EcmaScript 5; JavaScript is an implementation of and most browsers support. The second important item in the config file is: "exclude": ["node_modules" ] The exclude option tells the type script project not to process files in the node_modules directory. In essence, it ignores all the Angular libraries installed via NodeJS. These libraries already come with compiled bundles. We'll deal with moving those later. Now, create a buildTS task: gulp.task("buildTS", ["tslint"], function() { }); This gulp task is named BuildTS. Before this task is run; the tslint task will execute. The tslint task was created in the previous part of this series. The main task first specifies the source: return gulp.src(typeScriptSource) It uses the same typeScriptSource variable that the tslint task used. Then, it adds the tsProject as a gulp pipe: .pipe(tsProject()) Finally, it specifies the destination path: .pipe(gulp.dest(destinationPath)); What the full script does is take all the TypeScript files in our source directory, run them through the gulp-typescript compiler, and save the output to a build directory. Run the script: gulp buildTS You'll see results similar to this: You can see from the output that both the tslint and buildTS process ran. No errors; so let's review the output.

Review Generated JavaScript Code

Look in your project directory and you'll see a brand new build directory: Each TypeScript file was turned into a JavaScript file. Let's examine the main.js file; as it is simple:"use strict"; var platform_browser_dynamic_1 = require("@angular/platform-browser-dynamic"); var app_module_1 = require("./app.module"); platform_browser_dynamic_1.platformBrowserDynamic().bootstrapModule(app_module_1.AppModule); The first thing you'll notice is that the JavaScript iteration replaces the import statements with require statements. You'll recognize the require statement from the NodeJS code we are writing. However, browsers don't inherently support that. This is here because of commonJS module creation was specified in the compiler options. The systemJS library allows require() to be used in the browser, and that is what Angular 2 uses. Beyond that, the JavaScript code is not all that different from the original TypeScript code. You can review the other two JS files and you'll find similar results.

What's Next

The first few articles of this series focused on TypeScript, but the full intent is to provide you with everything you need to build your own applications. The next in the series will focus on moving the JavaScript Libraries and HTML files from their install locations to the build directory.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Copying Static Files - Building Angular 2 Applications with Gulp - Part 4

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Start with Part 1, and then read Part 2, and Part 3. This entry will show you how to use Gulp to copy files. We'll copy the Angular libraries from the node_modules directory to the build directory, HTML files from the source directory to the build directory, and JavaScript files from the source/js directory to the build directory. These can be done using Gulp directly, you will not need to install additional plugins.

Copy the Angular Libraries

There are a lot of required Angular libraries and we don't want to write a script for each one. Thankfully, we don't have to, as we can specify an array of glob directories to cover all the relevant libraries: var angularLibraries = ['core-js/client/shim.min.js','zone.js/dist/**','reflect-metadata/Reflect.js','systemjs/dist/system.src.js','@angular/**/bundles/**','rxjs/**/*.js','angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' ] This covers all the JavaScript libraries required for Angular 2 applications such as zonejs and the shim library. It includes the Angular library bundles and the SystemJS library. The use of globs wildcard match files make it easy to find the relevant files needed. Next, we'll need a destination path to put the libraries: var destinationPathForJSLibraries = destinationPath + '/js'; I put all the external libraries in the 'js' directory as an organizational tactic. Now the actual task: gulp.task('copyAngularLibraries', function () { gulp.src(angularLibraries, {cwd: "node_modules/**"}) .pipe(gulp.dest(destinationPathForJSLibraries)); }); The task is named copyAngularLibraries. It is simple. It takes the array as a source. The cwd flag with the src specifies the current working directory, meaning all the libraries are located in node_modules. Then the task specifies the destination path. This will copy all the required angular files from the node_modules directory to the build/js directory. Run this task: gulp copyAngularLibraries You should see results like this: You should see an updated build directory: This is the first step.

Copy JS Libraries

If we have any JavaScript libraries put in the src/js folder we want to copy those to the build directory. The SystemJS Configuration file is one example. The same approach from above can be used, but is even simpler since there are less directories to deal with. First, create a glob array to find the JS files: var javaScriptLibraries = [sourceRoot + 'js/**/*.js']; Then create the task: gulp.task('copyJSLibraries', function () { gulp.src(javaScriptLibraries) .pipe(gulp.dest(destinationPathForJSLibraries)); }); This is a simple task that specifies the input source and the destination. It uses the same destination variable that was used for the Angular libraries in the previous section. Run the task: gulp copyJSLibraries You'll see this: Check the build directory and see the final file: The systemjs.config.js file was successfully copied from the src directory to the build directory.

Copy HTML Files

If you're using my Hello World app, it only has a single HTML file. It is likely that a full app will have more, especially if you use external HTML templates. I want to write a task copy all HTML Files from the src directory to the build directory. First, create a glob array to find the HTML files: var htmlSource = [sourceRoot + '**/*.html']; Then create the task: gulp.task('copyHTML', function () { return gulp.src(htmlSource) .pipe(gulp.dest(destinationPath)); }); This is a simple task that specifies the input source and the destination. It uses the same destination variable that was used for the Angular libraries in the previous two sections. It could be easily combined with the copyJSLibraries task, however I prefer to keep them separate for logistical reasons, since HTML files and JS files are different. Run the task: gulp copyHTML You'll see this: Check the build directory and see the final file: The index.html file was successfully copied from the root of the src folder to the root of the build directory. If you're using our sample Hello World application, a side effect of finishing this part is that your app will run in the browser: Not an interesting app, but proof our scripts work.

What's Next?

Even though we have a workable application now; there is still a lot we can do as part of our build scripts. In the next article in this series I'll show you how to create source maps. Later articles will cover JavaScript minificiation, how to compile code on the fly, and various different build techniques. You can get all this information right now by signing up for my newsletter using the form below, so do it and be on your way to become an expert Angular 2 Developer.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Creating Source Maps - Building Angular 2 Applications with Gulp - Part 5

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Start with Part 1, and then read Part 2, Part 3, and Part 4. This entry will teach you about Source Maps. With a TypeScript application, the code running in the browser is not the same as the code we wrote. It has been translated from one language, TypeScript, to another, JavaScript. When an error occurs how can we debug it? The answer is to create a source map. We can look at the source maps in the browser, to learn where we went wrong in the TypeScript code. The usual browser debugging tools, such as break points and watches, will work with source maps.

Install Source Map Plugin

Gulp has a source map plugin that allows us to easily create source maps. First install it: npm install --save-dev gulp-sourcemaps You'll see something like this: The plugin is now available to use within your gulp script.

Generate Source Maps

The first step is to load the source map plugin in your gulpfile.js: var sourcemaps = require('gulp-sourcemaps'); I am going to add a configuration variable for the location of the maps: var mapPath = 'maps'; I like to keep my maps separate from the generated code, but you do not have to specify a separate path if you do not prefer. Now, you can add the source map generation to the buildTS task. First, here is the task unedited: gulp.task("buildTS", ["tslint"], function() { return gulp.src(typeScriptSource) .pipe(tsProject()) .pipe(gulp.dest(destinationPath)); }); There are two steps to the source map generation. The first is to initialize the maps. We want to do this as close to the front of the chain as possible so that the map code can keep track of all the changes. Then we want to save the maps. We want to do this as close to the end of the chain as possible. This is the modified task body: return gulp.src(typeScriptSource) .pipe(sourcemaps.init()) .pipe(tsProject()) .pipe(sourcemaps.write(mapPath)) .pipe(gulp.dest(destinationPath)); The second pipe calls the init() method on the source map module. The second to last pipe saves the source maps with the write() method. Run the task: gulp buildTS You'll see this: Check the build directory: A source map was generated for each TypeScript source file. Success! Open up the app in a browser, and bring up the source in your dev tools: The chrome dev tools let us drill down into the TypeScript files, just as we had written them. They support watches and breakpoints, just as if the browser was running them directly. This is a very useful debug tool.

What's Next?

Te next article in this series I'll show you how to minimize the JavaScript code. Future articles will cover compiling code on the fly, and various different build techniques. You can get all this information right now by signing up for my newsletter using the form below. Do it to help you become a better Angular 2 Developer.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Check out my Angular 4 Book Kickstarter

$
0
0
I launched a Kickstarter for an Angular 4 book. Check it out here. There are a lot of details on the Kickstarter page. I kept the price low, but that means I need a lot of backers. The full book will be released under a Creative Commons License upon completion. This is your chance to help me create a great tutorial resource for the Angular community. What are you waiting for? Back now!

Thoughts on Adobe's ColdFusion Roadshow in New York

$
0
0
Adobe had a ColdFusion Roadshow Event in New York last week and I attended. I had a moment between two projects, so I thought why not take a trip to the city and network a bit? I wanted to formalize some of my thoughts about the event in no particular order. I was personally invited by Kishore Balakrishnan, the Senior Product Marketing Manager for Adobe ColdFusion. I'm not sure why I got the invite. My software development company has been an Adobe partner in the past, but not in ages. I was part of the Adobe ACP program in the past, but am not currently a member. It could be that they just emailed everyone who had downloaded CF from their website. I'm not sure, but I also didn't ask. The even was sparsely attended, maybe 20 people tops. I did meet someone from one town over who is running a medical startup that plans to use ColdFusion. That was a treat. The event started with a presentation by Elishia Dvorak about What's new in ColdFusion 2016. My big takeaway was that they had built an API Manager tool. This is a way to manage REST APIs, whether they are built in CF or something else. This is a completely separate product from ColdFusion. I sounded to me like a proxy or entry point that could be used to manager other APIs, load balancing, documentation, and user management. I can see a benefit if you're a big company moving to a reusable service based architecture to power your organization, or a company whose business is providing services to external clients or vendors. It was an interesting approach. Since I've focused on UI Programming I don't know what else is out there that does that. If you need something like this, and are already a ColdFusion customer, it is worth checking out. Everything else new to CF was related to performance, security, and stability. Apparently when Adobe talks to customers there are the three areas of focus. I'm not surprised, though. ColdFusion is a mature technology that does what I need it to do. What is left to add? I've had trouble answering that question for 10 years. Then Kishnore got up to present about Tackling Future Challenges using ColdFusion. He started by talking about how ColdFusion success. Apparently ColdFusion is thriving. They said that each release doubles the sales of the previous release. I'm a bit surprised by the numbers. The next version of ColdFusion will be released in 2018, the only feature I can recall was a revamped version of CFScript which will offer more OO Features. And of course, more stability, better performance, and better security. All good things, but not the whiz bangy features to make new people interested. Since ColdFusion is doubling it's sales with each release that means there must be a huge demand, right? Nope! The two biggest complaints from the audience were the inability to find CF Developers and the inability to find CF Jobs. I hope those two networked with each other. My impression is that the ones who can't find CF Developers are you for beginners. The bulk of CF Devs have lots of experience with it, and no new blood is coming into the fold. Kishnore suggested that CF is easy to train people in. I agree. However, another attendee complained that it is hard to book people for CF Training courses from major training centers. The course always gets cancelled last minute because not enough people signed up. That is troublesome and won't help train up a new breed of devs. The topic of IDEs came up. A lot of people complained about CF Builder, how it is a mess, but and how they still use Dreamweaver. I have to admit this surprised me to find people are using Dreamweaver for coding? I admit that Eclipse, which is the base of CF Builder, takes a learning curve. For simple code hinting, IntelliJ has addressed my needs well. It is also worth nothing that CF Builder is now included with the license cost of CF. That's a nice touch. The topic of Rapid Application Development came up, and the attendees agreed that CF is RAD. I agree, especially when compared to Java. However, a lot of attendees said nothing can beat CF. I'm not sure that is still the case. One big benefit to CF being a RAD language is that it is loosely typed. However, a lot of server platforms offer that today. I was left with the impression that a lot of attendees had not played with more current tech. I do expect that you'll be more effective when dealing with a tech you've worked with for 20 years than you will be with something you just learned. But, once up the learning curve of new technology I'm not sure CF has the lead many championed. I worry that CFs push to add more Object Oriented features may hinder CF's RAD ability. With such high sales numbers, I'm a bit surprised that they couldn't get a bigger crowd in NYC. My perception is that CF has big usage in government, but it seems all but abandoned in the commercial markets I usually work in. Those are some random thoughts on the experience. Primarily I focus on UI technologies these days, but still have a few CF clients and every now and then. I'm glad I could fit the visit into my schedule. I'm glad CF is still around and kicking.

Minimizing the JavaScript Code - Building Angular 2 Applications with Gulp - Part 6

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Start with Part 1, and then read Part 2, Part 3, Part 4, and UglifyJS. An important aspect of modern HTML5 development is to make your JavaScript files as small and optimized as possible. The minification process shortens variable names, removes whitespace, and deletes comments. It can perform other optimizations too. The purpose is to provide a smaller download to the end user. The process can, sometimes, be significantly especially with larger applications. UglifyJS is my preferred minimizer, so we'll use that.

Install gulp-uglify

The first step is to install the gulp-uglify module. Run this command: npm install --save-dev gulp-uglify You'll see feedback like this: We are ready to use Uglify in our script.

Modify Gulp Script

First, load the gulp-uglify script in the gulpfile.js: var uglify = require('gulp-uglify'); ] Now, jump to the buildTS task. Here it is in the current state: gulp.task("buildTS", ["tslint"], function() { return gulp.src(typeScriptSource) .pipe(sourcemaps.init()) .pipe(tsProject()) .pipe(sourcemaps.write(mapPath)) .pipe(gulp.dest(destinationPath)); }); We want to run Uglify before the source map is written, but after the TypeScript is converted. Add a single line, like this: .pipe(uglify()) The line should be placed in the script before the source maps are written: return gulp.src(typeScriptSource) .pipe(sourcemaps.init()) .pipe(tsProject()) .pipe(uglify()) .pipe(sourcemaps.write(mapPath)) .pipe(gulp.dest(destinationPath)); The pipe() after tsProject() calls the uglify() method. We could configure the Uglify Script with various options, but for the purposes of this sample I used the default setup.

Review the Minimized Code

Run the updated script: gulp buildTS See it run: The directory structure will not have changed, but the contents of the custom JS files have. Assuming you're using our default hello world application, take a look at the app.module.js:"use strict";var __decorate=this&&this.__decorate||function(e,o,r,t){var p,n=arguments.length,c=n<3?o:null===t?t=Object.getOwnPropertyDescriptor(o,r):t;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,o,r,t);else for(var a=e.length-1;a>=0;a--)(p=e[a])&&(c=(n<3?p(c):n>3?p(o,r,c):p(o,r))||c);return n>3&&c&&Object.defineProperty(o,r,c),c},core_1=require("@angular/core"),platform_browser_1=require("@angular/platform-browser"),app_component_1=require("./app.component"),AppModule=function(){function e(){}return e}();AppModule=__decorate([core_1.NgModule({imports:[platform_browser_1.BrowserModule],declarations:[app_component_1.AppComponent],bootstrap:[app_component_1.AppComponent]})],AppModule),exports.AppModule=AppModule; This is a minimized version of the translated TypeScript code. It includes some SystemJS configuration that we didn't write manually--that was added by the TypeScript compilation. If you look closely, you see a lot of the function arguments are changed into single character values. White space and line breaks are removed. Other optimizations can be made by the Uglify library, such as variable definition optimizations. Such things are not present in the existing code. Run the final code in the browser, and you'll find it still runs as expected, and the source maps still work.

What's Next

The next few article in this series will talk about different build techniques, and some tasks I write to handle different options. The final article of this series will show you how to build a script that will recompile your code as changes are made on the fly. All the information is already available, so sign up for our newsletter to start reading right away.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Creating a Simple Build Task - Building Angular 2 Applications with Gulp - Part 7

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Start with Part 1, and then read Part 2, Part 3, Part 4, Part 6. In previous parts of this series, we created a lot of different build tasks. One for validating the TypeScript, one for compiling the TypeScript, and a few tasks for copying JavaScript and HTML files. What if we want to run them all in one command? This article will show you how. It is pretty simple to create a Gulp task which will run multiple other Gulp tasks: gulp.task("build", ['buildTS', 'copyJSLibraries','copyAngularLibraries','copyHTML']); This creates a new Gulp task named build. The argument to the task is an array and each element of the array is a string which represents another Gulp task. We saw this approach with buildTS task built in Part 3. In that part, the tslint task was executed as part of the buildTS task. In this case, the build task does not have its own functionality it just combines together the existing tasks. Run this task: gulp build You'll see something like this: All the tasks are run, creating a build.

What's Next?

The next part of this series will show you how to delete everything in the build directory before creating the build. I call this approach a clean build. All the information is already available, so sign up for our newsletter to start reading right away.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.

Creating a Clean Build - Building Angular 2 Applications with Gulp - Part 8

$
0
0
This is part of an ongoing series about building Angular 2 TypeScript applications with Gulp. Start with Part 1, and then read Part 2, Part 3, Part 4, Part 6, and Part 7. This part of the series will show you how to delete the build directory and produce something that I call a clean build. This is important when refactoring code, which may leave remnants of old files in the build directory.

Delete the Build Directory

To delete a directory, we can use the NodeJS Plugin, del. This isn't a Gulp plugin, but can be wrapped in a gulp task. First, install it: npm install --save-dev del You'll see the install screen, like this: Next, you can load the del library inside your gulpfile.js: var del = require('del'); Create a glob array with everything that needs to be deleted: var deletePath = [destinationPath + '/**'] The destinationPath variable is used, with a wild card after it. This tells the del task to delete everything. Next, create the task: gulp.task('clean', function () { return del(deletePath); }); The task is named clean. It calls the del() module with the deletePath value. Run the task: gulp clean You'll see this: Check your project directory: The build directory is noticeably absent, which is exactly what we want.

Run Clean, then Build

Let's combine the clean task with the build path. To do that we'll want to run the two tasks in sequence, as we don't want the clean task to delete files the build task is creating. To do that we'll use a gulp plugin namedrun-sequence. Install the plugin: npm install --save-dev run-sequence You'll see this: With it installed, we can create an instance of it in the gulpfile.js: var runSequence = require('run-sequence'); Then, create the task: gulp.task('cleanBuild', function () { runSequence('clean', 'build'); }); I named the gulp task, cleanBuild. It uses the runSequence library to run the clean task--which deletes everything in the build directory, and the build task--which will create a fresh build. Run the task: gulp cleanBuild You'll see something like this: You see that the clean task is run first; and after it is finished the build tasks start. This will delete the build directory and all other relevant files, and then re-generate using the other tasks we wrote about earlier in this chapter.

What's Next?

The next part of this series will create what I call a production build. The final part will show you how to watch directories for changes while the code is in development. Sign up to our mailing list to get an expanded version of this series.
Get our expanded 38-page version: Building Angular 2 Applications with Gulp.
Viewing all 497 articles
Browse latest View live