Angular rxjs Distinctions

Coming from AngularJS to Angular, I'm still trying to wrap my head around rxjs observable.

For example:

User.ts

export class User {
id?:any;
username:string;
password:string;
}

Using <User[]>

myUser(header: any) {
const url = `${this.mainUrl}/my_user`;
return this.http.get<User[]>(url, header).pipe(
  map(resp => {
    return resp;
  })
);
}

Not using <User[]>

myUser(header: any) {
const url = `${this.mainUrl}/my_user`;
return this.http.get(url, header).pipe(
  map(resp => {
    return resp;
  })
);
}

Both methods seem to give the same result. So I'm unsure of the significance of including it or not.

UPDATE:

The data I'm fetching looks nothing like my User.ts file, but surprisingly no errors are being thrown.

{
"username": "mhqadmin",
"inserted_at": "2019-02-06T07:01:17.024874",
"id": "b491e7c3-da11-40fe-b4b7-8f97fa88a9fd",
"avatar": {
    "middlename": "mhqadmin",
    "lastname": "headquarters",
    "id": "939c2eec-573e-4245-adcc-0771c73f22e4",
    "firstname": "marte"
},
"app_role": "mhq-admin",
"app_permission": true
}

Answer №1

When using this.http.get<User[]> compared to this.http.get, the main distinction is that you are specifying a type within the generic signature of get.

According to the Angular source code:

  get<T>(url: string, options?: {
    headers?: HttpHeaders | {[header: string]: string | string[]},
    observe?: 'body',
    params?: HttpParams|{[param: string]: string | string[]},
    reportProgress?: boolean,
    responseType?: 'json',
    withCredentials?: boolean,
  }): Observable<T>;

The usage of get<T> represents a generic type signature, allowing you to define the expected data structure. By invoking this.http.get<User[]>, you are essentially indicating that the returned data should conform to an array of type User. However, this concept is rooted in TypeScript and doesn't directly impact RxJS/Observables or JavaScript functionalities. When calling this.http.get, the operation simply triggers an HTTP request for data without any predefined type specification.

In order to tailor the retrieved data to match your User.ts class structure, simply defining the type as this.http.get<User[]> won't alter the data itself; it merely serves as a guideline for the compiler. To manipulate the data format accordingly, you would need to extract and reformat the relevant fields, as demonstrated below:

myUser(header: any) {
  const url = `${this.mainUrl}/my_user`;
  return this.http.get(url, header).pipe(
    map(resp => {
      return {
        id: resp.id,
        username: resp.username
      };
    })
  );
}

This snippet showcases aligning the data output with an interface/class like the following:

interface User {
  id: string;
  username: string;
}

However, keep in mind that the actual data structure being received likely adheres more closely to a model such as:

interface User {
  username: string;
  inserted_at: string;
  id: string;
  avatar: Avatar;
  app_role: Role;
  app_permission: boolean;
}

If you specify a type within the generic parameter, that defines the expected output model from the Observable. To accurately map this output to the correct interface, adjustments must be made as illustrated in the map example.

Answer №2

When you include <User[]> in your Typescript code, you are specifically telling Typescript that the result of http.get will be an Observable<User[]>. This allows Typescript to accurately infer the type of variable myUser as Observable<User[]>. This proves helpful later in your development process since it enables better tooling support by providing information on the properties available in your response types and catching any typos or mistakes during compilation. The use of generics in http.get allows you to define the expected response type (however, if not specified, it defaults to any).

If you omit <User[]>, Typescript will default to the any type, essentially offering no additional advantages over regular javascript.

Furthermore, the map(resp => { return resp; }) function is unnecessary and can be safely removed from your code.

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

Navigating through nested Firebase realtime DB queries using await/async techniques

In the process of developing a Firebase function (Gist), I encountered a challenge that I'm seeking assistance for. The function starts by querying a realtime database reference (events) using this code: await admin.database().ref('/events_geo ...

An error is anticipated when () is added, but surprisingly, I still encounter an error as well. This issue arises in React-Native and Typescript

I am still relatively new to React-Native, but I have been using React-Native, TypeScript, and integrating it with Firebase. An unusual error has occurred, which is visible in the screenshot below. However, when checking in VSC, the error seems to be non-e ...

The function to increase the number of days on a date in Angular is experiencing technical issues

I'm facing an issue where I need to add 12 days to a specific date, but the new date is not coming out as expected. Below is the code snippet: addDays(days: number): any { let startDate = new Date(this.selectedDeliveryDate); let endDate = new ...

The 'payload' property is not found within the 'Actions' type

I recently started using TypeScript and Visual Studio Code. I encountered the following issue: *[ts] Property 'payload' does not exist on type 'Actions'. This is my code: action.ts file: import { Action } from '@ngrx/store&apos ...

What is a more efficient way to write nested subscribe in Angular?

I am a beginner with RxJS and I'm interested in learning how to write clean code using it. I currently have a nested subscription that I've been trying to refactor without success. firstMethod() { this.testMethod(name) console.log(this.curren ...

Variety of part ingredients

In my component, I have a button and include another component which also contains a button. How can I align these two buttons next to each other without using absolute positioning? When I try positioning them using absolute right and top values, the lay ...

Exploring the incorporation of an inclusive switch statement within a Redux reducer utilizing Typescript. Strategies for managing Redux's internal @@redux actions

After conducting extensive research, I have yet to discover a definitive answer to this query. There is a question posted on Stack Overflow that provides guidance on how to implement a thorough switch statement: How can I ensure my switch block covers al ...

What purpose does a cast serve when used on a return type that is defined generically?

Consider this straightforward property access function export function accessProperty<T, K extends keyof T, P extends T[K]>(name: K, v: T): P { return v[name] as P } What is the significance of the cast as P in this context? I experimented with ...

Encountering a 404 error while trying to deploy a React app on Verc

After deploying my React project with TypeScript using Vite, everything is working smoothly. However, I am encountering a 404 error when trying to refresh the page. Error: 404 NOT_FOUND Error Code: NOT_FOUND ...

How to bring in images from the assets folder using React and Typescript

I'm facing an issue where direct image importing is working, but when using object types, it's not functioning properly. Why could this be happening? I am currently working with "react": "^16.12.0" and "typescript": "~3.7.2" // ./src/assets/baby ...

"The list of table rows in a React application using Typescript is not rendering properly

I am encountering an issue where the rows in my table are not being rendered while trying to map objects from a list called items. I am working with typescript and react-bootstrap. Can someone help me understand why this is happening and how to resolve it? ...

I am having trouble establishing a connection between two containers on Heroku

My web application is built using Node.js and MongoDB. After containerizing it with Docker, everything worked fine locally. However, when I tried to deploy it to production, I encountered an issue where the backend could not establish a connection with the ...

The element 'mat-toolbar' is unrecognized and not known:

Encountering an issue while executing karma tests - the error message indicates that 'mat-toolbar' is not a recognized element within the application. Here are some steps to troubleshoot this problem: 1. Confirm whether 'mat-toolbar' is ...

Avoiding type errors in d3 v5 axis by using Typescript

I am new to TypeScript and I have some code that is functioning perfectly. I believe if I define a type somewhere, d3's generics will come into play? Within my code, I have an xAxis and a yAxis. Both are the same, but D3 seems to have an issue with t ...

What steps are involved in setting up a sorting feature?

In order to utilize the array.sort() function, a number-returning function must be specified. Typically, it would look something like this: myArray.sort((item1, item2) => a < b); However, I am aiming for a different structure: myArray.sort(by(obj ...

Error in IONIC 3: The code is unable to read the 'nativeElement' property due to an undefined value, resulting in a TypeError

I am currently learning about IONIC 3 and working on an app that utilizes the Google Maps API. However, when I try to launch my app, I encounter the following error message: inicio.html Error: Uncaught (in promise): TypeError: Cannot read property ' ...

Tips for accessing data from a JSON file in a compiled Angular2 project

I have a scenario in my Angular2 project where I am fetching settings from a JSON file. However, after compiling the project for production using the ng build command, I noticed that the content of the JSON file is now inserted into the main.bundle.js. Thi ...

After compilation, any variables declared within a module remain undefined

I have declared the following files app.types.ts /// <reference path="../../typings/tsd.d.ts"/> module App{ export var Module = "website"; //---------------Controller Base Types--------------- export interface IScope extends ng.ISco ...

The FileSaver application generates a unique file with content that diverges from the original document

I'm attempting to utilize the Blob function to generate a file from information transmitted via a server call, encoded in base64. The initial file is an Excel spreadsheet with a length of 5,507 bytes. After applying base64 encoding (including newlines ...

Primary source for recurring components with the @SkipSelf decorator

Trying to understand the inner workings of Angular's dependency injection system, it seems that the component instance tree is traversed to locate the first occurrence of the specified provider, giving priority to ElementInjector over ModuleInjector ( ...