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

Access Images from Server using Front-End Technology

I have a collection of images stored in a server folder that I want to display on a div element using client-side code. Initially, I tried to achieve this with AJAX, but it returned raw data instead of the image URL. Despite my efforts to find a solution, ...

Tips for eliminating double quotes from an input string

I am currently developing an input for a website that will generate a div tag along with its necessary child elements to ensure the website functions correctly. I have a couple of key questions regarding this setup: <!DOCTYPE html> <html> < ...

Create a new column in Material UI Grid by adding an empty div element instead of using padding

I'm currently getting acquainted with Material UI Grid and I am interested in adding an empty column (a blank space on the right of the first element) without utilizing padding. How can this be achieved? Here's a snippet of the code being discus ...

The input value fails to update after the method is called

I am working on developing a todo-list application and here is the code I have so far: HTML: <div class="divPadder"> <input ref="makePlaceholderEmpty" class="inputBoxSize" type="text" :placeholder="placeholder"v-model="task"> <ul> ...

Once the div content is reloaded using AJAX, the refreshed HTML suddenly vanishes

My JS code reloads the div every 2 seconds: var auto_refresh = setInterval(function() { $('#indexRefresh').load('/includes/index_refresh_include.php?_=' + Math.random()); }, 2000); After that, I have an AJAX request that loads mor ...

There appears to be a malfunction with WebRupee

I have incorporated the new rupee sign into my website to represent Indian currency. Below is the code snippet I used: For the script, I included " and also added the following: <span class="WebRupee">Rs.</span> 116,754.00 To style it using ...

The issue of execution order in JavaScript Recursion with promises

In the process of developing a method for creating markup to be used in a web app's off-canvas navigation. One of the challenges I am facing is making an asynchronous callback to another service that provides children nodes for the parent menu node (r ...

Is there a way to use a single url in Angular for all routing purposes

My app's main page is accessed through this url: http://localhost:4200/ Every time the user clicks on a next button, a new screen is loaded with a different url pattern, examples of which are shown below: http://localhost:4200/screen/static/text/1/0 ...

Develop a structured type that encompasses the stationary attributes of an object-oriented class

Provided are the following classes: class EnumerationDTO { designation: string; id: number; } class ExecutionStatusDTO extends EnumerationDTO { static readonly open: ExecutionStatusDTO = { id: 0, designation: 'Open' }; static readonl ...

Leveraging Services in Classes Outside of Angular's Scope

I have a scenario where I am working with Angular v7.3.5 and I need to utilize a Service in a non-Angular class. Below is an example of what I'm trying to achieve: foo.model.ts import { Foo2Service } from './foo2.service'; // Definition fo ...

Sending information from React JS to MongoDB

I am currently facing a challenge in sending data from the front-end (react js) to the back-end (node js), and then to a mongodb database for storage. While I have successfully called the server with the data, I am encountering an issue when attempting to ...

Delightful Popup for Successful Woocommerce Additions

I have created a plugin that transforms Wordpress Woocommerce variations into a table layout. I made significant changes to the code and now I'm attempting to integrate Sweet Alerts 2 in place of the current alerts displayed when a user adds a product ...

While the data from Angular $resource can be viewed, it is not accessible in the code

As a newcomer to Angular, I'm facing a frustrating issue that I need help with. My $resource is fetching data from the server in key/value pairs like detail.name and detail.email. While I can access this data using {{detail.name}} in the view, I&apo ...

An option selection component for Vue.js

I'm attempting to design a component like the following: <template> <option v-for="(text, value) in options" :value="value"> {{ text }} </option> </template> Unfortunately, I encountered an error me ...

Styling with the method in React is a beneficial practice

I am working on a simple React app that includes some components requiring dynamic styling. I am currently using a method to achieve this, but I am wondering if there are other recommended ways to handle dynamic styling in React. Everything seems to be wor ...

Transfer information through the react-native-ble-plx module

To initiate a project involving connected devices, I must establish a Bluetooth connection among the different devices. The objective is to develop an application using React Native and then transmit data from this application to my Raspberry Pi. The Rasp ...

Refreshing a specific div within an HTML page

I am facing an issue with the navigation on my website. Currently, I have a div on the left side of the page containing a nav bar. However, when a user clicks a link in the nav bar, only the content on the right side of the page changes. Is there a way t ...

Combining JSON objects in Node.js

I am extracting data from my database and converting it to JSON format. However, I now want to merge all the JSON data into a single JSON object. I have attempted various methods, but due to my limited knowledge of JavaScript syntax, I have not been able ...

The error message "Declaration file for module 'mime' not found" was issued when trying to pnpm firebase app

Currently, I am in the process of transitioning from yarn to pnpm within my turborepo monorepo setup. However, I have run into an issue while executing lint or build commands: ../../node_modules/.pnpm/@<a href="/cdn-cgi/l/email-protection" class="__cf_e ...

I'm looking for the specific jQuery/JavaScript function that will accomplish this task

let data = [{ name: "abcd", type: "1 kg" }, { name: "efgh", type: "1 cai" }, { name: "ijkl", type: "1 kg" }]; If I have the name, I would like to get the corresponding type. For example, if I call getType('abcd'), it sho ...