Guidelines for cycling through a series of HTTP requests and effectively saving the data from each cycle into an array

Utilizing Spotify's API search feature, I am working with an array of SongSearchParams that consist of title and artist parameters:

export class SongSearchParams {
    public title: string;
    public artist: string;

    constructor(title: string, artist: string){
        this.title = title;
        this.artist = artist;
    }
}

The HTTP request structure is as follows:

  searchTrack(searchParams: SongSearchParams, type='track'){
    var headers = new Headers({'Authorization': 'Bearer ' + this.hash_params.access_token});
    this.user_url = "https://api.spotify.com/v1/search?query="+searchParams.artist+' '+
                    searchParams.title+"&offset=0&limit=1&type="+type+"&market=US";

    return this.http.get(this.user_url, {headers : headers})
      .map(res => res.json());
  }

Within a TypeScript file of one of my components, I have access to the SongSearchParams array. When a specific button is clicked, I aim to pass each element of this array through the searchTrack function to fetch details like album image, track name, and artist of a song.

onClick(){
  for(let searchQuery of this.songService.songSearches){ 
    this.spotifyserv.searchTrack(searchQuery)
      .subscribe(res => {
        this.searchedSong.artist = res.tracks.items[0].artists[0].name;
        this.searchedSong.title = res.tracks.items[0].name;
        this.searchedSong.imagePath = res.tracks.items[0].album.images[0].url;
        console.log(this.searchedSong);
        this.songService.addSong(this.searchedSong);
      })
  }
}

Upon execution of this code, it seems only the last song in the array is persistently stored despite logging all songs correctly during iterations.

To resolve this issue, some resources suggest utilizing Promises sequentially via the then() method. Therefore, I attempted to incorporate this into the searchTrack functionality:

A potential problem could lie within my addSong function implementation:

addSong(song: Song){
    this.songs.push(song);
    this.songsChanged.next(this.songs.slice());
}

If the above function appears correct, considering another approach like chaining promises might be beneficial (despite failed attempts).

Answer №1

In my opinion, exploring the forkjoin method could be helpful.

Here's a potential implementation:

let queryArray = [];

for(let term of this.musicService.searchTerms) {
    queryArray.push(this.spotifyService.findTrack(term));
}

Observable.forkJoin(queryArray)
    .subscribe(data => {
        // data[0]
        // data[1]
        // ...
        // data(n)
    });

Answer №2

After some trial and error, I managed to find a solution to my issue even though the exact reason behind it remains unclear (I can only speculate).

In the onClick() method of my class, there was a private member named songSearched of type Song which I was attempting to update for each song added to the list. Instead, I decided to modify the function as follows:

onClick(){
  for(let searchQuery of this.songService.songSearches){ 
    this.spotifyserv.searchTrack(searchQuery, 
          response => {
            let res = response.json();
            console.log(res.tracks.items[0].album.images[0].url);
            console.log(res.tracks.items[0].name);
            console.log(res.tracks.items[0].artists[0].name);
            let searched_song = {artist : null, title : null, imagePath : null}
            searched_song.artist = res.tracks.items[0].artists[0].name;
            searched_song.title = res.tracks.items[0].name;
            searched_song.imagePath = res.tracks.items[0].album.images[0].url;
            console.log(searched_song);
            //song_queue.push(searched_song);
            this.songService.addSong(searched_song);
          }
    )
  }
}

Instead of updating the same searched_song repeatedly, I created a new one within the function itself, ensuring that a separate searched_Song is available for each request. It seems that initially, I was overwriting the existing searchedSong, resulting in multiple searches being overwritten before being added to the list.

However, this does not clarify why the console log worked in the previous line during my initial attempt.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The final thumbnail fails to appear in the visible display (react-responsive-carousel)

I am currently facing an issue with displaying a series of images using react-responsive-carousel. When the images exceed a certain size causing the thumbnail section to become scrollable, the last thumbnail is always out of view. Although I have impleme ...

Declare that a method alters a value with state

Here's a more streamlined version of my code. Check out my custom hook below: export const useStep = () => { const [step, setStep] = useState<Steps>("sending"); const changeStep = (newStep: Steps) => setStep(newStep); return { ste ...

What is the proper way to reference a property's value within another property of the same JavaScript Object?

Within a Gulp.js file (or any Javascript file), I have defined paths in a Javascript object: var paths = { devDir : 'builds/development/', devDirGlobs : this.devDir+'*.html' } I am attempting to reference the pro ...

Substitute a JSONP API call using $.ajax() with a direct server-to-server API call

My javascript application utilizes an ajax function that has the following structure: $.ajax({ url: apiURL, dataType: 'jsonp', success: function(data) { if (data.ok) { //perform actions }}}); Everything was working perfectly until I ...

Access exclusive content by subscribing now!

How can I return a reference to a subject from a service without allowing the receiver to call .next() on the subject? Let's say there is a service with a subject that triggers new events. class ExampleService { private exampleSubject = new Subjec ...

The type 'Navigator' does not have the property 'userAgentData' in its definition

Since I'm looking to minimize the information provided by navigator.userAgent, I decided to migrate to User-Agent Client Hints. However, I've encountered an error while attempting to do so: https://i.stack.imgur.com/lgIl7.png Could someone plea ...

jQuery appears to be unresponsive or inactive

I'm trying to implement a jQuery script that will slide in a header after scrolling on the page, but for some reason, it's not working. When I reach the 3rd line, my code editor displays a !read only alert, suggesting there may be a syntax issue? ...

Creating a Star Rating System Using HTML and CSS

Looking for help with implementing a Star rating Feedback on articles in Visualforce page. Came across some code that seems to fit the bill but facing issues with getting it to work when placed in a file and executed, particularly in Firefox. Any assistanc ...

Button press triggers the fadeIn function successfully, but the keypress event does not have the same effect

I'm currently facing an issue with two div elements on my webpage. I want only one of them to be visible at a time, depending on which key is pressed. If the 1 key is pressed, I want 'div1' to fadeIn (if it's not already visible) and fo ...

typescript ways to exclude enum values

I am working with enums in TypeScript. enum Status { Cancelled = 'cancelled', Completed = 'completed', Created = 'created' } Now, I need to create another enum that includes only the values Completed and Created. enum S ...

Navigating to a Different Page in React Based on Button Click and Meeting Specific Conditions

Within this particular component, I have implemented a button named Submit. When this button is clicked, it triggers a series of actions: first, it exports the drawing created by the user as a jpeg URL, then sends this image data to another API that genera ...

Could Express be considered the most reliable and efficient application framework for NodeJS?

While I have some experience with Express, I haven't explored many other Node-based web application frameworks. It's clear that Express is lightweight and versatile, but my usage has been limited to small experimental projects rather than large-s ...

React is unable to assign a class field beyond the scope of axios

class App extends React.Component { app: Application; ... componentDidMound() { axios.get(…).then(res => { this.app.currentUser = res.data.data; // setting value inside lambda function. console.log(this.app.currentUser); // ...

Struggling to import MUI components from node modules in your React JavaScript project using Vite? Discover why autosuggestion isn't getting the

Encountering a dilemma with autosuggestion in Visual Studio Code (VSCode) while attempting to import MUI (Material-UI) components from node modules in my React JavaScript project built with Vite. The autosuggestion feature is not working as intended, causi ...

TypeScript overloading error: Anticipated 0 parameters, received 2 instead

I am facing an issue with a class containing an overloaded method that has two versions. One version does not take any arguments, while the second one can take two arguments. class DFD { ... getEndDatetime(): string; getEndDatetime(startTime?: ...

Display conceal class following successful ajax response

Upon clicking the button, the following script is executed: $.ajax({ url: "<?php echo CHILD_URL; ?>/takeaway-orders.php", type: 'POST', async:false, data: 'uniq='+encodeURIComponent(uniq)+'&menu_id=' ...

The 'resp' parameter is assumed to have an unspecified type, shown as 'any'. This is an error in Angular

} ErrorHandler(response){ console.debug(response.json()); } DataHandler(response){ this.ClientModels = response.json(); } I have developed two functions to handle error and success responses, but an error message is showing up saying "para ...

When attempting to import my JSX file into page.js, I continue to encounter the error "module not found." How can I troubleshoot and resolve this issue in Visual Studio Code

I recently created a new file called mysec.jsx in the components folder of src. I then used the export function to properly export it. However, when I tried to import this file in page.js using the import function, I encountered an error message that said: ...

Utilizing D3 to fetch geographic data in the form of a TopoJSON file for U.S. counties

After retrieving a set of coordinates, the goal is to use D3 to find the corresponding county from a U.S. TopoJSON file. Here is an example code snippet: navigator.geolocation.getCurrentPosition(function(position) { let coordinates: [number, number] = [p ...

Create a table by incorporating the information from the page along with additional content

I need to extract the data from a list and convert it into a table, add some additional content that I will provide, and then align the table accordingly. While I can easily align elements and already have the list, I am facing difficulty in converting it ...