Can a custom subscribe() method be implemented for Angular 2's http service?

Trying my hand at angular2, I discovered the necessity of using the subscribe() method to fetch the results from a get or post method:

this.http.post(path, item).subscribe(
  (response: Response)=> {console.log(response)},
  (error: any)=>{console.log(error)}
);

However, I had the idea of enhancing the subscribe() method by creating a custom version that includes an error callback function with a strongly typed error argument. This would allow us to subscribe to the Observable in the following manner:

this.http.post(path, item).subscribe(
  (response: Response)=> {console.log(response)},
  (error: HttpError)=>{console.log(error.body)}
);

I defined the structure of HttpError as shown below:

import { ModelState } from "app/Base/model-state";
import { ModelStateDictionary } from "app/Base/model-state-dictionary";
import { ErrorBody } from "app/Base/error-body";

export class HttpError {
    public ok: boolean;
    public status: number;
    public statusText: string;
    public type: number;
    public url: string;
    public body: ErrorBody;
    public static create(error: any): HttpError {
        let errorBody: ErrorBody = new ErrorBody();
        let body = JSON.parse(error._body)
        errorBody.message = body.message == null ? "" : body.message;
        errorBody.modelStateDictionary = new ModelStateDictionary();
        if (body.modelState != null) {
            for (let key in body.modelState) {
                let modelState: ModelState = new ModelState();
                modelState.Value = key;
                for (let value in body.modelState[key]) {
                    modelState.Error.push(value);
                }
                errorBody.modelStateDictionary.push(modelState);
            }
        }
        let httpError: HttpError = new HttpError();
        httpError.body = errorBody;
        httpError.ok = error.ok;
        httpError.status = error.status;
        httpError.statusText = error.statusText;
        httpError.type = error.type;
        httpError.url = error.url;
        return httpError;
    }
}

To handle this conversion and ensure users can benefit from the improved version of subscribe(), I believe I need to invoke the create() method prior to subscription and transform the Java object error into an instance of HttpError. It seems like I might need to implement a custom Observable or utilize map(). As a newcomer to TypeScript and Reactive programming, I would appreciate some guidance on how to accomplish this conversion effectively.

Answer №1

Initially, my understanding is that http.post in Angular essentially wraps the HTTP response. This snippet is extracted from the Angular source code.

function httpRequest(backend: ConnectionBackend, request: Request): Observable<Response> {
  return backend.createConnection(request).response;
}

In this context, either 'response' or 'error' refers to the actual HTTP response object.

this.http.post(path, item).subscribe(
  (response: Response)=> {console.log(response)},
  (error: any)=>{console.log(error)}
);

It might be beneficial to extend a method within Observable to customize the response handling and retrieve the desired Object. For example, using something like this.http.post(path, item).castHttpError().subscribe()

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/subscribe.md

However, caution is advised when extending functionalities of established libraries like Angular. While creating your own distribution of Angular is discouraged by Angular itself, it could still be worth experimentation.

Lastly, I recommend crafting a utility method for implementing this operation, even though it may seem unnecessary, it won't cause harm.

this.http.post(path, item).subscribe(
  response => { console.log(response); },
  error => {
    console.log(toHttpError(error).body);
  }
);

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

Exploring TypeScript's Index Types: Introduction to Enforcing Constraints on T[K]

In typescript, we can utilize index types to perform operations on specific properties: interface Sample { title: string; creationDate: Date; } function manipulateProperty<T, K extends keyof T>(obj: T, propName: K): void { obj[propName] ...

Child component not receiving disabled state from Angular 8 FormControl

In my code, there is a unique custom input that I have defined: <nivel-servico-slider formControlName="fornecedor_a"></nivel-servico-slider> This custom input has all the necessary properties as outlined in Angular's guide for c ...

Accessing attributes of a parent class object from within a child object

Imagine having four tabs within an Angular component, each with its own set of criteria for being displayed. Here's a high-level overview of the scenario. export class DisplayTabs { foo: true; bar: false; tabs: { 'A': { order: 1, g ...

Transforming button click from EventEmitter to RXJS observable

This is the functionality of the component utilizing EventEmitter: import { Component, Output, EventEmitter } from "@angular/core"; @Component({ selector: "app-my-component", template: ` <button (click)="clickEvent($event)& ...

Associate an alternate attribute that is not displayed in the HTML component

Imagine there is a collection of objects like - var options = [{ id: "1", name: "option1" }, { id: "2", name: "option2" } ]; The following code snippet is used to search through the list of options and assign the selected option to anot ...

Having trouble compiling Angular CLI version 8.3.21 with the command ng serve

Upon trying to compile my first Angular app, I encountered an error when running ng serve: ERROR in ./src/styles.css (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded! ...

Enabling cookie communication between NestJS server and Next.js frontend

I seem to be encountering challenges when trying to set cookies from a NestJS backend into my Next.js app. My NestJS application is running on port 3001 and here is my bootstrap setup: async function bootstrap() { const app = await NestFactory.create(Ap ...

Retrieve parent route parameters from a dynamically loaded route component

Struggling to access the parent route params in a lazy loaded route component using activatedRoute.parent.params. Despite this not working, I have managed to find a solution that involves fetching the value using an array index number which feels like a &a ...

Utilizing TypeScript to enhance method proxying

I'm currently in the process of converting my JavaScript project to TypeScript, but I've hit a roadblock with an unresolved TypeScript error (TS2339). Within my code base, I have a class defined like this: export const devtoolsBackgroundScriptCl ...

Restrict a class to contain only functions that have a defined signature

Within my application, I have various classes dedicated to generating XML strings. Each of these classes contains specific methods that take input arguments and produce a string output. In order to enforce this structure and prevent the addition of methods ...

Issue with Socket.io Client: Consistently receiving error messages for an incorrect

Here is the server-side code: import http from 'http'; import Koa from 'koa'; import { Server } from 'socket.io'; (async () => { const app = new Koa(); var server = http.createServer(app.callback()); var io = new Se ...

Using a Typescript enum as a parameter type can lead to accepting incorrect values

When working with TypeScript, I have defined an enum, and now I want to create a function that accepts a parameter whose value is one of the enum's values. However, TypeScript does not validate the value against the enum, allowing values outside of th ...

Creating a HandleCredentialResponse function in Angular version 14 for implementing the "Sign in with Google" feature using Typescript

In the process of building a very simple angular version 14 application, I am working on displaying a 'Sign in with Google button' and incorporating the login functionality. For information about the new method of Sign in With Google, you can re ...

Angular component fails to render when passed as a string in the innerHtml attribute

One interesting challenge I faced is working with an API that returns HTML containing Angular components which are not being displayed in the application. I am trying to figure out how to display an Angular component stored as a string within the HTML con ...

Continuously apply the template in a recursive manner in Angular 2 without reintroducing any duplicated components

Recently, I delved into the world of angular 2 and found it to be quite fascinating. However, I'm currently facing a roadblock and could really use some assistance. The scenario is as follows: I am working on creating a select box with checkboxes in ...

Enhancements to a NativeScript Application

After running some tests on my NativeScript app following the steps outlined here - , I found that it takes 18 seconds for the program to start and for a user to log in. Is this considered acceptable performance? Appreciate any feedback provided! ...

Patiently waiting for the component variable to be assigned through subscription

I am facing an issue with two calls in my component. The second call depends on the result from the first call. In the first call, I set the value for my component variable "locked". The second call should only be executed when the result is true, meaning ...

Angular 4: Loading components sequentially

I am currently working with Ionic 3 and based on the Angular 4 framework. I have a question regarding loading multiple children components asynchronously, one by one: Load parent component; Load first child component; After the first child component is l ...

How to style a parent div with a background class in Angular 6

In my Bootstrap 4 project, I am creating an accordion that consists of cards. Each card contains various icons such as edit, view, and details. When any of these icons are clicked, a function in the component is triggered to navigate the user to a child ro ...

developed a website utilizing ASP MVC in combination with Angular 2 framework

When it comes to developing the front end, I prefer using Angular 2. For the back end, I stick with Asp MVC (not ASP CORE)... In a typical Asp MVC application, these are the steps usually taken to publish the app: Begin by right-clicking on the project ...