Combining Rxjs map and filter to extract countries and their corresponding states from a JSON dataset

I have a unique dataset in JSON format that includes information about countries and states. For example:

 {
  "countries": [
    {
      "id": 1,
      "name": "United States"
    },
    {
      "id": 2,
      "name": "India"
    }],
  "states": [
    {
      "id": 1,
      "countryId": 1,
      "name": "Alabama"
    },
    {
      "id": 2,
      "countryId": 1,
      "name": "Alaska"
    } ] }

With this data, I created a Service to retrieve the countries and states for displaying in dropdown menus:

export class CountriesService {

  constructor(private http: HttpClient) { }

  public getCountries(): Observable<Country[]> {

    return this.http.get<Country[]>("assets/data.json").pipe(map(obj => obj["countries"]));

  }

  public getStates(countryId: number): Observable<State[]> {
    return this.http.get<State[]>("assets/data.json").pipe(
      map(res => res["states"]), 
      map(res => { if (res.countryId === countryId) return res;}));

  }
}

Although the getCountries() method works perfectly, fetching all the countries, I am facing issues retrieving specific states based on the countryId using the getStates method.

Currently, this method is not returning any results. Any idea what might be going wrong?

Answer №1

Ensure to apply the filter once the data is acquired.

export class CountriesService {
  constructor(private http: HttpClient) { }

  public getCountries(): Observable<Country[]> {
    return this.http.get<Country[]>("assets/data.json").pipe(
      map(obj => obj["countries"]),
    );
  }

  public getStates(countryId: number): Observable<State[]> {
    return this.http.get<State[]>("assets/data.json").pipe(
      map(res => res["states"]), 
      withLatestFrom(of(countryId)),
      map((id, states) => states.filter(state.countryId === id)),
    );
  }
}

It is also recommended to merge all information together to prevent multiple requests for state data which remains constant.

export class CountriesService {

  constructor(private http: HttpClient) { }

  public getCountriesWithStates(): Observable<Country[]> {
    return this.http.get<Country[]>("assets/data.json").pipe(
      map(data => data.countries.map(country => ({
        ...country,
        states: data.states.filter(state => state.countryId === country.id),
      }))),
    );
  }
}

service.getCountriesWithStates().subscribe(countries => {
// countries[0].states[0];
});

Answer №2

When the API call returns an observable, it is actually emitting an array due to your map function, not an array of observables. Therefore, the second map function you are using is not functioning as expected. Instead, within the first map, you can filter out the states that have the desired country id by utilizing a method called filter which is available on JavaScript arrays.

public getStates(countryId: number): Observable<State[]> { return this.http.get<State[]>("assets/data.json").pipe( map(res => res["states"].filter(res => res.countryId === countryId)); }

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

Developing an Azure pipeline to generate artifacts for an Angular Universal application

I am currently facing an issue with deploying my Angular Universal app to Azure Web App Service. Running npm run build:ssr && npm run serve:ssr locally works perfectly fine. Similarly, running npm run start without ssr rendering also works smoothly ...

The wrap() method in jQuery clones elements multiple times

I have created a simple function that wraps a div tag inside another div tag when the browser window exceeds a certain width of x pixels. However, I've encountered a strange bug when resizing the page more than once. Let me share with you the jQuery ...

Creating a consistent base URL for both Vue and Apache reverse proxy configurations

Currently, I am experimenting with a Vue app and testing it using pm2 in conjunction with Apache. After starting the app with pm2 and running it on port 3000, I then utilize an Apache reverse proxy to access the app through a domain and HTTPS. However, I e ...

Encountering issue with POST operation in GraphQL on Angular application integrated with AWS Amplify and DynamoDB

I am in the process of developing a basic Angular application using AWS Amplify with a DynamoDB backend. To handle GraphQL API calls, I utilized the amplify add API command to generate the necessary code. My current objective is to populate a table with ...

The issue of the marker vanishing upon refreshing the page on AngularJS

Currently, I am encountering a rather peculiar issue. Upon the initial page load, the code snippet below correctly displays a marker at the specified coordinates and ensures the map is properly centered: <div class="paddingtop"> <map data-ng- ...

Encountering issues with verifying login credentials in Angular 2

Greetings! I have designed a login page where the user will be logged in if the response is successful, otherwise an error message will be displayed. Below is the JSON data with email and password fields: { Email": "<a href="/cdn-cgi/l/email-protect ...

Click to add a different template into the document

My HTML page consists of a form with multiple input fields and a carousel. Towards the bottom of the form, there is a button labeled Add another quote. This button essentially duplicates the input fields above (all contained within class="quote"). Here&ap ...

A more efficient method for querying documents based on ids that are not in a given list and then sorting them by a specific publish date

After implementing the code provided below, I noticed that the performance tests indicate each request takes a second or longer to complete. My goal is to enhance this speed by at least 10 times. The bottleneck seems to be caused by the NOT operator resu ...

I am looking to transfer an image stored in a database onto a card

One issue I am facing is that when trying to display an image from a database, uploaded by a user and showing on a card with additional information like name and price, an icon resembling a paper with green appears in the output. Here's my code snippe ...

Having trouble fetching JSON response in Scalatra with JPA for ORM implementation

I am currently utilizing JPA for data modeling within Scalatra. My data model consists of a structure where one class has a variable as an object of another class, which in turn contains a list of objects from a different class (forming a transitive relati ...

Ways to forward a webpage once validation has been completed

I have a login form that is being validated using jQuery/Ajax to receive a JSON response. The form calls a PHP page called add-data.php. Upon successful validation, I want to redirect to another page after displaying the message Successfully logged!: if ...

Tips for implementing event handlers on dynamically generated li elements in VueJS

Creating multiple ul elements using v-for in the following way <div v-for="item in info"> <ul> <li><a>{{item.number}}</a></li> <li><a>{{item.alphabet}}</a></li> </ul> </div&g ...

Tools for parsing command strings in NodeJS

Currently, I'm utilizing SailsJS for my application. Users will input commands through the front-end using NodeWebkit, which are then sent to the server via sockets. Once received, these commands are parsed in the back-end and a specific service/cont ...

Angular 6 - Resolving the Issue of 'Function calls are not supported in decorators' in Production Builds

Currently, I'm in the process of developing a cutting-edge Angular 6 application. However, as I was progressing with the development phase and tried to create a prod build using the following command: ng build --prod To my dismay, I encountered a pe ...

MQTT: The method net.createConnection does not exist

Following the guide at https://www.npmjs.com/package/mqtt#install to establish an mqtt connection, I encountered a render error indicating _$$_REQUIRE_(dependencyMap[1], "net").createConnection(port, host)','_$$_REQUIRE(_dependencyMap[ ...

How to completely disable a DIV using Javascript/JQuery

Displayed below is a DIV containing various controls: <div id="buttonrow" class="buttonrow"> <div class="Add" title="Add"> <div class="AddButton"> <input id="images" name="images" title="Add Photos" ...

Show or hide a Div based on radio button selection problem

I've successfully implemented a Div visibility toggle using the code below: $('input[name="type"]').on('change', function() { var show = $(this).val(); $(".typechoice").hide(); $("#"+show).show(); }) <script src="h ...

Load jQuery results when scrolling to the top of the window

I have a function that triggers when I click a button to fetch more data from my table. I'm attempting to make it work when the button reaches a certain distance from the top of the window, but I've been unable to achieve this so far... $(funct ...

What is the method for breaking a statement within an if statement on Blogger when both the IF and ELSE conditions are met?

I'm making some adjustments to the labels on my blog to ensure that each post has at least two labels. The concept is that if a post has LABEL 1, it will load one script, otherwise it will load another. However, I've encountered a situation wher ...

Removing a targeted element from an array in Angular

After receiving a JSON array object in Angular using TypeScript, I am attempting to remove a specified object from it. However, my attempts at deletion have been unsuccessful. addCategorySub(categorySub: CategorySubModel, index: number) { categorySub.id ...