Subscribe: Jeffry Houser's Blog
http://www.jeffryhouser.com/rss.cfm?mode=full
Added By: Feedage Forager Feedage Grade B rated
Language: English
Tags:
angular  bootstrap  code  component  create  echo  import  interface  part part  part  popup  string  testing  typescript 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Jeffry Houser's Blog

Jeffry Houser's Blog



Jeffry Houser's Blog



Published: Thu, 14 Dec 2017 11:56:27 -0700

Last Build Date: Wed, 06 Dec 2017 09:00:00 -0700

 



How do I Fix Uncaught (in promise): Error: StaticInjectorError[] in Angular 5?

Wed, 06 Dec 2017 09:00:00 -0700

I've updated my Learn With Programming Books to Angular 5. Angular changed their versioning structure, so Angular 5 is more like Angular 2.2 than a complete update. Unfortunately, the upgrade was not seamless and this error drove me insane. Everything I thought I'd fix it, it would crop back up: ERROR Error: Uncaught (in promise): Error: StaticInjectorError[UserModel]: StaticInjectorError[UserModel]: NullInjectorError: No provider for UserModel! Error: NullInjectorError: No provider for UserModel! at _NullInjector.get (injector:31) [angular] etc.. etc.. The error looked like this: The underlying cause of this error is that Angular 5 changed how they create providers moving from a reflect based injector to a static injector. This removes the need for the reflect polyfill that is used in Angular applications. Without digging deep into Angular code I can't explain better, all I knew was that I had the error and needed a resolution. If you search, you'll find a lot of write ups on this, but it was trial and error that solved the issue for me. Here are two things to look at that helped me solve the issue. Check Your TypeScript Version Angular 5 requires TypeScript 2.3 or later, so make sure that your build scripts have the proper version installed. I'm using TypeScript 2.4, and your package.json should look something like this: "typescript": "^2.4.0", If you're using the Angular CLI this shouldn't be an issue, as it should already have the proper versions set up. Check Case Sensitivity of Classes and Imports This is the one that drove me nuts. About half of my development standards come from 'legacy' applications, and the rule of thumb used to be to name class files in proper case, so UserModel.ts instead of usermodel.ts. However, it appears--and I'm not sure why--that Angular has a problem with the mixed case of the class imports. If I was importing two classes from the same directory and setting them up as providers in the main application, I would get this error. This would cause errors: import {UserModel} from "../model/UserModel"; import {TaskModel} from "../model/TaskModel"; @NgModule({ // other stuff here providers : [ UserModel, TaskModel] }) This would not: import {UserModel} from "../model/usermodel"; import {TaskModel} from "../model/taskmodel"; @NgModule({ // other stuff here providers : [ UserModel, TaskModel] }) Even if I changed nothing with the actual import files. By putting all the class imports in lower case, I was able to avoid the issue. That was until I set up unit tests using karma-typescript. Karma TypeScript spit up on the imports with incorrect case. I ended up putting the file names in all lower case so they would be fine with my Angular Build Scripts and with the Karma TypeScript tests. Final Thoughts I thought the upgrade, and book update, would be a couple of days, but took me a full week. So, go check out my Angular 5 books, or at least get on my mailing list using the form below. Keep up to date by reading DotComIt's Monthly Technical Newsletter First Name Email Address * [...]



Enable Double Opt In for MailChimp APIs

Tue, 28 Nov 2017 09:00:00 -0700

I was using some very old code to power the "Join my mailing list" boxes on my various sites. It stopped working perfectly a while back and I've been rewriting the code to use the MailChimp 3.0 APIs instead of the MailChimp 1.3 API. Setting it up was a lot easier than I expected. The first thing I noticed after rolling it out, however, was that users were being subscribed immediately to the mailing list without using the double opt in. Obviously this is a nightmare, despite the new MailChimp defaults. You do not ever want use single opt in. I was using this API to add new members to a list. I pulled directly from a sample in their docs: { "email_address": "urist.mcvankab@freddiesjokes.com", "status": "subscribed", "merge_fields": { "FNAME": "Urist", "LNAME": "McVankab" } } The reason double opt in was being bypassed was because of the status of the user. I put the status as subscribed, which is a way to tell mailchimp they already double opted in. To fix my problem, I needed to change to that pending, something like this: { "email_address": "urist.mcvankab@freddiesjokes.com", "status": "pending", "merge_fields": { "FNAME": "Urist", "LNAME": "McVankab" } } The API assumes that subscribed means they are in, but pending means they still need to approve the sign up. More details on the user statuses are on the same page with information about managing subscribers, but sadly not mentioned on the API Doc page. I'm surprised how easy it was to set up the API Integration, so Kudos to MailChimp for that. I wish the API Docs were more detailed on the meaning and values of certain fields.



General Life Lessons

Tue, 21 Nov 2017 09:00:00 -0700

I've recently started to watch reddit on a regular basis. Generally the conversation and information I Get there is a lot more interesting than Facebook. In the Computer Science Career Questions subreddit. The subreddit seems to be made up of primarily students or people on their first two years of the job. Someone asked me for some valuable life lessons, and my response has been getting way more upvotes than I'm used to. I thought I'd make an interesting non-technical blog post. Here are some of the advice I'd give to people just starting out their careers. In no particular order: Don't Quit: Keep your current job until you have a new one lined up. There is some psychology involved. When people hear you are happily employed they experience the thrill of the chase. When they don't have a job they think there may be something wrong with you. Ashton Kutcher has some great words on this sentiment. Know Your Priorities: I spent the past 18 years as a consultant running my own biz. Most people view me as a successful businessman, but I've had a lot of missteps. I would probably be a lot richer going the 'traditional' route and switched jobs every 3-5 years. I have always valued flexibility over money. What are your values and how does that apply to your career choices? Don't be Afraid to Fail: I've been involved in ~15 different ventures of varying success over the past 30 years. Hugely satisfying even if not always profitable. Go for it! Control your Spending: Research the FIRE movement. FIRE stands for Financial Independence, Retire Early. The gist is keep your expenses low, invest what is left over and soon the investment return will be more than your expenses, eliminating the need to have a job. I'm not FIRE yet, but keeping expenses low is part of what kept me in business during various failures. Corollary: Max out your tax deductible retirement contributions. Mr Money Moustache has become an unofficial spokesperson for the for the FIRE movement. Learn how to Communicate: Take a writing course or public speaking course. This is probably more important to your future job prospects than anything technology related. Taking a Dale Carnegie course is recommended. Keep in Touch: Reach out to friends and colleagues at least once a year to say "Howdy, let's do lunch." You never know where your next opportunity will come from, and even if nothing comes of it it's good to keep connections with people. Technology works on a Cycle: Everything old becomes new again. Lotus Notes was a 'NoSQL' database in the 80s/90s that worked on similar client-server principles that the web works on today. The VAX machine my college uses had dumb terminals with a server doing the heavy work--not unlike a Chromebook using Google Services. Programming languages are similar. It is often hilarious to me see "all ya kids" trumpeting these brand new concepts from 20 or 30 years ago. Corollary: Businesses also work on a cycle and decentralize their infrastructure to increase efficiency and remove bottlenecks and centralize to increase company wide cohesiveness. Be Niche: I find there are more opportunities being a specialist than a generalist. But, don't be afraid to change that specialty, though. A decade ago I was one of the most prominent Flex/Flash Developers in the world, but that technology is less important today. Two decades ago I was a ColdFusion expert, a tech that is also less relevant today. Both of these skills still get me client work, though. Own You: A lot of the things you'll build for employers will be owned by them. Try to own as much as you as you can. Always be aware of the rights you're giving up. I recently turned down a book deal with a major tech publisher because they would not explicitly say that my self published writings were non-competitive. Read Contracts: Read something before you sign it. Ask for a copy for your records. Hopefully you find this interesting. I'll be back next week with something more technical. ;) [...]



Testing a Bootstrap Popup with Angular - Part 2

Wed, 15 Nov 2017 10:00:00 -0700

This is the second half of my article on testing a Bootstrap popup. Before reading this, you should read my post about creating a popup with Angular and Bootstrap, and the one about testing the popup component. This post will focus on testing the code that creates the popup. Review Code In my test sample, the code to create the popup is in the app.component.ts file. This is it: onModalRequest():void { const modalRef = this.modalService.open(PopupComponent ); modalRef.result.then((result) => { console.log(result); console.log('closed'); }).catch( (result) => { console.log(result); console.log('cancelling'); }); } This is triggered by button click in the view. Create an instance of the modal using the modalService, which is an instance of the NgbModal. It saves that instance in another variable, modalRef. The modalRef.result is a promise, and we can use that to run code whenever the modal is closed or dismissed. The promise then() method represents a successful closure of the modal. The promise catch() method represents a dismissal. Since this is a test app, the close and dismiss methods don't do anything other than log items out to the console, but a real app may save data or update a view. We're going to write a few tests against this code. The first will just verify that the modal opened. Then we'll open and close the modal, verifying that the result function was called. Then we'll open and dismiss the modal, verifying that the catch function was called. Write the Tests I put my tests in a file named app.component.test.ts. As always, we'll start with the imports. These are the Angular testing imports and the ng-bootstrap imports: import {async, TestBed,ComponentFixture} from '@angular/core/testing'; import {NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; Now, load our custom components: import {AppComponent} from "../../../../../src/com/dotComIt/learnWith/main/app.component"; import {PopupComponent} from "../../../../../src/com/dotComIt/learnWith/views/popup/popup.component"; We import the AppComponent, which contains the code we'll be testing and the PopupComponent which contains the code we'll be testing. Now, create a describe function to create the set of unit tests: describe('AppComponent', function () { }); Next, create a bunch of variables inside the describe: let fixture: ComponentFixture; let appComponent: AppComponent; let modalService: NgbModal; let modalRef: NgbModalRef; The ComponentFixture is used to create an instance of a component so you can access all properties, methods, and DOM elements of its HTML template. The appComponent is an instance of the component's class. The modalService and modalRef relate to the popup window that will be created. Here is a beforeEach(): beforeEach(async(() => { TestBed.compileComponents().then(() => { modalService = TestBed.get(NgbModal); modalRef = modalService.open(PopupComponent); fixture = TestBed.createComponent(AppComponent); appComponent = fixture.componentInstance; spyOn(modalService, "open").and.returnValue(modalRef); spyOn(console,'log').and.callThrough(); }); })); It compiles the components on the TestBed. Remember the TestBed was configured in a base.test.ts file, which our scripts know to compile first. After the components are compiled, we get the modalService and create a modalRef by opening the component. The fixture instance of the AppComponent is stored as is its componentInstance. Finally the beforeEach() creates two spyOn() methods. It looks at the open method of the modalService, and tells it to return the modalRef as a specific value. Then it spys on the console.log() method. Normally I would try to avoid spying on this, but since no real functionality exists inside our app this is the best way to determine if the close or dismiss methods will run on the modal popup. Let's start off with an[...]



Testing a Bootstrap Popup with Angular - Part 1

Wed, 08 Nov 2017 10:00:00 -0700

Last week's post showed you how to create a popup using Angular 4 and ng-bootstrap. This week, I'll show you how to test it. This post covers testing the popup component. Next week I'll test creating the popup. Get a Testing Framework You'll need a testing framework. I have my own scripts based on Karma, Jasmine, and karma-typescript. I write about this in full details in the companion book to my Angular 4 book series. You could also use the Angular CLI or scripts of your own choosing. Specifics of the setup is beyond the scope of this article, because I want to focus on the tesing technique. Configure the Test Module Angular includes a testing construct called TestBed. This is a module created for testing other modules and is considered the foundation of all Angular tests. We're going to create a base.test.ts file to set up the TestBed to parallel the main application. This will parallel the main application from our source app. It doesn't matter where you create the base.test.ts file as long as it is loaded by your testing code, and your apps main module is ignored. I place it in the root of a testing directory. When the app runs in a browser, the index loads a shim library and a ZoneJS library that are required by Angular. But the tests are not run in a browser, so we need to import these scripts manually, like this: import "core-js" import "zone/dist/zone"; import "zone/dist/long-stack-trace-zone"; import "zone/dist/proxy"; import "zone/dist/sync-test"; import "zone/dist/jasmine-patch"; import "zone/dist/async-test"; import "zone/dist/fake-async-test"; This will prevent a lot of confused errors about uncaught reflect-metadata and class decorators. Now we need to import the Angular specific testing modules: import { TestBed } from "@angular/core/testing"; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing"; This imports the TestBed which is the testing module. It also imports BrowserDynamicTestingModule and platformBrowserDynamicTesting. These are used to parallel the platformBrowserDynamic class which loads the initial application. With these imported we can immediately initialize the TestBed: TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); Now import the BrowserModule which is the ng module for the browser, and the NgbModule, which contains the ng-bootstrap libraries: import { BrowserModule } from '@angular/platform-browser'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; Now, import the custom components from our demo: import { AppComponent } from '../src/com/dotComIt/learnWith/main/app.component'; import { PopupComponent } from '../src/com/dotComIt/learnWith/views/popup/popup.component'; Now, configure the TestBed: beforeEach(() => { TestBed.configureTestingModule({ imports : [BrowserModule, NgbModule.forRoot()], declarations: [ AppComponent, PopupComponent ] }).overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [ PopupComponent ] } }) }); The first thing to notice is that I put the TestBed configuration in a beforeEach() function. What is beforeEach()? It is a special function that is part of the Jasmine testing framework. The function allows you to run code before the tests are executed. We use it to create and configure the testing module which will be used by most of our other unit tests. You can have multiple beforeEach() functions if needed, but here we only need one. The configureTestingModule() accepts a configuration object which sets up imports for other modules and declarations for components. This is all like the @NgModule metadata in our main application. The configureTestingModule() does not support entryComponents, unfortunately. We used the entryComponents metadata to set up the component that ng-bootstrap will use to creat[...]



Creating a Popup with Bootstrap and Angular

Thu, 02 Nov 2017 09:00:00 -0700

How does one create a modal window with Bootstrap and Angular 4? This post will show you how. The Setup First, we need a generic app. You can use the Angular CLI, or my own seed project to create one. They are all going to give you a similar code base, although the directory structure is a bit different. I'm going to continue using the seed project I created, so you may have to make minor tweaks to the setup for other options. Next be sure to install ng-bootstrap using Node: npm install --save @ng-bootstrap/ng-bootstrap If using the Angular Quickstart or the DotComIt seed project, you'll have to tell SystemJS how to find it. Open the SystemJS config and add this to the map property: '@ng-bootstrap/ng-bootstrap': 'js:@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap' The seed project scripts will need to copy the Bootstrap libraries into the build directory. Just find the angularLibraries array in the config file and add the new entry: '@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap' Now open up the index.html file and add the bootstrap CSS: Create the Pop Component Now, let's create a component that will be the popup. Create a file named popup.component.ts in src/com/dotComIt/learnWith/views/popup. First, add your imports: import {Component} from '@angular/core'; import {NgbActiveModal} from "@ng-bootstrap/ng-bootstrap"; This imports the Component so we can create this class as a component. It also imports the NgbActiveModal. This will allow us to close the modal. Create the @Component metadata: @Component({ selector: 'Popup', templateUrl : './com/dotComIt/learnWith/views/popup/popup.component.html', styleUrls: [ './com/dotComIt/learnWith/views/popup/popup.component.css' ] }) I named the selector Popup, although we won't need that. I also specified an external HTML template and an external CSS file. I do this as a matter of habit. The CSS file can be empty. We'll roll back to the HTML file in a bit. For now, create the class: export class PopupComponent { } Not much there. Add in a constructor: constructor(public activeModal: NgbActiveModal) { } The constructor will inject an instance of the NgbActiveModal class into this component using Angular's Dependency Injection syntax. Finally, we'll add two methods. The first is to close the popup: onClose():void { this.activeModal.close('closed'); } Closing the popup usually means the user is done interacting with it and wants to move on to other things. onDismiss(reason : String):void { this.activeModal.dismiss(reason); } Dismissing the popup means the user is cancelling the operation. Both methods will be referenced inside the HTML template. Overall there is not much to this Angular Component, because I left it simple for sample purposes. It could get as complex as you need it to. Now look at the popup.component.html file. Start with a header: Test Modal x The header includes a Title and an X button. When the X button is clicked, the onDismiss() method is called. Dismissing the modal is like cancelling it, whereas closing it usually means you are done with it. Now, add a body: Modal Body Not much there, just some test text. Finally, add a footer: Cancel Close The footer includes two buttons. One is a cancel button which will dismiss the modal. The other is a close button. Both call the related methods inside the component. That's all we need to create the component that will display inside the modal. Modify the Main App Component Open up the app.component.ts file. Modify the template to be like this: template : 'Open Modal' There is a single button which will call an onModalRequest() function. The onModalRequest() function goes in the class body of the AppComponent. But, first be sure that the constructor injects ng-bootstrap[...]



Running Eclipse on the Surface Book

Thu, 26 Oct 2017 10:00:00 -0700

This question comes in from a reader who found my post about using the Surface Book as a programmer. I thought it might make a blog-worthy followup. This was Eric's question:
I am having trouble running Eclipse IDE on my Surface Book. Eclipse works, except that the "console" that my program calls for is teeny tiny. Like an inch and a half squared on my 3000 x 2000 screen. Fonts in the console also are minuscule -- I cannot even read them easily with a magnifying glass . Tried everything (adjusting font sizes in eclipse, running compatibility tests in windows) to no avail. Any ideas on how I can resolve this? Thanks in advance.
This is one of the biggest problems with the Surface Book. Eclipse--and a lot of other programs--are not high DPI Aware. It sucks, but it is getting better. The solution probably lies here. That post is for Photoshop and other Adobe tools, but it works for just about everything. First, you do a registry edit to tell Windows to look for an external manifest file. Then you create the manifest file in the install directory of your file. Name the file the executable with a .manifest' at the end. So, for Eclipse the execution program is ecliipse.exe and the manifest file will be eclipse.exe.manifest. This is the manifest text: false Reload eclipse and things should be better. I recently uninstalled Eclipse since I'm not on any client projects using it. I prefer IntelliJ when I can. Major windows updates will probably reset the registry setting. Just this morning, my creators update borked it. About half of the programs on my machine use this 'manifest' trick to make the programs usable. I even created manifest files for javaw.exe and java.exe from my Java install. And as a corollary, if you're using a lot of Remote Desktop Connections, use Terminals. It has settings to prevent the remote desktop from skewing way too small due to the same high DPI issues.



Angular Unit Testing: How do I Fix a Platform with a Different Configuration Has Been Created?

Tue, 17 Oct 2017 09:00:00 -0700

I've run into this one a few times. You're setting up Unit Testing of an Angular application and get an error like this:
Uncaught Error: A platform with a different configuration has been created. Please destroy it first.
It's frustrating and a but confusing. If you Google on that error you'll find a bunch of stuff, but no explicit solution. You've probably set up a TestBed configuration environment as part of your unit testing, probably like this: import { TestBed } from "@angular/core/testing"; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from "@angular/platform-browser-dynamic/testing"; TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); However, somewhere in the code, the non-testing modules have been loaded, probably like this: import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app.module'; platformBrowserDynamic().bootstrapModule(AppModule); The error occurs because of the conflict between the platformBrowserDynamic() and the platformBrowserDynamicTesting(). Make sure that you exclude the source files the import and initialization of the non-test version of the library. In your karma.conf file add an exclude property to the Karma configuration object, something like this: exclude : "src/app/main.ts", In my case, today, the error was related to a missing '/' in the excluded directory structure. I hope this helps someone.



How do I fix IE11 problems with CSS Calc and min-height?

Tue, 10 Oct 2017 10:00:00 -0700

I hate it when you have a problem that you cannot replicate in a simple example. That's exactly where I am. I'm working on an application built with HTML, CSS, and various JavaScript frameworks. The application requires a footer to be aligned at the bottom of the page. If the content is too large for the page, then the the footer should show up under the content. But, if the content is too small for the page, the footer should show up at the bottom of the window, or viewport. This should be pretty simple to build using CSS and HTML:
Lots of Main Content and navigation and headers Here
Some Footer Information Here that should always be at the bottom of the page
The CSS would be something like this: html, body { height: 100vh; margin : 0; } .wrapper { min-height: calc(100% - 200px); } footer { height : 200px; background-color : blue; } The actual client project code is a lot more complex, but this gives you the gist. Play with the code here. Ignore my design skills. The problem I was having was that IE11 seemed to have a problem with the min-height. When clicking in the page, or clicking a link to go to another page, it was as if the wrapper's min-height would shrink down on pages where the view height was greater than the actual content. This would cause the footer to jump to the middle of the page. For the life of me, I haven't been able to create a simple sample to demonstrate this. Some part of the client's custom code seems to be causing this. After some head banging and conferring with my team, I came up with this solution. It makes use of JavaScript and JQuery to 'hard code' the min-height on the wrapper. Instead of using the CSS Calc. this happens when the page loads and whenever the page is resized. if(/MSIE \d|Trident.*rv:/.test(navigator.userAgent)){ function onResize(){ /* The jquery calc code */ $('.wrapper').css('min-height', '100%').css('min-height', '-=200px'); } $(window).resize(function() { onResize() }); $(window).ready(function(){ onResize() }); } I used a regex trick to only execute the code for IE browsers. And I used this answer as a base for my solution. Part of our problem solving this was my inability to create a simple reproducible case, but pouring over thousands of line of code I could not find the magic style combination that caused the 'footer jump' problem. Frustrating; but the JS code above seems to solve the issue admirably.



Create TypeScript Modules - - Part 8

Tue, 03 Oct 2017 09:00:00 -0700

This is the last in my series of articles intended to introduce you to Typescript. It is bonus material I wrote for my Angular 4 book. This is the last part of the series. Check out part 1, part 2, Part 3, Part 4, Part 5. and Part 6, and Part 7. When writing a real-world application, it does not make sense to include all the code in a single file. TypeScript supports that by allowing you to expand different functionality into modules. Create Interface Module The first thing we're going to do is create a module for the name interface. I put this in a file named IFile.ts: export interface name { firstName: string; middleInitial? : string; lastName: string; getName() : string; }; This looks exactly like the Interface created in the previous exception with the one addition of the export keyword. Export tells the compiler that this class is available for use inside other classes. Create Class Modules Now create the Person class: export class Person implements name { firstName: string; middleInitial : string; lastName: string; getName() : string { return this.firstName + ' ' + this.middleInitial + ' ' + this.lastName; } } This also puts the export keyword in front of the class definition. If you try this you'll notice an immediate error. The name is not defined. To define it we'll need to add an import statement: import {name} from "./IName"; The import statement tells you that the name entity is imported from the IName file and can be used within this class. The path I used, './IName', tells us that the files are in the same directory, however we can use a more elaborate package setup, and most likely you will do that for main applications. We can create the Pets.ts module in the same manner: import {name} from "./IName"; export class Pet implements name { firstName: string; lastName: string; type : string; getName() : string { return this.firstName + ' ' + this.lastName + ", " + this.type; } } This code mirrors the Person module, with the primary changes being the use of the export keyword before the class definition and the import of the name interface. The Echo class needs a similar rework: import {name} from "./IName"; export class Echo { static readonly messageIntro : string = "Hello" subjectArray : name[]; private message : string; constructor(subjects : name[]){ this.subjectArray = subjects; } createMessage():void{ this.message = ''; for (let person of this.subjectArray){ this.message += Echo.messageIntro + " " + person.getName() + ""; } } echo():string{ return this.message; } } The functionality remains unchanged. Like the previous classes it uses an export statement to make the class available elsewhere, and an import statement to make use of the name interface. Rework Main Application With all the classes stored in separate files, our primary app has become a lot simpler. First, import all the classes: import {name} from "./IName"; import {Person} from "./Person"; import {Pet} from "./Pet"; import {Echo} from "./Echo"; Then, create the nameArray: let nameArray : name[] = []; Now, populate the nameArray: let jeffryInstance : Person = new Person(); jeffryInstance.firstName = "Jeffry"; jeffryInstance.middleInitial = "A"; jeffryInstance.lastName = "Houser"; nameArray.push(jeffryInstance); let hercInstance : Pet = new Pet(); hercInstance.firstName = "Hercules"; hercInstance.lastName = "Houser"; hercInstance.type = "Dog"; nameArray.push(hercInstance); let zeusInstance : Pet = new Pet(); zeusInstance.firstName = "Isadora"; zeusInstance.lastName = "Houser"; zeusInstance.type = "Dragon"; nameArray.push(zeusInstance); Create an instance of the Echo class: let echoInstance : Echo = new Echo(nameAr[...]



Create an Interface in TypeScript - - Part 7

Tue, 26 Sep 2017 09:00:00 -0700

I'm writing a series of articles about Typescript as extra material to support my upcoming Angular 4 book. This is the seventh part of that series. Check out part 1, part 2, Part 3, Part 4, Part 5. and Part 6. This section will talk about interfaces. It is not about User interfaces, but rather object-oriented interfaces. An interface is a definition of properties and methods that must be supported by a class which implements this interface. You can think of an interface as the contract between a class instance and a method argument or variable. If they both match the interface they are interchangeable. Create the Interface For this sample, we're going to create a name interface. This interface will represent the name of a person and will contain a first name and last name. It will have an optional middle initial and also a method to retrieve the name. Here is the interface: interface name { firstName: string; middleInitial? : string; lastName: string; getName() : string; } The interface is set up similar to a class or enum. It uses the keyword interface, and the name of the interface--in this case name. The firstName and lastName properties are as normal properties on an object. The middleInitial is an optional property, and that is distinguished by a question mark. Finally, a single method is defined by the interface, getName(). This will be used to return the name. The interface does not contain an implementation, just a definition of the method. That means different classes which extend the interface can have different implementations. Rework the Echo Class Let's rework the Echo class to use the interface instead of strings. First create the method stub with the instance variables: class Echo { static readonly messageIntro : string = "Hello" subjectArray : name[]; private message : string; } The main change here is that the subject string was replaced with a subjectArray of name types. The constructor: constructor(subjects : name[]){ this.subjectArray = subjects; } The constructor now accepts an array of name instead of a single string. The createMessage() function now loops over the array: createMessage():void{ this.message = ''; for (let person of this.subjectArray){ this.message += Echo.messageIntro + " " + person.getName() + ""; } } Inside the loop, the interface's getName() function is used to add an element to the output. Finally, the echo() function: echo():string{ return this.message; } The echo function has not changed, it just returns the object instance variable, message. Implement the Interface with a Class I'm going to create two classes which implement our name interface contract. One will be for a Person and another for a Pet. First, the Person class: class Person implements name { firstName: string; middleInitial : string; lastName: string; getName(): string { return this.firstName + ' ' + this.middleInitial + ' ' + this.lastName; } } The class is defined with the class keyword followed by the name of the class. Then comes the implements keyword followed by the name of the interface. If you wanted you could list multiple interfaces here. The firstName, middleInitial, and lastName are created properties on the object, not much different than how they were with the interface definition. The getName() method includes a definition. It concatenates the firstName, middleInitial, And lastName, returning a single string. Now, let's create another class that implements name. This one is called Pet: class Pet implements name { firstName: string; lastName: string; type : string; getName(): string { return this.firstName + ' ' + this.lastName + ", " + this.type; [...]



Create your first TypeScript Class - - Part 6

Tue, 19 Sep 2017 09:00:00 -0700

I'm writing a series of articles about Typescript as extra material to support my upcoming Angular 4 book. This is the sixth part of that series. Check out part 1, part 2, Part 3, Part 4, and Part 5. This entry will teach you about creating your own classes. A class is like your own variable type with data and functions to process that data. Create a Class Create your class stub: class Echo { } This creates a class named Echo. The purpose of this class is to create and store our welcome message. Let's start by creating some properties on the class: static readonly messageIntro : string = "Hello" subject : string; private message : string; The subject is a relatively normal variable. It is a string that contains the subject of our welcome message. The message is similar, but has the private distinguisher. This means that the message variable is private to the local message. It will contain the final message once it is put together, but is only accessible inside the class, not from code accessing an instance of the class. The messageIntro is a bit different. We are not able to define constants inside of a TypeScript class, so instead I used the readonly keyword. This means the value will not be changeable, just like a constant. I also define the messageIntro as a static property, which means it exists on the class and not on an instance of the class. Every class needs a constructor, so create one: constructor(subject : string){ this.subject = subject; } The constructor will be called automatically when we create a new instance of the class with the new keyword. This constructor accepts one argument, the subject. The code just saves the subject argument into the subject variable. Now, add a createMessage() function: createMessage():void{ this.message = Echo.messageIntro + " " + this.subject + ""; } This concatenates the read only messageIntro variable with the subject and a line break. We had similar code in previous samples, but not encapsulated into a function. The return type of this function is void, meaning nothing is returned. We'll add one final function to our class: echo():string{ return this.message; } This function returns the complete message. The message value could be blank if the createMessage() function as not called yet, however this will still work. Now, create an instance of the Echo class: var echoInstance : Echo = new Echo('World') This uses the new keyword to create the new instance. You may have seen this in other languages. You can output the subject for testing purposes: console.log(echoInstance.subject); You can also try to output the message: console.log(echoInstance.message); Since the message is a private variable, you'll see a compile error: By the same token, we can access the messageIntro static value: console.log(echoInstance.messageIntro); console.log(Echo.messageIntro); Can you guess which line works before trying to compile the code? The second one is the proper way to access static variables. The first one will throw an error: Our final code is to output the value to the screen: document.body.innerHTML = echoInstance.echo(); Compile the code--you should see no errors--and load it in a browser: In a non-sample application, I might try to make my classes more discrete. Since this one adds a line break at the end of the message, it is conflating data processing and display code, something which is undesirable in real world applications. Review the Generated Code This is the generated code: var Echo = (function () { function Echo(subject) { this.subject = subject; } Echo.prototype.createMessage = function () { this.message = Echo.messageIntro + " " + this.sub[...]



Loops and Arrays in TypeScript - Part 5

Tue, 12 Sep 2017 09:00:00 -0700

I'm writing a longer series of articles about Typescript. This will be extra material to support my upcoming Angular 4 book. This is the fifth part of that series. Check out part 1, part 2, Part 3, and Part 4. This entry will focus on loops and arrays. We'll create an array of strings, and then loop over them with our echo function to welcome multiple people in our HTML page. Create an Array The first step is to create an array. You can use this sytnax: let personArray : string[] = ["Jeffry", "Tom", "John"]; This creates a variable just like other variables we had seen. The key differentiator is that after the type, I added square brackets. This is what tells the compiler we are creating an array of strings. You can define arrays with any of the native types, such as numbers or Boolean, or with your own custom types. For-in Loop The very first time I wanted to loop over an array, I used a for-in loop, like this: let bodyString : string = ""; for (let person in personArray){ bodyString += echo(messageIntro + " " + person + ""); } document.body.innerHTML = bodyString ; I had used for-in loops in other languages, such as ActionScript so this was my natural impulse. Let's look at the results: Instead of outputting the data in the array, it outputted the index. The proper way to use a for-in loop in TypeScript would be like this: for (let person in personArray){ bodyString += echo(messageIntro + " " + personArray[person] + ""); } This isn't much different than a generic for loop that uses a counter, although the syntax is a bit nicer: All version of ECMAScript after 2015 support for-in loops the same way that TypeScript does. This is supported by most browsers and in fact that generated JS Code uses for-in loops: for (var person in personArray) { bodyString += echo(messageIntro + " " + person + ""); } But, this result wasn't quite what I was after. Thankfully TypeScript includes another option, the for-of loop. For-Of Loops A for-of loop makes one syntactical difference than a for-in loop. Instead of using the keyword in, it uses the keyword on: for (let person of personArray){ bodyString += echo(messageIntro + " " + person + ""); } This type of loop the loop counter, person, will match the value of the personArray instead of the index. After the compilation this is turned into a for loop with an explicit counter: for (var _i = 0, personArray_1 = personArray; _i < personArray_1.length; _i++) { var person = personArray_1[_i]; bodyString += echo(messageIntro + " " + person + ""); } Compile this code and load it in the browser to see the expected results: Looping in TypeScript is not much different than looping in other languages. The next entry in this series will focus on creating classes. Keep up to date by reading DotComIt's Monthly Technical Newsletter First Name Email Address * [...]



String Enums in TypeScript - Part 4

Tue, 05 Sep 2017 09:00:00 -0700

I'm writing a longer series of articles about Typescript. This will be extra material to support my upcoming Angular 4 book. This is the fourth part of that series. Check out part 1, part 2, and Part 3. This article will focus on creating String based Enums.

What is an Enum?

Enums are a data type I have not come across in most other languages, but they are inspired by C#. An enum is a way to give friendly names to numerical or string values. They are like an array with indexes, but more specific. I can envision using something like this with a view stack style component and using an enum to handle which view is currently displayed. Or, I might use it with an event class instance to determine what type of event occurred. Or it could be used to determine what color style to apply to certain text.

Create a String based Enum

It is interesting that Enum's can be used to represent textual values too. Look at this: enum MyColors { Blue = "#0000FF", Red = "#FF0000", Green = "#00FF00", }; The value of the color name represents the hex value of the actual color. I recently could have used something similar when dynamically applying colors to the header of a site based on which section the user was viewing. Get the individual colors, and output them: let myColor1 :MyColors = MyColors.Blue; let myColor2 :MyColors = MyColors.Red; let myColor3 :MyColors = MyColors.Green; console.log(myColor1); console.log(myColor2); console.log(myColor3); You'll see something like this: (image) Enums are an interesting data type, caught somewhere between an array and a class.
Keep up to date by reading DotComIt's Monthly Technical Newsletter



Enums in TypeScript - Part 3

Tue, 29 Aug 2017 09:00:00 -0700

I'm writing a longer series of articles about Typescript. This will be extra material to support my upcoming Angular 4 book. This is the third part of that series. Check out part 1 and part 2. This article will focus on Enums, a TypeScript data type that does not exist in JavaScript. What is an Enum? Enums are a data type I have not come across in most other languages, but they are inspired by C#. An enum is a way to give friendly names to numerical values. They are like an array with indexes, but more specific. I can envision using something like this with a view stack style component and using an enum to handle which view is currently displayed. Or, I might use it with an event class instance to determine what type of event occurred. Or it could be used to determine what color style to apply to certain text. Create a Number based Enum I'm going to start by creating a simple sample with a number based enum: enum MyNumbers { First, Second, Third } The MyNumbers enum contains four values each one representing a number. Since enums are sort of like arrays, the First item is at the 0 index, the second item will have the value of 1, and so on. We can use MyNumbers like it was it's own variable type: let myNum :MyNumbers = MyNumbers.First; Output this value. console.log(myNum); What do you think you'll get? Since it is the value of MyNumbers.First and that is the first element of the zero-based index, you'll get number 0: A benefit of enums is that we can control the number scheme: enum MyNumbers { First = 1, Second, Third } We specified the First item is equal to the number 1. Turn each element into a variable: let myNum1 :MyNumbers = MyNumbers.First; let myNum2 :MyNumbers = MyNumbers.Second; let myNum3 :MyNumbers = MyNumbers.Third; Then output them: console.log(myNum1); console.log(myNum2); console.log(myNum3); You'll see: Now our text numbers match up with the actual text index. We can control the numbers even if they aren't in sequential order. Add a new entry to the MyNumbers enum: enum MyNumbers { First = 1, Second, Third, Ten = 10, } This is number 10, skipping four through 9. Grab it as a variable and output it: let myNum10 :MyNumbers = MyNumbers.Ten; console.log(myNum10); Combined with our other outputs, you'll see something like this: Enums provide a lot of flexibility. Enums can also be created to use a string based index, and we'll discuss that in the next article. Keep up to date by reading DotComIt's Monthly Technical Newsletter First Name Email Address * [...]