Susan Harkins (345) [Avatar] Offline
#1
Please post errors in the published version of Angular in Action here. If necessary, we'll publish a comprehensive list for everyone's convenience. Thank you!

Susan Harkins
Errata Editor
Manning Publications
41242 (1) [Avatar] Offline
#2
My source code
[ 938 bytes ]
Chapter 7, Listing 7.7. Published code is:

ngOnInit() {
this.route.queryParams
.subscribe(params: Query => {
this.return = params['return'] || '/forums';
if (!this.userService.isGuest()) {
this.go();
}
});
}

This fails to compile. I modified it to:

ngOnInit() {
this.route.queryParams
.subscribe( params => {
this.return = params['return'] || '/forums';
if (!this.userService.isGuest()) {
this.go();
}
});
}

Also, you remove the OnInit import, and the implements OnInit, which caused ngOnInit to error out. I put these back in.
312507 (2) [Avatar] Offline
#3
Errata in Angular in Action - Page 34
Code sample to download material CSS from Material Design Light is as follows:

<link rel="stylesheet" href="//storage.googleapis.com/code.getmdl.io/1.0.1/material.indigo-orange.min.css">


This link appears invalid and does not change the UI. I changed it to the following and this worked. MDL also recommends adding the JavaScript reference and adding the defer attribute so the script isn't executed until after the page fully loads.

<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-orange.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
jeremy.wilken (205) [Avatar] Offline
#4
Hello, can you share the error and more detail? You appear to just be removing TypeScript typing information.

41242 wrote:Chapter 7, Listing 7.7. Published code is:

ngOnInit() {
this.route.queryParams
.subscribe(params: Query => {
this.return = params['return'] || '/forums';
if (!this.userService.isGuest()) {
this.go();
}
});
}

This fails to compile. I modified it to:

ngOnInit() {
this.route.queryParams
.subscribe( params => {
this.return = params['return'] || '/forums';
if (!this.userService.isGuest()) {
this.go();
}
});
}

Also, you remove the OnInit import, and the implements OnInit, which caused ngOnInit to error out. I put these back in.
jeremy.wilken (205) [Avatar] Offline
#5
Errata in Angular in Action - Page 34
Hello, the link is still valid and works when I test it. You also do not need the script tag, as we don't use any of the JavaScript for that library in the example, just the CSS. I don't believe this is an issue, but if it is still please explain further.

312507 wrote:Code sample to download material CSS from Material Design Light is as follows:

<link rel="stylesheet" href="//storage.googleapis.com/code.getmdl.io/1.0.1/material.indigo-orange.min.css">


This link appears invalid and does not change the UI. I changed it to the following and this worked. MDL also recommends adding the JavaScript reference and adding the defer attribute so the script isn't executed until after the page fully loads.

<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-orange.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
jeremy.wilken (205) [Avatar] Offline
#6
There is a typo as found in this post: https://forums.manning.com/posts/list/42920.page

For some reason the line is duplicated in the final version of the pdf.
312507 (2) [Avatar] Offline
#7
Errata in Angular in Action - Page 34
jeremy.wilken wrote:Hello, the link is still valid and works when I test it. You also do not need the script tag, as we don't use any of the JavaScript for that library in the example, just the CSS. I don't believe this is an issue, but if it is still please explain further.


Thanks, Jeremy. I don't know what happened but when I first attempted this it was definitely not working and would not apply the appropriate styles. Now it's working for me, as well. Sorry for the false alarm, maybe there was just some sort of networking issue occurring at the time on Google's end.
15339 (1) [Avatar] Offline
#8
In the 3.6.3 code sample, p. 71
<!-- isActive() returns true or false in order to set active class -->
<h1 class="leading" [class.active]="isActive()">Title</h1>
<!-- Renders to the following -->
<h1 class="leading accent">Title</h1>

the last line should have "accent" replaced by "active":
<h1 class="leading active">Title</h1>
272589 (1) [Avatar] Offline
#9
I played around with the custom phone number validator (Listing 9.3):

const expression = /((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}/;

export function PhoneValidator(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: any } => {
      const valid = expression.test(control.value) && control.value.length < 14;
      return valid ? null : { phone: true };
    };
}


Following minor observations:

A phone number such as "(012) 345-5678" (there is a space after the closing bracket) is not accepted because of the length check (< 14) but should be valid according to the regular expression. It is not quite clear to me, what the purpose of the length check is. The regular expression should be sufficient.

The regular expression should include ^ and $ to match start and end of the string, otherwise phone numbers such as "Bad123-1234" or "123-1234Bad" are accepted as valid.


mangelo (25) [Avatar] Offline
#10
Text on page 39
The bottom paragraph under Figure 2.5 says that the components/summary directory must be created manually. I don't recall this ever being the case even a few versions ago.
jeremy.wilken (205) [Avatar] Offline
#11
272589 wrote:I played around with the custom phone number validator (Listing 9.3):

const expression = /((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}/;

export function PhoneValidator(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: any } => {
      const valid = expression.test(control.value) && control.value.length < 14;
      return valid ? null : { phone: true };
    };
}


Following minor observations:

A phone number such as "(012) 345-5678" (there is a space after the closing bracket) is not accepted because of the length check (< 14) but should be valid according to the regular expression. It is not quite clear to me, what the purpose of the length check is. The regular expression should be sufficient.

The regular expression should include ^ and $ to match start and end of the string, otherwise phone numbers such as "Bad123-1234" or "123-1234Bad" are accepted as valid.




There are a lot of regexp for phone validators, this is merely one of them. I wouldn't get too caught up in the regexp but in the way to create validators. There are many phone formats that this might not accept, but could be valid.
jeremy.wilken (205) [Avatar] Offline
#12
Text on page 39
mangelo wrote:The bottom paragraph under Figure 2.5 says that the components/summary directory must be created manually. I don't recall this ever being the case even a few versions ago.


This was the case when it was written, but the CLI is capable of creating the directory tree today.
mangelo (25) [Avatar] Offline
#13
Page 47: When you run the application now, you should see the five default stocks...
We do not see the 5 default stocks at this point because of this line in the StocksService:

  load(symbols) {
    if (symbols) {
      return this.http.get<Array<StockInterface>>(service + '/stocks/snapshot?symbols=' + symbols.join());
    }
  }


The symbols array is empty at this point so this function doesn't return anything.
mangelo (25) [Avatar] Offline
#14
Page 47: When you run the application now, you should see the five default stocks...
mangelo wrote:We do not see the 5 default stocks at this point because of this line in the StocksService:

  load(symbols) {
    if (symbols) {
      return this.http.get<Array<StockInterface>>(service + '/stocks/snapshot?symbols=' + symbols.join());
    }
  }


The symbols array is empty at this point so this function doesn't return anything.


Disregard this post. I wish there was a delete button!! Found my bug!!