Reputation: 93
I have following Interface to be used as a type for a JSON file :
export interface IIndustrySectors {
IndustrySector: string;
isSelected: string;
dataSubjectCategories:string[];
dataTypeCategories:string[];
SubIndustries:[{
IndustrySector: string;
isSelected: string;
dataSubjectCategories:string[];
dataTypeCategories:string[];
SubIndustries:[{}]
}]
}
and, two services:
// Read all the Data from the JSON file
getMainIndustrySectors(): Observable<IIndustrySectors[]> {
return this.http.get<IIndustrySectors[]>(this.industrySectorsURL).pipe(
tap(((data) => console.log('All: ' + data) )),
catchError(this.handleError)
);
}
//Get Specific object
getBySector(sector): Observable<IIndustrySectors| undefined> {
return this.getMainIndustrySectors().pipe(
map((products: IIndustrySectors[]) => products.find(p => p.IndustrySector === sector)));
}
Here is a part of the JSON file
[
{
"IndustrySector":"Accommodation and Food Service Activities",
"isSelected": "false",
"dataSubjectCategories":["DS.Employees","DS.Collaborators"],
"dataTypeCategories":"Personal Data",
"SubIndustries": [
{
"IndustrySector":"Food and Beverage Service Activities",
"isSelected": "false",
"dataSubjectCategories":[],
"dataTypeCategories":[],
"SubIndustries":[]
},
{
"IndustrySector":"Accommodation",
"isSelected": "false",
"dataSubjectCategories":["DS.Minor","DS.Parent","DS.Legal Person","DS.Natural Person","DS.Disable"],
"dataTypeCategories":[],
"SubIndustries":[]
}
]
}
]
The problem is when I call the service "getBySector" by following code:
this.readjsonService.getBySector(sector).subscribe(response=>{
if(response.dataSubjectCategories.length>0)
{
for(i=0; i<response.dataSubjectCategories.length;i++ ){
this.DSofSectores.push(response.dataSubjectCategories[i])
}
}
})
It tthrows an error:
TypeError: Cannot read property 'dataSubjectCategories' of undefined "
it prints the values, though.
Why is it?
what do is that based on the sector, I get in "response" other data related to it and fill an array of type string which are bind to dropdown list. It works fine, but the following image showes what happens after selecting the sub sector:
PLEASE help me , I am newbie and I am so sick of this :(( Thanks.
EDIT: when I say
if (response == undefined) {
throw new Error("sector not found");
}
else { .....
it passes the condition, meaning it is not undefined, yet it say "cannot read undefined"
Upvotes: 0
Views: 1780
Reputation: 27202
TypeError: Cannot read property 'dataSubjectCategories' of undefined "
As above statement suggest that you are trying to access dataSubjectCategories
of undefined object. Hence, response
is not an object.
Use response[0].dataSubjectCategories
instead of response.dataSubjectCategories
Demo
var response = [
{
"IndustrySector":"Accommodation and Food Service Activities",
"isSelected": "false",
"dataSubjectCategories":["DS.Employees","DS.Collaborators"],
"dataTypeCategories":"Personal Data",
"SubIndustries": [
{
"IndustrySector":"Food and Beverage Service Activities",
"isSelected": "false",
"dataSubjectCategories":[],
"dataTypeCategories":[],
"SubIndustries":[]
},
{
"IndustrySector":"Accommodation",
"isSelected": "false",
"dataSubjectCategories":["DS.Minor","DS.Parent","DS.Legal Person","DS.Natural Person","DS.Disable"],
"dataTypeCategories":[],
"SubIndustries":[]
}
]
}
];
var DSofSectores = [];
if(response[0].dataSubjectCategories.length>0) {
for(i=0; i<response[0].dataSubjectCategories.length;i++ ) {
DSofSectores.push(response[0].dataSubjectCategories[i])
}
}
console.log(DSofSectores);
Upvotes: 0
Reputation: 1294
In your getBySector
service, you say:
products.find(p => p.IndustrySector === sector))
Using Array#find
will return undefined
if no objects in the array match the selector, in this case if no products have IndustrySector === sector
. This is why the service is required to have a return type of Observable<IIndustrySectors|undefined>
.
If you're seeing this error at compile-time, or as an error in your IDE, it's because of this return type; it knows that the response can be undefined
and therefore, you have to account for that possibility. Changing your consuming code to the following should fix the problem:
this.readjsonService.getBySector(sector).subscribe(response => {
if (response !== undefined) {
if(response.dataSubjectCategories.length > 0) {
for(let i = 0; i < response.dataSubjectCategories.length; i++) {
this.DSofSectores.push(response.dataSubjectCategories[i])
}
}
}
})
But be aware that this means that, at runtime, when a sector
is passed in that doesn't match any products, the for
loop will not be executed.
Upvotes: 1
Reputation: 54771
The filter method does not find a match. So the observable is yielding a undefined
.
getBySector(sector): Observable<IIndustrySectors| undefined> {
return this.getMainIndustrySectors().pipe(
map((products: IIndustrySectors[]) => products.find(p => p.IndustrySector === sector)));
// ^^^ matches none
}
Upvotes: 1