1

I have a typescript object like this

const playlist: { tracks: Array<Track> } = { tracks: new Array<Track>() };

And this is Track interface

interface Track {
  title?: string;
  album?: string;
  artists?: string;
  duration?: string;
  explicit?: boolean;
  url?: string;
}

I'm trying to get data from Spotify web API to my playlist object like this

for (let i = 1; i <= iterationCount; i++) {
    const endpointX = `${BASE_API_URL}playlists/${playlistId}/tracks?limit=${PLAYLIST_ITEM_LIMIT}&offset=${i}&fields=${fieldString}`;
    const subscription: Subscription = this.http.get<WritableTrackList>(endpointX).subscribe(data => {
      for (const item of data.items) {
        const track: Track = this.helperService.trackApiObject2TrackObject(item.track);
        this.playlist.tracks.push(track);
      }
    });    
}

When I try to print playlist object in the javascript console with console.log(this.playlist);, it's working. enter image description here

Buth I try to print playlist.tracks with console.log(this.playlist.tracks);, it's print an empty array

enter image description here

Why can't I access the tracks property of the playlist object? How can i access this property? Any solution?

Hirusha Fernando
  • 1,156
  • 10
  • 29
  • If you see the console.log(this.playlist), it has tracks: Array(0) means there is no item in that array, also there is i icon in front of it, hover over on it you will see message. The list that you are seeing is temporary adn changed after console.log – Anurag Oct 17 '21 at 05:33
  • When are you logging tracks property? Console.log is passed object reference. It might be possible that this.playlist is getting populated later. Can you try console.log(JSON.parse(JSON.stringify(this.playlist))) and see it still your list is populating? – Pankaj Sati Oct 17 '21 at 05:39
  • @PankajSati I tried that. It is not displaying the list. It is displaying an empty list – Hirusha Fernando Oct 17 '21 at 06:27
  • Does this answer your question? [Is Chrome's JavaScript console lazy about evaluating arrays?](https://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays) – Andriy Lozynskiy Oct 17 '21 at 07:28
  • @Hirusha Your list is getting populated inside of the subscription. Therefore, the values will become available only after that. There is no issue with this approach though if you intend to display/ modify items only when fetched. – Pankaj Sati Oct 17 '21 at 08:22

2 Answers2

0

try this :

console.log(this.playlist['tracks']);

if you want to use like this.playlist.tracks you must declare an interface for playlist:

interface PlayList{
tracks:Track[]
}
0

maybe try to print it inside the subscription.

    .subscribe(data => {
          for (const item of data.items) {
            const track: Track = this.helperService.trackApiObject2TrackObject(item.track);
            this.playlist.tracks.push(track);
          }

console.log([...this.playlist.tracks])

        }); 

// printing outside subscription will most likely give an empty array

although in general you would want something reactive

tracks$ = this.http.get<WritableTrackList>(endpointX).pipe(map(trackApiObject2TrackObject));

then in the template

<ng-template ngFor let-track[ngForOf]="tracks$| async">
<app-track [track]></app-track>
</ng-template>