-2

I have the following JSON definitions:

 export class Company {
      name: string;
      trips : Trip[] = [];
    }

export class Trip{
    id: number;
    name: string;        
}

I am able to see the trips in the console using:

console.log(this.company);

In the component I have the following method:

if(this.company) {
     Object.keys(this.company.trips).forEach((data) => {     
            console.log(data);                        
        });
}

What I am getting in the console is the trip's properties names which is "id" and "number". I would like to know how to access the value.

user2304483
  • 1,462
  • 6
  • 28
  • 50
  • 1
    why are you using `Object.keys`? – Jota.Toledo Feb 21 '19 at 10:20
  • `this.company.trips.forEach(trip => { console.log('trip.id', trip.id })` – Julien METRAL Feb 21 '19 at 10:21
  • *"What I am getting in the console is the trip's properties names which is "id" and "number"."* That's odd. You've said it's an *array*. The keys of an array are numeric strings (`"0"`, `"1"`, etc.), not things like `"id"` and `"number"`. – T.J. Crowder Feb 21 '19 at 10:23
  • On a side note: If these are representations of data coming from an api, I would strongly suggest that you make these interfaces instead, because these will not be instances of the class. You might be falling into a problem of testing for a constructor (`instanceof`) and not get what you expect. – Silvermind Feb 21 '19 at 10:24
  • `Object.keys` gives you the names of the own, enumerable, String-named properties of the object. If you want the values, you can use [`Object.values`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values) which returns an array of the values of those properties. If you want both, you can use [`Object.entries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) which returns an array of `[key, value]` arrays. Normally, though, you know the shape of the object and use its properties directly. – T.J. Crowder Feb 21 '19 at 10:27
  • I've changed from keys to values and now I am to see the values but I get both id and name I need only the value of the name. Any idea how to access ? – user2304483 Feb 21 '19 at 10:32

1 Answers1

0

According to your data structure, you should not even try to do Object.keys what you should be doing as the Trip is an object, is something like following in which you treat the iteration object as a real Trip object

if(this.company && this.company.trips){
this.company.trips.forEach((trip:Trip) => {     
            console.log(trip.id + '\n' + trip.name);                        
        });
}

if you have any issue with this piece of cod then make sure you are correctly doing your deserialization process and objects are getting cast properly.

Thriller
  • 485
  • 4
  • 11
  • I'm getting ERROR TypeError: this.company.trips.forEach is not a function – user2304483 Feb 21 '19 at 10:40
  • @user2304483 then you are facing the casting issue as I thought. there is a library for casting I guess it might be a good idea to give it a go. https://github.com/typestack/class-transformer – Thriller Feb 21 '19 at 10:43
  • you might also take a look at this tread https://stackoverflow.com/questions/35969974/foreach-is-not-a-function-error-with-javascript-array – Thriller Feb 21 '19 at 10:49
  • you mean the trips is not coming as array from the api ? – user2304483 Feb 21 '19 at 10:49
  • No I mean the deserialization problems in Angular side when you try deserialize JSON coming from server to objects – Thriller Feb 21 '19 at 10:50
  • I've changed the code to cast to array and now I'm getting the values {id: 1, name: "ABC"} but I need to access only the name. I need way to fetch only the name. This is the current code: if(this.company) { const parent = this.company; console.log(parent.trips); Array.prototype.forEach.call(parent.trips, child => { console.log(child) }); } – user2304483 Feb 21 '19 at 10:58
  • have you tried doing a cast on the child like: `Array.prototype.forEach.call(parent.trips, (child:Trip) => { console.log(child.name) }); }` ? – Thriller Feb 21 '19 at 11:04
  • if this also doesn't work then you should convert the child in the execution code with any method you know, such as the ones you can find here https://stackoverflow.com/questions/40421100/how-to-parse-a-json-object-to-a-typescript-object – Thriller Feb 21 '19 at 11:08
  • it doesn't work I still get the full Trip object. Do I need to change something in the Trip class to make it work ? – user2304483 Feb 21 '19 at 11:17
  • can you make a working version on stack blitz so I can take a look? – Thriller Feb 21 '19 at 11:18
  • I don't think so because the object is coming from API. – user2304483 Feb 21 '19 at 11:20
  • well, you could just fake your service with 3-4 data in a JSON string. the problem is I don't get it why you should get `{id: 1, name: "ABC"}` on the normal loop but the casting to Trip is not working. usually when you have `{id: 1, name: "ABC"}` and you cast to `Trip` the child should be a real `Trip` object that you can do `child.name` – Thriller Feb 21 '19 at 11:23
  • I actually don't get nothing, the console.log(child) doesn't work – user2304483 Feb 21 '19 at 11:32
  • but you just said: "I've changed the code to cast to array and now I'm getting the values {id: 1, name: "ABC"} but I need to access only the name. " I don't understand. let's do something, can you copy here the json for 2 companies so I can make a stackblitz example for you? – Thriller Feb 21 '19 at 13:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188919/discussion-between-user2304483-and-thriller). – user2304483 Feb 23 '19 at 07:24
  • I had a console.log before the loop, that's why I said that, I'm still with tis problem – user2304483 Feb 28 '19 at 06:50