Check out our Angular Book Series.

When am I too old to learn programming?

This comes in from a reader, and I thought it might make an interesting blog post.

After reading your "general life lessons" blog

I consider this a programming blog as opposed to general life lesson blog. But, then again, I'm writing this post, so...

I wanted to ask if you have known anyone who has came into the field of programming at a later age with no prior experience and if so how did they learn?

I know tons of people who came to the field or programming later in life w/ no prior experience. Of course, the bulk of them entered the field in the 80s and 90s. It might be harder to do that today. I'll get to the 'how did they learn' later.

and can the field of programming be for everyone?

I'd like to think so.

Im turning 30 next year with 12 years of blur behind me.

I just want to point out that, from my perspective, you are not entering the field 'later in life'. Unless you plan to spend the next 20 or so years studying before trying to enter the workforce. 30 isn't old nor later in life.

I just finished my AA and intro classes into programming(basically C++ Syntax and excercises). what brings me down is the guidance from other people. when I ask for advice from people in the field most answers are "get an internship", "things will come together when you graduate", and "work on real-world applications".

It sounds like you're too beginner to be considered for an internship, but maybe in a year or two. If you can get an internship or Co-op or similar work-study program I highly recommend it. It gives you work experience and programming experience with no expectations of preexisting knowledge. I cannot say enough good things about my own co-op experience--back in the mid 90s.

As an entry-level CS student with a plethora of information its difficult for me to understand what should i be learning not necessarily in order but things i need to know to break into the field one day. I think i pretty much hit a HUGE learning curve after learning how to print to screen, receive input, ifs and switches, loops, arrays, pointers, and classes.

Earlier you asked how people learn. People learn in a lot of different ways. I, personally, learn by experimenting with stuff and writing about it which is why my blog is full of programming posts, some stuff about obscure bugs, some about weird trivia, and some are just super basic stuff.

C, or C++, is pretty low-level. Not bad for basics, but it is unlikely you will graduate to work in that language. The thing I recommend concentrating on is learning concepts. It sounds like you have very basics. But, learn about how to use classes to create your own data types. Learn about encapsulation principles and separation of logic and data, and how loosely coupled pieces can fit together to build something more. That sort of stuff will, hopefully, come in some more advanced classes. Also experiment with other languages; especially other language types. SQL is a different type of language than C, and LISP is completely different than either of those, as some random examples.

All those things will make you a better programmer, and while in school for programming that should be your primary goal.

That said, I fully believe that being a good programmer will not help you get a job. For that you'll need to learn some marketing and networking. An internship can give you a jump start on that.

Unfortunately, interviewing has changed in the past 3-5 years. It becomes more about programming trivia than about how to get things done. I've been on some brutal client interviews where even when I do awesome I have no desire to move forward.

There are some random thoughts. What do you think?

Using Angular, RXJS, and SystemJS

just updated DotComIt's build scripts for building Angular 6 applications. I wrote these before the AngularCLI was king of the heap and keep these around because I haven't had time to update my LearnWith series, which contains an introduction to Angular.

Anyway, I copied my Angular5 scripts, updated the package.json to a bunch of new versions, build the sample app, and then started getting errors from the application:


Error: Unexpected token <
Evaluating http://local10.dciseed.dot-com-it.com/Angular6TypeScript/build/js/rxjs

My local dev server has directory browsing turned on, so instead of loading the actual files behind rxjs it was trying to load the directory listing. That won't work. I also saw this error in my experimentation, which said that '"rxjs/operators" not found'. Supposedly that issue was fixed long before RXJS 6.0.0, but alas I was still seeing it.

The solution was to list all the rxjs directories as a package inside of SystemJS Config:


packages: {
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js' },
'rxjs/operators': {main: 'index.js', defaultExtension: 'js' },
'rxjs/testing': {main: 'index.js', defaultExtension: 'js' },
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js' },
rxjs: { main: 'index.js', defaultExtension: 'js' }
}

It took me a while to find this solution, and even then I couldn't get it to work until I removed the quotes around the last package definition.

Weird stuff,

How do you Access the Arguments of a Jasmine spy?

I've been writing unit tests for clients. It's a nice change to finally have some clients who care about such things.

I have this Angular method that creates an object, then emits an event.

The method was something like this:


onButtonClick() {

let eventParameters = {};

// do stuff

this.eventEmitter.emit(eventParameters);
}

I want to be compare the properties of the eventParameters argument with what I expect them to be. However, I have no way to access the eventParameters directly because it is local to the method. My first thought was to do something like this:


spyOn(component,'onButtonClick').and.returnValue(myOwnEventParametersObject)

However my intent was to test the code inside the method, whereas this bypasses calling the method altogether. That would not suffice.

So, how'd I do it?

First, I saved an instance to the Spy:


const mySpy = spyOn(component.eventEmitter, 'emit');

I can drill down into this spy to get the results of the most recent call:


const recentCallArgs = mySpy.calls.mostRecent().args[0];

Once I have the argument object, I can introspect it to compare the arguments created by the method with what I expected them to be.


expect(recentCallArgs.value).toBe('value');

TaDa!

How do I combine Objects in JavaScript? Use the Ellipsis Operator!

This is a followup to last week's post about using Object.assign() to combine two JavaScript objects. Today I'll show you how to use the spread, or ellipsis, operator to do the same thing.

The scenario is that we have a configuration object being passed into a method. A lot of the config values are optional, and we want to default them if they are left out before the method does it's magic. We could write a lot of manual conditions to accomplish this, like this:


function conditionalConfig(config){
if(!config.option1){
config.option1 = defaultOption1Value;
}
if(!config.option2){
config.option2 = defaultOption2Value;
}
// etc.. etc.. etc..
// do other stuff
}

The code works, but it is tedious to write. We can use the Spread Operator to simplify it.

The Spread Operator

The spread operator is an ellipsis, or three dots. It has a handful of uses, but today I'm going to show you how to combine two objects.

Start with a function and an object that contains all the default values:


function defaultConfigWithSpread(config){
defaultObject = {
option1 : 'DefaultValue1',
option2 : 'DefaultValue2',
option3 : 'DefaultValue3',
option4 : 'DefaultValue4',

Notice I didn't close the object yet. We have one more property to add to the object:


...config
}

That last property is our spread operator. It tells the underlying engine to take all the properties from the config object and copy them into the defaultObject. If a property already exists in the defaultObject, it is overwritten. If a property does not exist it will not be changed.

For demonstration purposes, log the two objects:


console.log(config);
console.log(defaultConfig);
// do other stuff
// end function
}

You can test this like this:


customConfigObject = {
option1 : 'Value1',
option2 : 'Value2',
option3 : 'Value3',
}
defaultConfigWithSpread(customConfigObject);

Look at the console output and you'll see that the original config object is unchanged, but the default object contains all the new values:

The custom values from our config argument are retained and the unset default value--option4--is set with the new config.

You have to be careful when doing this to keep around a clean version of the default object since it is modified with this approach. I addressed that by creating the default config inside the function, as opposed to some permanent store.

Play with the code here.

It is a nice shorthand to be aware about.

How do I combine Objects in JavaScript? Use object.assign()!

Let's say we have a config object being passed into a method. A lot of the config values are optional, and we want to default them if they are left out before the method does it's magic. The structure is like this:


function conditionalConfig(config){
if(!config.option1){
config.option1 = defaultOption1Value;
}
if(!config.option2){
config.option2 = defaultOption2Value;
}
// etc.. etc.. etc..
// do other stuff
}

The code works great, but it is tedious to write all those conditionals. Is there a way to simplify it? Yes there is and I'm going to talk about two ways to do that. Today we'll cover object.assign().

Object Assign

The first way to simplify this code is to use object.assign(). Object.assign() will copy all the values from one object into another. First, create an object instance with all the default values:


function defaultConfigWithAssign(config){
defaultObject = {
option1 : 'DefaultValue1',
option2 : 'DefaultValue2',
option3 : 'DefaultValue3',
option4 : 'DefaultValue4',
}

Now use Object.assign() to combine that with your function argument:


Object.assign(defaultConfig,config)
// dump to console for testing purposes
console.log(config);
console.log(defaultConfig);
// do other stuff
// end function
}

You can test this like this:


customConfigObject = {
option1 : 'Value1',
option2 : 'Value2',
option3 : 'Value3',
}
defaultConfigWithAssign(customConfigObject);

Look at the console output and you'll see that the original config object is unchanged, but the default object contains all the new values:

The custom values from our config argument are retained and the unset default value--option4--is set with the new config.

You have to be careful when doing this to keep around a clean version of the default object since it is modified with this approach. I addressed that by creating the default config inside the function, as opposed to some permanent store.

Play with the code here.

Next week I'm going to talk about the Spread operator which can be used to accomplish the same thing.

How do I test Observable.timer?

This was trickier than I thought, which is why I'm writing a blog post about it. I'm writing some code which uses an FakeAsync Zone nor RxJS TestScheduler.

The timer() call returns an Observable, so I decided to create one myself which gave me complete control.


let timerObserver :Observer<any>;
beforeEach(() =>
{
spyOn(Observable, 'timer').and.returnValue(Observable.create(
(observer =>{
timerObserver = observer;
})
));
});

I created an Observer object. This is the internal logic that makes the Observable resolve itself. I used spyOn() inside a beforeEach() to have the unit testing framework return my own Observable and ignore the library code. I save the observer for later usage.

Now, when I'm testing I can resolve the timer immediately:


it('Some Test',()=>
{
// do stuff if needed

// trigger the fake timer using the Observer reference
timerObserver.next('');
timerObserver.complete();

//
expect(somethingToHappenAfterTimerCompletes).toHaveBeenCalled();
});

I spent more time banging my head on this than I thought I would, and I hope this helps you.

How do I test the text of an HTML Element with Jasmine, Karma, and Angular?

I think this should have been simple, but my Google Fu was failing me. I'm working on an Angular app, as I often do, and was writing unit tests to verify that property changes inside a Component's class were reflected inside the view template.

The Component and View

I'm just going to use truncated code here, but the component had a property like this:


export class MyClass{
@Input() buttonText : string = "";
}

The template had something like this:


<button class="myButton">{{buttonText}}</button>

Change the value on the component, and the view should change. This sort of binding is basic to Angular. How do we test that?

Write the Tests

First, you set up the TestBed:


beforeEach(async(() =>
{
TestBed.configureTestingModule({
declarations: [ MyComp ]
})
.compileComponents();
fixture = TestBed.createComponent(MyComp);
component = fixture.componentInstance;
}));

This should be pretty standard, and this code is almost copied verbatim from the Angular CLI defaults.

Now your test should do something like this. First set the value on the component


const defaultButtonText = "Something"
component.buttonText = defaultButtonText ;

Now you have to detect the changes to force the view to refresh itself:


fixture.detectChanges();

Get the HTML Element:


const button = fixture.debugElement.query(By.css('.myButton'));

And check the button's TextContent:


expect(button.nativeElement.textContent.trim()).toBe(defaultButtonText )

You're code should be all set to test.

For completeness, here is the full test:


it('Set Button Text to Something', () =>
{
const defaultButtonText = "Something"
component.buttonText = defaultButtonText ;
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('.myButton'));
expect(button.nativeElement.textContent.trim()).toBe(defaultButtonText )
});

I hope this helps someone.

How do I listen for an Angular Event in TypeScript?

I'm building a custom Angular service for a client project that will create modal and other popups. If certain interaction occurs within the modal, then the modal should dispatch an event and the service needs to close the modal. In Angular you can use an EventEmitter to dispatch the event from the component's class. Create the emitter as a property on the component's class and add the @output metadata:


@Output()
myEvent : EventEmitter<any> = new EventEmitter();

Then to dispatch the event use the emit method:


this.myEvent.emit('Emitted Value');

That does exactly what I need in the component side. However, to listen for the event, most of the documentation I can find talks about doing so in the HTML template:


<MyComp
(myEvent)="onMyEvent($event)">

</MyComp>

Unfortunately, the service cannot add that event handler onto HTML because there is no HTML, so that was a no go for my use case. How do you do it?

After the service creates the component and displays it, it has an instance to that component class. We can introspect into the component class to get access to the emitter, and subscribe to it:


myCompRef.instance.myEvent.subscribe((value) =>
{
// do something
});

Under the hood the EventEmitter is a Subject, which is like an Observable.

Running Unit Tests from IntelliJ

I put together this screencast about running Unit Tests using IntelliJ.

How do you tell Jasmine to run a single test?

Last week I wrote about how to tell Jasmine to ignore a unit test. This week I'll tell you how to ignore every unit test except one.

To use last week's example, a normal unit test would be something like this:


it("True is True", () =>
{
expect("True").toBe("True");
});

A normal test suite will include lots of tests spread out through lots of files. You can focus a unit test using fit(). This tells Jasmine to only run the unit test with the 'f':


fit("True is True", () =>
{
expect("True").toBe("True");
});

other unit tests will be ignored. This can be a great use when testing something new.

You can use the same thing to disable a full suite with fdescribe() instead of describe:


fdescribe("Some Test Suite"()=>
{
it("True is True", () =>{
expect("True").toBe("True");
});
});

This type of stuff can be pretty handy if you're running your tests via command lines.

More Entries

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.