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

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

$
0
0
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.

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

$
0
0
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.js 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.

Running Eclipse on the Surface Book

$
0
0
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.

Creating a Popup with Bootstrap and Angular

$
0
0
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.js' The seed project scripts will need to copy the Bootstrap libraries into the build directory. Just find the angularLibraries array in the config.js file and add the new entry: '@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap.js' 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(private 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: 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: Not much there, just some test text. Finally, add a footer: 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 : '' 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's NgbModal constructor(private modalService: NgbModal) { } Now, look at the onModalRequest() method: 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'); }); } First, the modalRef is created using the mmodalService.open() method. The PopupComponent is sent in as an argument, so be sure to import it. The modalRef.result is a promise object. If the modal is closed then the result function will be executed. If it is dismissed the failure function will execute. For both of these functions, I'm just outputting the results to the log. /

Modify the app.module

We need to tell the @NgModule about the popup component. First, review the imports: import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; import { AppComponent } from './app.component'; import {PopupComponent} from "../views/popup/popup.component"; The first two imports are from the angular library. The second one comes from the ng-bootstrap library. The final two imports related to our custom code. Create the NgModule metadata: @NgModule({ }) I started it empty. First, add the imports: imports: [ BrowserModule, NgbModule.forRoot() ], It loads the BrowserM declarations: [ AppComponent, PopupComponent ], The declarations tells the module which of our custom components need to be ready for use. Next, bootstrap our app's main component: bootstrap: [ AppComponent ], Good to go! And finally, add the PopupComponent the the entryComponents array: entryComponents: [PopupComponent] This is important because this is how we tell Angular to allow this component instance to be created on the fly with our code. Finally, after the metadata, export the component class: export class AppModule { }

Test It

Now you can test things. Open the app in a browser: Now, click the Open Modal button: Click the X or Cancel Button. You should see a message show up in the console: Open it again, and click the close button: You are good to go. I wrote this post as a prelude to testing Bootstrap Popups with Angular. Those articles will come over the next few weeks. In the meantime, get my new book series on Angular 4 which uses similar techniques.
Keep up to date by reading DotComIt's Monthly Technical Newsletter

Testing a Bootstrap Popup with Angular - Part 1

$
0
0
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.js/dist/zone"; import "zone.js/dist/long-stack-trace-zone"; import "zone.js/dist/proxy"; import "zone.js/dist/sync-test"; import "zone.js/dist/jasmine-patch"; import "zone.js/dist/async-test"; import "zone.js/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 create the modal. Thankfully there is a workaround. We daisy chain an overrideModule() method after the configureTestingModule is created to add the entryComponents metadata. That's all we need in the base.test.ts file. Notice there is no formal export of a class. It isn't needed, since no other classes will use this explicitly. Be sure this file is compiled into your tests before your other code to avoid compile errors.

Test the Popup

Now, we're going to test the PopupComponent. There are two methods that we care to test: onDismiss(reason : String):void { this.activeModal.dismiss(reason); } onClose():void { this.activeModal.close('closed'); } The first is the onDismiss() method, which will occur if the user cancels the popup. It means all changes are cancelled. The second method is the onClose() method and it occurs if the user formally closes the popup with the close button. Create a file named popup.componment.test.ts. Start with imports: import {async, TestBed} from '@angular/core/testing'; import {NgbModal, NgbModalRef, NgbActiveModal} from "@ng-bootstrap/ng-bootstrap"; import {PopupComponent} from "../../../../../../src/com/dotComIt/learnWith/views/popup/popup.component"; It imports the async and TestBed modules. The async import is used to run a beforeEach() or it() test inside an async test zone that mocks the mechanics of asynchronous processing. Then some modal specific classes are imported from ng-bootstrap. Finally our custom PopupComponent is loaded. Now, create a describe function: describe('popupcomponent', function () { }); The describe() function is a Jasmine function that defines a test suite, which is a collection of related tests. The function takes two arguments. The first argument is a string that is the name of the test suite, in this case 'Sample Tests'. The second argument is a function, which runs the tests. You can embed a describe() function inside other describe() functions if you feel it is relevant to your testing. Create two variables inside the describe() block: let comp: PopupComponent; let activeModal : NgbActiveModal; We'll define these values in a beforeEach() block and reuse them in individual tests. Look at the beforeEach() next: beforeEach(async(() => { TestBed.compileComponents().then(() => { let modalService : NgbModal = TestBed.get(NgbModal); const modalRef : NgbModalRef = modalService.open(PopupComponent); comp = modalRef.componentInstance; activeModal = comp.activeModal; }); })); We compile the components on the TestBed. This returns a promise, which we use to get access to the global variables our tests will need. First it creates a local instance of the modalService. It uses that modalService to open the popup and create the modalRef variable. The component instance is saved off the modalRef. And the activeModal value is pulled out of the component for easy access. The first test: it('should create component', () => expect(comp).toBeDefined() ); The it() function defines the test. It has two arguments, and the first is the descriptive name of the test. If it fails, you can use this name to determine which test actually failed. The second argument is a function that performs the test. The test is written to be easily parsable: expect(comp).toBeDefined() This is called an assertion. We expect the component to be defined. This will return true if the component exists, or false if the component does not exist. This is often an easy test to run to make sure you have your configuration set up correctly. Let's write a test for the onDismiss() method: it('Call onDismiss()', () => { spyOn(activeModal, 'dismiss'); comp.onDismiss('Some Reason'); expect(activeModal.dismiss).toHaveBeenCalled(); expect(activeModal.dismiss).toHaveBeenCalledWith('Some Reason'); }); This test uses a new command, spyOn(). The spyOn() method is used to watch an object for a method call. You can use this in tests to intercept the method and return specific values. Alternatively, you could use it to verify that a certain method was called. The spyOn() is looking at the activeModal as the first argument, and the dismiss method as the second argument. Then the onDismiss() method is called on the component. Two tests follow. One to make sure that the dismiss() function was called. And the second to make sure it was called with a specific argument, 'Some Reason'. The test of the onClose() method operates using a similar fashion: it('Call onClose()', () => { spyOn(activeModal, 'close'); comp.onClose(); expect(activeModal.close).toHaveBeenCalled(); expect(activeModal.close).toHaveBeenCalledWith('closed'); }); Instead of spying on the dismiss method of the active modal we spy on the close method. And that is the method we check in the two assertions. Try this out by running your tests. If you use my seed, use this: Gulp test And you'll see something like this:

Final Thoughts

This concludes this article, but I have another one coming out next week. It will examine the code I use to test the component that creates the popup. If you want all this information and more, get my the bonus book to my Angular 4 book series. It shows you how to create an app from scratch, and covers Angular CLI, unit testing, debugging techniques, and how to build your own project seed.
Keep up to date by reading DotComIt's Monthly Technical Newsletter

Testing a Bootstrap Popup with Angular - Part 2

$
0
0
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 easy test, to see that the modal opened: it('Modal Opened', function () { appComponent.onModalRequest(); expect(modalService.open).toHaveBeenCalled(); }); This is pretty self-explanatory. It calls the appComponent's onModalRequest() creates the modal, and checks to see that the open method had been called, insinuating that the modal had been created. Let's create the modal, then close it: it('Modal Opened, then Closed', (done : DoneFn) => { appComponent.onModalRequest(); fixture.detectChanges(); fixture.whenStable().then(() => { modalRef.close(); fixture.whenStable().then(() => { expect(console.log).toHaveBeenCalledWith('closed') done(); }); }); }); First thing you notice is that a done() function is passed into the test function. This is a function that tells Jasmine to run the code asynchronously. This is a special Jasmine construct, and is different than the async or fakeAsync test beds which are Angular constructs. The Angular constructs have all sorts of issues if you use any sort of timer under the hood, and gave me lots of problems when I was writing the test code for the learn with app. This approach avoids those issues. Next, the onModalRequest() method is called on the appComponent. Then we access the fixture to detectChanges(). This tells the component to process a digest cycle. It will redraw whatever needs redrawing. In our case, it waits for the modal to actually be created and opened. Then we wait until the fixture is stable using the whenStable() function. This means the modal was created and it is all good to continue. The whenStable() method returns a promise, and we execute the success function on it. Inside the success function we call a close() method on the modalRef value. We do not need to call the detectChanges() again, but we do need to wait until code is stable before running our assertion. The assertion excepts that console.log() will have been called with the value "closed". This is the hard coded result value inside the main app component code. Finally it calls the done() function to tell Jasmine that we are done running async code. This completes the test To test the dismiss function, we use a similar approach, but I needed an extra level of waiting until the component fixture was stable before I could check for the dismiss function to have been called: it('Modal Opened, then dismissed', (done : DoneFn) => { appComponent.onModalRequest(); fixture.detectChanges(); fixture.whenStable().then(() => { modalRef.dismiss(); fixture.whenStable().then(() => { fixture.whenStable().then(() => { expect(console.log).toHaveBeenCalledWith('cancelling') done(); }); }); }); }); The code opens the modal with appcomponent.onModalRequest(). Then it calls fixture.detectChanges() to watch for the DOM changes. Then it uses whenStable() to make sure the modal opened. When it is open, it is dismissed. Then it waits until it's stable twice before running the assertion. The assertion checks that the console.log() method was called with the 'cancelling' string. Then it calls the done() function, finishing off this method. Run it: Gulp test And you'll see results like this:

Final Thoughts

When researching how to test a popup with Bootstrap and Angular 4 I found a lot of conflicting information. But, I hobbled through it and found this approach which seemed to work well for me. I wrote a full 70 pages on Unit Testing in the bonus book to my Angular 4 series. Get it now!
Keep up to date by reading DotComIt's Monthly Technical Newsletter

General Life Lessons

$
0
0
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. ;)

Enable Double Opt In for MailChimp APIs

$
0
0
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.

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

$
0
0
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.js: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

How do I create a REST service in PHP?

$
0
0
I've been working to update the LearnWith series. The series builds UI applications--right now with Angular--and multiple backends with NodeJS, or ColdFusion. I'm creating a new book that creates services in PHP. How do you create a REST service in PHP? I did it this way. First, add a header: header("Content-Type: application/json; charset=UTF-8"); The Content-Type header says the results will be in JSON. Then, get the request type: $method = $_SERVER['REQUEST_METHOD']; The $method variable will be GET, or POST, or PUT, or whatever REST protocol you're using. Then, use a switch statement to determine the type of request: switch ($method) { case 'GET': // access URL Variables // $_GET["myvar"]) // data retrieval here; echo(json_encode($result)); break; case 'PUT': // retrieve PUT body data $data = json_decode(file_get_contents('php://input')); // $data->myvar // Update data Here echo(json_encode($result) ); break; case 'POST': // retrieve POST Body data $data = json_decode(file_get_contents('php://input')); // $data->myvar // Create some data Here echo(json_encode($result) ); break; default: echo("Unknown Request Type"); break; } That is pretty much it. For get requests, you can access URL variables directly, like this: $_GET["myvar"]) For PUT or POST requests, you'll most likely be sending a JSON object as the body of the request and you can access it like this: $data = json_decode(file_get_contents('php://input')); I hope this helps someone. Be sure to check out my LearnWith series, where you'll be able to find information about integrating Angular and AngularJS with PHP very soon.

Why won't Jersey work on JDK 9?

$
0
0
I've been experimenting with writing REST Services in Java. A ton of clients have used Java to power their backend's over the years, but I never created a REST Service environment from scratch myself. I decided to tackle it during the holiday time and educate myself. I try to focus on front end programming technologies, but knowing about the backend is beneficial. I decided to use Jersey to build out REST Services in Java and the road has been rocky. I have a Maven project setup to use Tomcat 8.5 and Java 9.01. Unfortunately, I kept seeing a lot of errors like this in the Java console: java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor( implementation=org.glassfish.jersey.jaxb.internal.XmlRootObjectJaxbProvider$General contracts={javax.ws.rs.ext.MessageBodyReader} scope=javax.inject.Singleton qualifiers={} descriptorType=CLASS descriptorVisibility=NORMAL metadata= rank=0 loader=null proxiable=null proxyForSameScope=null analysisName=null id=130 locatorId=0 identityHashCode=1215770148 reified=false) at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:705) at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor etc.. etc.. or this: java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBContext at org.glassfish.hk2.utilities.cache.LRUHybridCache.compute(LRUHybridCache.java:315) at org.glassfish.hk2.utilities.reflection.internal.ClassReflectionHelperImpl.getAllMethods(ClassReflectionHelperImpl.java:108) at org.glassfish.hk2.utilities.reflection.internal.ClassReflectionHelperImpl.getPreDestroyMethod(ClassReflectionHelperImpl.java:209) at org.glassfish.hk2.utilities.reflection.internal.ClassReflectionHelperImpl.access$400(ClassReflectionHelperImpl.java:56) at org.glassfish.hk2.utilities.reflection.internal.ClassReflectionHelperImpl$2.compute(ClassReflectionHelperImpl.java:74) at org.glassfish.hk2.utilities.reflection.internal.ClassReflectionHelperImpl$2.compute(ClassReflectionHelperImpl.java:70) at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture$1.call(LRUHybridCache.java:115) at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture$1.call(LRUHybridCache.java:111) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.run(LRUHybridCache.java:173) at org.glassfish.hk2.utilities.cache.LRUHybridCache.compute(LRUHybridCache.java:292) at etc..etc.. They went on and on. Basically, some libraries that are required by Jersey are no longer included as part of the Java 9 SDK. They were there in Java 8, but were removed. These errors exist because the libraries cannot be found. The trick to remove these errors is to load these libraries using Maven. Find the pom.xml that builds your project and find the dependencies section. It will probably look something like this: org.glassfish.jersey.containersjersey-container-servlet-coreorg.glassfish.jersey.injectjersey-hk2org.glassfish.jersey.mediajersey-media-json-binding We need to add back in the missing dependencies. There are two libraries that were required: javax.xml.bindjaxb-api2.3.0javax.activationactivation1.1 Relaunch your Tomcat instance and you are good to go. No errors and your Jersey services should work without issue.

How do I copy Multiple Directories with Maven?

$
0
0
I've been playing around with Java since a lot of my clients use it as their service layer to power their Angular applications. As such I'm digging into Maven a common build tool for Java applications. Java development is more complicated than something like PHP or ColdFusion. With PHP or ColdFusion I can just write a file, throw it in a web directory and load it. Java requires a compilation process, which complicates things a bit. Since I'm building a service layer as part of the Learn With applications, I wanted to copy specific files into my final WAR file. I wanted to copy the front end from the books into the final WAR file, without having to replicate all the UI code in the Java project. The Maven ">Resource plugin lets me copy files from outside the Java project into the Java project before building the project. Something like this works:maven-resources-plugin3.0.2copy-resourcesvalidatecopy-resources${basedir}/src/main/webapp/your-dir-hereC:/non-packaged-resourcestrue This works great to copy non-project files from the resource directory: C:/non-packaged-resourcestrue This will be external to the project. Into the outputDirectory ${basedir}/src/main/webapp/your-dir-here Which is part of the project. Once the files are in the web-app directory they will be compiled into the final WAR file and accessible when that WAR is deployed to a Java server, such as Tomcat. However, I'm dealing with multiple UI technologies and wanted to copy over all the files. How do I do it? The answer is to put multiple execution blocks inside the tag:copy-resources-AJSvalidatecopy-resources${basedir}/src/main/webapp/AJSC:/Projects/lw/AJS/chapter1/angularApptruecopy-resources-A4validatecopy-resources${basedir}/src/main/webapp/A4C:/Projects/lw/A4/chapter1/Angular4TypeScript/buildtruecopy-resources-A5validatecopy-resources${basedir}/src/main/webapp/A5C:/Projects/lw/A5/chapter1/Angular5TypeScript/buildtrue Make sure that each execution block has a unique ID, or else Maven will get confused. This copies my Angular 5 source files to: ${basedir}/src/main/webapp/A5 And they can be surfable using "http://localhost:port/A5/" The Angular 4 source files to: ${basedir}/src/main/webapp/A4 And they can be surfable using "http://localhost:port/A4/" And the AngularJS files will be put to: ${basedir}/src/main/webapp/AJS And they can be surfable using "http://localhost:port/AJS/". That is how you can copy multiple external directories into your Java project using Maven.

How do you get the ID of the inserted row with Java and SQL Server?

$
0
0
I've been playing around with the Learn With series and building the backend services in Java. I was going right along until I got to the chapter to create and update data. The query is something like this: String SQL = "insert into tasks(taskCategoryID, userID, description, completed, dateCreated) values(?,?, ?, 0, ? ) SELECT SCOPE_IDENTITY() as taskID"; This is a super common approach to creating a new item in SQL Server, and then immediately selecting the newly created ID with SCOPE_IDENTITY(). I'd expect it to work easily. The rest of the code: PreparedStatement pstmt = connection.prepareStatement(SQL); // set parameters pstmt.setInt(1, taskCategoryID); pstmt.setInt(2, userID); pstmt.setString(3, description); LocalDate dateCreated = LocalDate.now(); pstmt.setObject(4, dateCreated); ResultSet rs = pstmt.executeQuery(); The last line will throw an error claiming that the query returned no results sets and blow up. I had been swimming along smoothly until I ran into that issue. It turns out that, for updates and inserts, that is the wrong approach. Instead of using executeQuery(), I need to use executeUpdate(), like this: pstmt.executeUpdate(); After that, I can get the second result set using this: ResultSet rs = pstmt.getGeneratedKeys(); Then things are good to go. You'll probably find the LearnWith series supporting Java next month.

How do I run a Gulp Script in a different directory from Maven?

$
0
0
If you want to run a Gulp Script from Maven, you use the frontend plugin, right? Unfortunately, that seems to assume that the Gulp script is part of the Java project. I'm creating a Java Backend to the LearnWith series and am sharing UI code between multiple backend technologies. As such, my directory structure is different and the UI code is not in the web root. I want to run a gulp script in a different directory, and then copy the results into the project's webapp directory. How do you do it? I was able to do it with the exec Maven Plugin. First, set up the plugin in the plugins portion of Maven POM: org.codehaus.mojoexec-maven-plugin1.6.0 The groupId, arftifactId, and version are specified. For each script you want to run you'll need an execution statement:Build Angular 5validateexecgulpbuildC:\Projects\lw\A5\chapter7\Angular5TypeScript The id is a unique name for the build script. The phase is validate, because it is. The goal should be set to exec. The configuration is where the real magic happens. We tell it to execute the gulp command with the argument 'build', so this will run: gulp build We want to make sure that the script runs in the proper directory and that is specified with the workingDirectory tag. Presumably this directory will be outside the current directory structure. Finally, close the plugin tag: That's all you need to do to run an external Gulp Script from a Maven project. This assumes, of course, you have Gulp installed. Next week I'm going to write about copying the processed files into the Java project.

How do I copy files with Maven?

$
0
0
Last week, I wrote about running a Gulp Script from Maven. The Gulp Script was located in a directory outside of the Java project. This week I'll show you how to copy the file from the external directory into the Java project. We're going to use the maven-resources-plugin to make this work. First, set it up as a plugin in the Maven POM file: maven-resources-plugin3.0.2 This adds the artifactId--AKA the plugin name--and the version number. For each set of files we want to copy, we'll need to add an execution block, so start there:copy-resources-A5validatecopy-resources This specifies the id of the copy, which is just a unique name for the process. It is done on the validation phase. And the goal is to copy-resources. Before we end the execution block, we need to add the configuration. this will tell us what we are copying and where we are copying it too. ${basedir}/src/main/webapp/A5C:/Projects/lw/A5/chapter7/Angular5TypeScript/buildtrue The outputDirectory specifies the location of the copied files. I made them relative tot he $(basedir), which is the root of the Java project. In the Angular 5 files in the A5 directory of the Java Project's webapp. The source directory is listed under resources, resource. Finally close off the open tags, which is the execution tag, the executions tag, and the plugin tag: I'm using this approach to copy the results of an external Gulp script into the final WAR, so that the files will be surfable via the Tomcat instance. It has been working great for me.

What is Apache Royale?

$
0
0
A friend reached out to me to ask what I thought of Apache Royale and I thought it would make a good blog post.

What is Apache Royale?

Apache Royale is a rebrand of Apache Flex's FlexJS project. Royale would allow you to create HTML(5) applications with MXML and ActionScript. It is independent and separate from Adobe's Flash Platform. There are a lot of 'legacy' Flex apps out there, so from that perspective it makes a lot of sense to allow a Flex Developer to repurpose their AS3 and MXML skills in order to build HTML5 applications with no reliance on the Flash Player or Adobe AIR. That is great.

Where do I fit in?

While I am still a PMC member of the Apache Flex project, I am not involved with Royale in any way. I haven't followed Apache Royale very closely, and am even less so since it was promoted to a top level Apache project, separate from Flex. You can take my opinion and understanding with a grain of salt.

What do I think about Royale?

Despite the impressiveness of the technology, Royale does not allow you to convert a Flex application to an HTML5 application. It is expected you will create a new application from scratch. And since you're doing that regardless, why not use a technology that is more 'native' to HTML(5) development? Such technologies might be AngularJS or React. I fear the target market of Royale--Flex Devs who want to build HTML5 applications--moved on many years ago. The flip side of that is that HTML5 devs change their mind on the framework of choice every few years. They have embraced ActionScript-like things such as TypeScript and frameworks built with it such as Angular. These are clearly not as HTML5 'native' like AngularJS or React are. Could the tide of interest swing back to ActionScript and MXML? I don't know.

Final Thoughts

While Apache Royale is a really cool project, I fear it is too little too late. I don't have any problems building HTML5 applications that would be solved by moving to a MXML / ActionScript solution. There are already other frameworks and tools for converting from ActionScript to JavaScript, but they have not gained a lot of traction. I see no reason why Royale would change that. I do wish the team luck, they have some of the smartest people I had the privilege of knowing. For now I'm content building Angular applications to solve client problems.

Why can't IntelliJ find java.time with JDK 9?

$
0
0
I've been working on a a few projects that use the JDK 9 with IntelliJ. My latest started getting an error like this: java package java.time does not exists java cannot find symbol symbol: class LocalDate The LocalDate class was added to the JDK 8, so this error makes sense if you are building using an earlier version of JDK. But, I should not be seeing it when using JDK 9. Googling on similar errors seems to bring me back to the same thing I already knew. You're using the wrong version of the JDK, be sure to upgrade to JDK 8 or later. But, I am already using JDK 9, so should not be having this problem. I spent an hour pouring over IntelliJ settings before stumbling onto this screen: The Java Compiler target bytecode version of my project was set to 1.7 instead of 9. I already fixed that in the screenshot above. It made my errors go away immediately. The most confusing thing is that I didn't have errors on any of the other projects.

How do I run ES6 JavaScript code on the console?

$
0
0
I've been following a tutorial on using Redux and the code in the sample is ES6 code. The tutorial ran the code in the debugger of Visual Studio Code, but me being an IntelliJ user could not find an parallel way to run the code. I created an Index.html file that loaded the JS file, but nothing happened. I assume because the ES6 syntax used in the sample as not yet universal in the browser JS engines. So, what next? I looked for a way to run the code at the console, and found one. With NodeJS installed: node filename That ran the code, and gave the same results that the tutorial got in the Visual Studio Code window. After doing that, I realized I could run the same thing in IntelliJ's terminal Window. I'm not used to running advanced JS or TypeScript code w/o transpiling it with a tool like TypeScript, Webkit or the Angular CLI. This project started simpler, but I'm good to go now. I hope this helps you!

What is the difference between Boolean class and boolean primitive type in Java?

$
0
0
I was recently working on the Java code for the LearnWith series. The application behind the book is a Task Manager application and one of the features is the ability to filter tasks based on their completed state. The database field is a bit field, because a task can either be completed or not completed. However, from a filtering perspective I need to accommodate for three different states: Completed, not Completed, and All Tasks. How do I handle that in Java? A database bit column usually turns into a Boolean value in a programming language, and for that it works great. With Java the boolean primitive type is perfect for this. It can support values of true or false. However, boolean does not have an undefined or null state. It must always have a value. To handle the UI filtering I had to use an instance of the Boolean class. Since it is a class it can be undefined or null. The final code was something like this: if(BooleanVariable != null){ // do something to handle value } else { // do something to handle the null value } This stuff should be old hat if you have a lot of Java experience, but from someone who focuses on UI code over server side code, it made me pause for 10 seconds to figure it out.

Setting up Java and Jersey with IntelliJ

$
0
0
I put this video together about setting up Java and Jersey using IntelliJ. This demonstrates the project structure I used when writing the Learn With books on Java.
Viewing all 497 articles
Browse latest View live