What is the procedure for extracting specific elements from a JSON response and transforming them into an array that adheres to a defined

In order to retrieve the JSON response of a GET request made by a service within my app to our backend, extract specific parts from it, and store them in an Array based on an Interface I have created for future use.

Here is a sample of the JSON data:

[{
        "id": 1,
        "name": "Lar das meninas",
        "latitude": -23.6695527,
        "longitude": -46.603418,
        "about": "About the orphanage",
        "instructions": "Come visit us",
        "opening_hours": "From 8am to 6pm",
        "open_on_weekends": false,
        "directory": {
            "directoryName": "/PROD/FILE",
            "server": {
                "serverName": "XYZ34"
            }
        }
    },
    {
        "id": 2,
        "name": "Petito Orphanage",
        "latitude": -23.6740118,
        "longitude": -46.6066612,
        "about": "About the orphanage",
        "instructions": "Come visit us",
        "opening_hours": "From 8am to 6pm",
        "open_on_weekends": false,
        "directory": {
            "directoryName": "/PROD/FILE",
            "server": {
                "serverName": "XYZ34"
            }
        } 
    }
]

I am interested in extracting the fields name, latitude, longitude, directoryName, and serverName from this data. To achieve this, I defined an interface as follows:

export interface Orphanage {
  name: string,
  latitude: number,
  longitude: number
}

My initial attempt was to utilize TypeScript's matching mechanism to map these fields, calling the HTTP endpoint using the provided service, but the console output displayed the entire response instead of the required fields.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'
import { Orphanage } from './orphanage';
import { tap } from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class OrphanageService {

  constructor(private http: HttpClient) { }

  getOrphanages() {
    return this.http.get<Orphanage[]>('http://localhost:3333/orphanages').pipe(
      tap((res: Orphanage[]) => console.log(res))
    );
  }
}

I attempted another approach by subscribing to the Observable returned by the service within the component, assigning the extracted data to a property, and logging it, yielding the same undesired outcome.

import { Component, OnInit } from '@angular/core';

import { Orphanage } from '../orphanage';
import { OrphanageService } from '../orphanage.service';

@Component({
  selector: 'app-orphanages-main',
  templateUrl: './orphanages-main.component.html',
  styleUrls: ['./orphanages-main.component.scss']
})
export class OrphanagesMainComponent implements OnInit {

  orphanages: Orphanage[];

  constructor(private orphanageService: OrphanageService) { }
 
  ngOnInit(): void {
    this.orphanageService.getOrphanages()
    .subscribe((orphanages: Orphanage[]) => {
      this.orphanages = orphanages;
      console.log(this.orphanages);
    });
  }
}

To effectively filter out only the necessary fields and address the nested structure including directoryName and serverName, further steps and adjustments need to be undertaken.

I appreciate any guidance or insights on how to proceed in achieving this goal.

Thank you!

Answer №1

To transform emitted data, you can utilize the RxJS map operator or the Array#map method to create a new array based on existing array properties. Here is an example:

Data Structure

export interface Orphanage {
  name: string;
  latitude: number;
  longitude: number;
  directoryName: string;
  serverName: string
}

Data Fetching Service

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

  getOrphanages() {
    return this.http.get<Orphanage[]>('http://localhost:3333/orphanages').pipe(
      map(orphanages =>
        orphanages.map(orphanage => {
          return <Orphanage>{
            name: orphanage['name'],
            latitude: orphanage['latitude'],
            longitude: orphanage['longitude'],
            directoryName: orphanage['directory']['directoryName'],
            serverName: orphanage['directory']['server']['serverName']
          }
        })
      ),
      tap((res: Orphanage[]) => console.log(res))
    );
  }
}

Component Implementation

export class OrphanagesMainComponent implements OnInit {
  orphanages: Orphanage[];

  constructor(private orphanageService: OrphanageService) { }
 
  ngOnInit(): void {
    this.orphanageService.getOrphanages().subscribe({
      next: (orphanages: Orphanage[]) => {
        this.orphanages = orphanages;
        console.log(this.orphanages);
      },
      error: (error) => {
        // Handle HTTP errors appropriately
      }
    });
  }
}

Note: It is advised to pass object with next and error callbacks to subscribe as directly passing callbacks is deprecated.

Answer №2

To convert the JSON data into Orphanage array, utilize the JavaScript map method. Then, transform each piece of information received in the Observable's stream into an Orphanage array using the rxjs map operator:

export interface Orphanage {
  name: string;
  latitude: number;
  longitude: number;
  directoryName: string;
  serverName: string;
}

 getOrphanages(): Observable<Orphanage[]> {
    return this.http.get<any[]>('http://localhost:3333/orphanages').pipe(
      map(this.transformJsonToOrphanages)
    );
  }


 transformJsonToOrphanages(json): Orphanage[] {
   return json.map((jsonObj): Orphanage[] => {
      return {
         name: jsonObj.name,
         latitude: jsonObj.latitude,
         longitude: jsonObj.longitude,
         directoryName: jsonObj.directory.directoryName,
         serverName: jsonObj.directory.server.serverName
      }
    })
 }

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

Tips for sending a timestamp as input to a stored procedure in TypeScript with the mssql module

Currently, I am utilizing the mssql npm package to communicate with SQL server. I have encountered a dilemma where the variable (which is of type TIMESTAMP in sql server) fetched from a stored procedure is returned as a byte array. Now, I need to pass this ...

Resolving the Issue: How to Solve the "Missing Required Request Body" Error in Angular and Spring MVC

I'm encountering an issue with removing a product from the database using Angular on the frontend. The error message I am receiving is: Required request body is missing: public boolean prodcust.controller.DeleteController.deleteProduct(java.lang.Stri ...

Angular2 with Typescript is experiencing issues with the implementation of operations in JavaScript

I'm struggling to implement a D3 graph example in my Angular 2 TypeScript application. The issue arises with the lines marked with "----> Error". I have no clue on how to tackle this problem. Can anyone offer some assistance? d3.transition().dura ...

Exploring the process of linking a C# REST API to an Ionic 2 mobile application

I am completely lost on how to connect an asp.net web api with my ionic 2 mobile app. Any help or advice on resolving this problem would be greatly valued! ...

I must connect a TypeScript class to an Angular component

Here is an example of element class export class Element { fields = [] } And here are two field classes export class SmallText { value constructor(value) { this.value = value } } export class LargeText { value construct ...

Error Encountered when Deploying Angular App on Heroku - Issue with Application, H10 Status Code

I have been struggling to deploy my Angular 7 application on Heroku for a few days now and keep running into Application errors even after a successful build. I recently realized that I had the entire /dist folder in .gitignore, so I removed it, but the ap ...

The image referenced in the assets folder could not be located within the SCSS

Although I've come across similar questions, none of the solutions provided seem to work for me. I've tried them all, but they just don't seem to do the trick. My goal is quite simple - I just want to set a background image using CSS. Howev ...

What is the proper syntax for specifying a specific field in a generic class?

type Specific = {field: 'add'} | {field:'remove'}; function add(value: Specific) {} // Ensures value.field === 'add' function remove(value: Specific) {} // Ensures value.field === 'remove' How can I restrict functi ...

Setting up the Angular JS environment manually, without relying on an Integrated

I am a complete beginner when it comes to Angular JS. I recently inherited an Angular JS application that I need to run on a server without using any Integrated Development Environment (IDE). I have tried researching online for methods to run the applicat ...

Is it possible to utilize useRef to transfer a reference of an element to a child component?

When I want to mount something into the element with id tgmlviewer, I call it a viewer object. This process works smoothly when there is only one component of this kind. import React, { useEffect } from "react"; import { Viewer } from "../.. ...

Ways to pass styling properties to a nested component

I am working on a component that includes an input field: <mat-form-field appearance="standard"> <mat-label >{{label}}<span>*</span></mat-label> <input [type]="type" <span matSuffix>{{suffix} ...

displaying the name of the current admin center on the header

In my project, the admin registers an account with a center name. However, when they log in and see the admin page on the header, I need to display the center name that was registered for the current logged-in admin. Unfortunately, I have no idea how to ac ...

Creating a conditional interface based on props in TypeScript: A step-by-step guide

What is the most effective way to implement conditional props in a component that can be either a view or a button based on certain props? Let's take a look at an example called CountdownButtonI: class CountDownButton extends Component<CountdownBut ...

A mistake was made: The template contains errors stating that 'app-my-profile' is an unknown element

I encountered an error message: "Uncaught Error: Template parse errors: 'app-my-profile' is not a known element," while working on setting up my profile service. import { BrowserModule } from '@angular/platform-browser'; import { NgM ...

I'm encountering a 404 error on Next.js localhost:3000

Embarking on a fresh project in Next.js, my folder structure looks like this: https://i.stack.imgur.com/HhiJo.png However, upon navigating to localhost:3000, I am greeted with a 404 error screen. It seems there is an issue with the routing, but unfortuna ...

Filter array of objects by optional properties using TypeGuards

In my TypeScript code, I have defined the following interfaces: interface ComplexRating { ratingAttribute1?: number; ratingAttribute2?: number; ratingAttribute3?: number; ratingAttribute4?: number; } export interface Review { rating: ComplexRati ...

Errors occur when passing an object to the redux store in a TypeScript project due to a mismatch

I am encountering an issue where I need to pass a datum object to a redux store without triggering TypeScript errors import { TreeNodeDatum } from 'react-d3-tree/lib/types/common'; import { HierarchyPointNode } from 'd3-hierarchy'; con ...

Using Typescript to Integrate node-gtf JavaScript Library into an Express Application

Would like to utilize a Typescript Express Server for integrating GTFS data with the help of the GTFS library (https://github.com/BlinkTagInc/node-gtfs) current version is ("gtfs": "^3.0.4") This is how I am importing the library imp ...

Sharing AppSettings between an Angular project and ASP.NET Core in a seamless manner

Currently, I have a project set up using the VS 2022 ASP.NET Core with Angular template. The project itself is working well, but I am facing a challenge in trying to integrate the Angular app with the .NET Core's appsettings.json file for configurati ...

Clearing the Value of a Linked Ant Design Cascading Dropdown Select in Next.js/React.js

I'm currently developing a React form with the assistance of Ant Design's Form component. The form boasts various dropdowns such as facility, specialization, and doctor. It is imperative that when the values in the facility or specialization drop ...