I've been following the instructions in the book Pro Angular 9 written by Adam Freeman. I encountered an error on line 8:
private categories: string[] = [];
The error message reads:
Error: src/app/model/product.repository.ts:13:7 - error TS2322:
Type '(string | undefined)[]' is not assignable to type 'string[]'.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
I'm confused about how a variable can be both a string and an array at the same time.
To add to my confusion, Angular points out that the error is actually in line 13, not line 8. Here's what's on line 13:
this.categories = data.map(p => p.category).filter((c, index, array) => array.indexOf(c) == index).sort();
I don't fully understand what this line of code accomplishes other than mapping over an array with a filter function.
The file contains two more errors. On line 17:
getProducts(category: string = null): Product[] {
Type 'null' is not assignable to type 'string'.
In JavaScript, I would typically assign an empty string like this: var myString = ''
. Why use null as a string in TypeScript? Aren't they different types?
The third error is on line 22:
return this.products.find(p => p.id == id);
Type 'Product | undefined' is not assignable to type 'Product'.
Type 'undefined' is not assignable to type 'Product'.
This error is puzzling to me.
Below is the complete content of the file:
import { Injectable } from "@angular/core";
import { Product } from "./product.model";
import { StaticDataSource } from "./static.datasource";
@Injectable()
export class ProductRepository {
private products: Product[] = [];
private categories: string[] = [];
constructor(private dataSource: StaticDataSource) {
dataSource.getProducts().subscribe(data => {
this.products = data;
this.categories = data.map(p => p.category).filter((c, index, array) => array.indexOf(c) == index).sort();
});
}
getProducts(category: string = null): Product[] {
return this.products.filter(p => category == null || category == p.category);
}
getProduct(id: number): Product {
return this.products.find(p => p.id == id);
}
getCategories(): string[] {
return this.categories;
}
}
Here's product.model.ts
:
export class Product {
constructor(
public id?: number,
public name?: string,
public category?: string,
public description?: string,
public price?: number
) { }
}
This also resulted in an error:
Unexpected token. A constructor, method, accessor, or property was expected.
Could the error in line 22 be related to an issue in the Product
class? What seems to be problematic in the Product
class? It seems properly structured with a constructor.
I visited the GitHub repository for the book and downloaded the latest files, which were consistent with the material in the book.