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

transform json array into a consolidated array by merging identical IDs

I need to transform an array into a different format based on the values of the ID and class properties. Here is the initial array: const json = [{ "ID": 10, "Sum": 860, "class": "K", }, { "ID": 10, "Sum": 760, "class": "one", }, { "ID": ...

The call to Contentful's getAsset function resulted in an undefined value being

I am facing a challenge while trying to fetch an asset, specifically an image, from Contentful and display it in my Angular application. Despite seeing the images in the Network log, I keep encountering an issue where the console.log outputs undefined. Any ...

Divide the enhanced document into sections using TypeScript

In my project, I am working with Material UI and TypeScript. I have noticed that I need to declare the Theme interface and ThemeOptions in the same file for it to work properly. Is there a more efficient way to separate these declarations from the main t ...

Strange occurrences observed while looping through an enum in TypeScript

Just now, I came across this issue while attempting to loop through an enum. Imagine you have the following: enum Gender { Male = 1, Female = 2 } If you write: for (let gender in Gender) { console.log(gender) } You will notice that it iter ...

When using routerLink, it automatically converts the URL to a

I am currently working on an Angular project where I need to link to bookmarks on other pages. In my HTML, I have links structured like this: <a href="#products" routerLink="overview">products</a> However, during compilation and execution of ...

Conceal the React button once it has been pressed

In my checklist of questions, I have set up a system where the first button is shown if any checkboxes are selected. If no checkbox is selected, then the second "Submit" button is displayed. Upon clicking submit, a message appears inside. Additionally, for ...

Unable to proceed with deployment due to the absence of the 'category' property in the '{}' type

Everything seems to be functioning properly - I can add and remove products, all with the properties I specified in the database. However, my deployment for production is being hindered by some errors that I'm encountering. ERROR in src\app&bsol ...

Leveraging Angular2's observable stream in combination with *ngFor

Below is the code snippet I am working with: objs = [] getObjs() { let counter = 0 this.myService.getObjs() .map((obj) => { counter = counter > 5 ? 0 : counter; obj.col = counter; counter++; return view ...

Utilizing Angular and TypeScript: The best approach for managing this situation

I need some guidance on handling asynchronous calls in Angular. Currently, I am invoking two methods from a service in a controller to fetch an object called "categoryInfo." How can I ensure that these methods return the categoryInfo correctly and displa ...

Determine the presence or absence of data in an Angular Observable

Here is an example of how I am making an API call: public getAllLocations(): Observable<any> { location = https://v/locations.pipe(timeout(180000)); return location; } In my appl ...

Prevent touching the pseudo content of an element

My issue involves a toggle button component where I have utilized the ::before pseudo class to add text. The problem arises when clicking on the text within the toggle button causes the button's state to change. How can this be prevented? Here is the ...

Tips for changing the color of an MUI 5 checkbox and label when hovering

I am looking to create a checkbox enclosed in a wrapper with a label. The goal is to change the color of everything inside the wrapper when it is hovered over. Here is an example image: Below is the code I have attempted: const styles = {formControlLabel: ...

Verify an entry with exactly 7 numerical digits

When inputting data, the user is limited to entering only 7 figures. If more than 7 figures are entered, an error message will display: "You need 7 digits". For instance, if the user enters something like this: 12345678910 The error message is correctly ...

Update the object status from being null to a different one using the set state function

class SubCategoriesComponent extends React.Component< SubCategoryStateProps > { constructor(props: RouteComponentProps<CategoryUrlParams>) { super(props); this.state = { category: null, }; } componentDidMount() { ...

Vue3 can accept a prop of type String or PropType

In my Vue3 project, I have a component that accepts a prop which can be either a string or an object. Here's how it looks: import { defineComponent } from 'vue' const Component = defineComponent({ props: { book: { type: [String, ...

Tips for optimizing the performance of nested for loops

I wrote a for loop that iterates over 2 enums, sending them both to the server, receiving a value in return, and then calculating another value using a nested for loop. I believe there is room for improvement in this code snippet: const paths = []; for awa ...

Ways to access information from a SQLite database using Angular

I am a beginner in front-end/back-end communication and I need guidance on how to retrieve data from a SQLite db file to populate a page in my Angular project. I have no idea where to begin, so any resources you can recommend would be greatly appreciated. ...

The issue with Angular 2's router.navigate not functioning as expected within a nested JavaScript function

Consider the app module: import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angul ...

Using Boolean functions in ngStyle allows for dynamic styling of elements in Angular templates

<div *ngFor= “ let singleorder of order.order”> <p [ngStyle]=" 'color':(singleorder.status === 'CONFIRM' )? 'green' : 'red' , 'background' : (singleorder.status === ' ...

Exploring Angular 2 Routing across multiple components

I am facing a situation where I have an app component with defined routes and a <router-outlet></router-outlet> set. Additionally, I also have a menu component where I want to set the [routerLink] using the same routes as the app component. How ...