The issue at hand is with the Typescript part of an Angular app.
I have a data array I've received from a subscription; it contains several (but not a consistent or predictable number of) objects with members "titleName" and "ID". I need to add the member "toggle", which will be interacted with within the component. Due to the database call in question and its other uses, I can't realistically add "toggle" on the services side. I've tried the following:
titlesraw;
titles: any;
...
getTitles() {
this.getTitles.subscribe(
data => {
this.titlesraw = data;
console.log(this.titlesraw); //console reads what I expect
for (var i = 0; i < this.titlesraw.length; i ) {
let title = {
id: this.titlesraw[i]["ID"];
titleName: this.titlesraw[i]["titleName"];
toggle: true;
}
console.log(title); //console reads what I expect
this.titles.push(title);
}
}
)
}
When I run the code, I get the following error:
ERROR TypeError: Cannot read properties of undefined (reading 'push') at <line with this.titles.push(title)>
I think this is because I'm not declaring titles
correctly. What do I need to do differently?
EDIT: I've changed titles: any;
to titles: any[] = [];
, and I get the following error instead:
Cannot read properties of undefined (reading 'ID') at <line with this.titles.push(title)>.
Again, when I do the printout of the temporary variable title
, it shows me exactly what I expect.
CodePudding user response:
You can do it very easily with map
function.
Let me explain to you. Here, I am assuming that you are receiving an array
of objects
from an Api
call. You can modify your response using map
function of arrays
like this.
titles = [];
this.getTitles.subscribe(data => {
this.titles = data.map((titleObject) => {
titleObject.toggle = true;
return titleObject;
})
})
CodePudding user response:
Well, first of all let me point out some good practices while working with TypeScript.
Stick to types and avoid using
any
. Check this article for better understanding. But basically, when you start usingany
you "...are saying no thank you when over 500 contributors to the language offer their help. It sounds like to opt-out of the type checker, and with it, losing all security and confidence in our type system should not be a decision taken lightly." I am not saying you should never use it, even because there will be cases where you are going to need it, so just avoid it, especially in this specific case.Create types/models for your objects.
You don't need
titlesraw
, at least in this piece of code that you're showing up.
Based on it and answering your question, the problem is due because titles
is not of Array
type. push
is a method from Array
type, thus your titles
should be an Array
for this to work.
With that said, here's how your code should look like:
class Title {
id: number;
titleName: string;
toggle: boolean;
}
titles: Title[] = [];
...
getTitles() {
this.getTitles.subscribe(data => {
for (var i = 0; i < this.data.length; i ) {
const title: Title = {
id: this.data[i]["ID"],
titleName: this.data[i]["titleName"],
toggle: true
}
this.titles.push(title);
}
}
)
}