Extracting an array from an HTTP response in Angular/Typescript using the map operator or retrieving a specific element

Q1: How can I extract an array of objects from a http response using map in Angular?

Q2: Is there a way to retrieve a specific object from a http response by utilizing map in Angular?

Below are the example URL, sample data, CurrencyAPIResponse, and Currency object for reference.

I have experimented with 2 methods and various alternatives, but none seem to be effective:

Q1: Extract an array of objects from a Map property within the Response object:

get(): Observable<Currency[]> {
    return this.httpClient.get<CurrencyAPIResponse>('https://api.coindesk.com/v1/bpi/currentprice.json')
      .pipe( map( response => Array.from( response.bpi.values())));
}

Q2: Retrieve a specific Currency object from a Response containing a Map property:

getOne(name: string): Observable<Currency> {
    // @ts-ignore
    return this.httpClient.get<CurrencyAPIResponse>('https://api.coindesk.com/v1/bpi/currentprice.json')
      .pipe( map( response => response.bpi.get( name)));
}

Upon accessing the specified url, you will obtain an object with a map structure. The data is as follows:

{
  "time": {
    "updated": "Jun 5, 2022 12:04:00 UTC",
    "updatedISO": "2022-06-05T12:04:00+00:00",
    "updateduk": "Jun 5, 2022 at 13:04 BST"
  },
  "disclaimer": "Some text",
  "chartName": "Bitcoin\"",
  "bpi": {
    "USD": {
      "code": "USD",
      "symbol": "&#36;",
      "rate": "29,698.5140",
      "description": "United States Dollar",
      "rate_float": 29698.514
    },
    "GBP": { ... }, 
    "EUR": { ... }
  }
}

The definition of my type and object is as follows:

Currency:

export class Currency {
  code: string = '';
  symbol: string = '';
  rate: number = 0;
  description: string = '';
  rate_float: number = 0;
}

The CurrencyAPIResponse:

interface CurrencyAPIResponse {
  "time": {
  	"updated": string, // or should this be a date?
    "updatedISO": string,
    "updateduk": string
  },
  "disclaimer": string,
  "chartName": string,
  "bpi": Map<string,Currency>
}

Answer №1

Not specifically using the Angular HttpClient, but rather more focused on Javascript.

In response to Question 1, there are various methods you can employ to convert an Object literal into an Array. For instance, if you wish to extract values and create an array from them, you can utilize Object.values(putYourObjectHere). Alternatively, if you want to extract keys and create an array of them from your original object, you can use Object.keys(putYourObjectHere) and so forth.

Regarding Question 2, you have the option of utilizing Array.prototype.find() as well as other options available in both ES5 and ES6. To learn more about the find() method

Answer №2

To achieve your desired outcome through piping observables, you can follow this approach:

fetchData(): Observable<Currency[]> {
    return this.http.get<CurrencyAPIResponse>('https://api.coindesk.com/v1/bpi/currentprice.json')
  .pipe( 
      pluck('bpi'),
      map(obj => [...Object.values(obj)])
  );
}

If you need only one currency:

fetchOne(name: string): Observable<Currency> {
    return this.fetchData()
  .pipe( 
      map(array => array.find(element => element.code === name))
  );
}

A more efficient approach would be to make the initial HTTP call just once, and then utilize a function to extract individual currencies using

array.find(element => element.code === name)
.

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

In Angular 4, there are two routes that result in the same endpoint but direct to separate modules

I'm currently working on an Angular 4 project with the following structure: app fUsers home home.component.ts home.module.ts home.routes.ts fUsers.module.ts fUsers.routes.ts lUsers dashboard dashboard.component.ts dashboard.module.ts das ...

Having difficulty updating the value of a FieldArray with setFieldValue in Formik

Thank you for taking the time to read this. I am currently working on creating a form using Formik that involves nesting a FieldArray within another FieldArray. Oddly enough, setFieldValue seems to be functioning correctly as I can log the correct values ...

Eliminate the AM and PM options from the input time selection dropdown menu in HTML

I'm looking to eliminate the AM / PM option in this time input dropdown, can it be done? The form builder currently uses 24-hour format based on the presence of the AM / PM field. ...

Utilizing Components for Efficient Development in Angular

I have three different types of objects: A - FirstName - LastName B - FirstName - LastName - MiddleName C - FirstName My goal is to create a component that can be used to easily create these objects using a simple form where I can input the necessa ...

Sending binary information from a .net core web api to a typescript application

I currently have a .net core 3.0 web api application connected to an angular 8 client. While I have successfully transferred data between them using json serialization, I am now looking for a way to transfer a bytes array from the api to the client. After ...

It appears that protractor-flake is programmed to re-run all tests instead of just the ones that have failed

Running tests using the latest version of "[email protected]", encountering failures during testing but the tests are rerunning again. No custom reporter used except Allure reporting. Below is the command used for running: protractor-flake --max-at ...

Tips for sorting/merging/consolidating data in Angular

Take a look at this code snippet: rowData = [ [ '2019-12-10 08:00:00', '2019-12-10 08:00:00', '2019-12-10 08:00:00', '2019-12-10 08:00:00', '2019-12-10 08:00:00', '2018-12-10 08:00:00' ...

Is there a way to ensure that the onChange event of ionic-selectable is triggered twice?

I've been working with an ionic app that utilizes the ionic-selectable plugin, and for the most part, it's been running smoothly. However, I encountered a rare scenario where if a user on a slow device quickly clicks on a selection twice in succe ...

Angular is throwing an error due to an unexpected token when running on an IIS server within a subfolder

I have recently developed an Angular 11 template (Angular version 11 + .Net core 5.0) using visual studio 2019. The Angular application needs to be accessed from a subfolder called caui rather than the root folder. After publishing the Angular application ...

Why does my useEffect consistently execute after the initial rendering, despite having specified dependencies?

const [flag, setFlag] = React.useState(false) const [username, setUsername] = React.useState('') const [password, setPassword] = React.useState('') const [errorUsername, setErrorUsername] = React.useState(true) const [er ...

"Issue with default select value in Angular using ngModel - one select element not setting default value, while another works fine

Why is this functioning properly? File: myComponent1.html <select id="BisMonat" class="form-control" [(ngModel)]="currentmonatbis"> <option [value]="01">Januar</option> <option [value]="02">Feb ...

Android encountered an unknown error while trying to access the URL, resulting in an HTTP failure response with a status

My Ionic app runs perfectly fine on iOS, but when I try to run it on Android, I encounter the following error: Http failure response for (unknown url): 0 Unknown Error https://i.stack.imgur.com/8EFna.png I have CORS enabled on the server side and it wor ...

Is it possible to confirm that a value is a valid key without prior knowledge of the object's keys during compile-time?

Is there a way in TypeScript to declare that a variable is a keyof some Record without prior knowledge of the keys? For instance, consider an API response returning JSON data. Is it possible to define a type for the keys of this payload to ensure that whe ...

Function in Typescript that accepts an array or a single instance of a constructor and then returns a list

UPDATE:: reproducible link to the TypeScript playground I have also found a solution in the provided link, but I am still open to learning why my initial approach didn't work. TLDR; This method does not yield the expected results getEntitiesByComp ...

Preventing specific directories from being imported in a Typescript project

I am intrigued by the idea of restricting files within a specific scope from importing files from another scope. Let's consider this example: Imagine we have the following project structure: project/ ├── node_modules/ ├── test/ ├── ...

Storing multiple items in an array using LocalForage

I have a challenge where I need to add multiple items to an array without overriding them. My initial approach was like this: localForage.getItem("data", (err, results) => { console.log('results', results) // var dataArray ...

Managing onChange in a ReactJs project

Currently, my React tsx page features input boxes like the following: <textarea value={this.state.myData!.valueOne} onChange={(e) => this.handleValueOneChange(e)}/> <textarea value={this.state.myData!.valueTwo} onChange={(e) => thi ...

What is the correct way to wrap an http.get in TypeScript?

My understanding of Typescript is limited, so I have a basic question related to my web application's frontend. In most http get-requests, I need to include two parameters. To simplify this process, I created a simple wrapper for HttpClient (from "ang ...

Node.js is raising an error because it cannot locate the specified module, even though the path

Currently in the process of developing my own npm package, I decided to create a separate project for testing purposes. This package is being built in typescript and consists of a main file along with several additional module files. In the main file, I ha ...

Implementing Injector Class instead of ReflectiveInjector class is a great way to improve performance

I have been experimenting with dynamic loading data in angular. To achieve this, I initially used the following code snippet - const inputProviders = Object.keys(data.inputs).map(inputName => { return { provide: inputName, useValue: data.inputs[inp ...