Refining Angular service coding techniques

In my application, I have implemented this specific format to interact with an API and retrieve data from it.

Below is the code snippet taken from one of the service.ts files:

getCheckoutDetails(): Observable<UserDetail> {
    let query = `7668`;
    return this.http
        .get(this.appConfig.getAPIUrl()
            + `/buy/getDetails?${query}`)
        .map(this.extractData)
        .catch(this.handleErrors);
}


private extractData(res: Response) {
    let data = res.json();       
    return data.body ? data.body.message ? data.body.message : {} : {};
}

private handleErrors(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
        const body = error.json() || '';
        const err = body.error || JSON.stringify(body);
        errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
        errMsg = error.message ? error.message : error.toString();
    }
    console.error(errMsg);
    return Observable.throw(errMsg);
} 

We are now utilizing cpd to identify duplicated code in the application. Interestingly, it points out that there is duplication whenever the methods extractData and handleErrors are utilized.

Is there a more efficient approach to address this issue by employing a base class?

Answer №1

If you want to organize your methods in a more structured way, consider moving them to a base class. Here's an example:

class CoreService {
  constructor(
    private httpClient: HttpClient, 
    @Inject(AppConfiguration) private appConfig: AppConfiguration) {}

  fetchData(url: string) {
     return this.httpClient
            .get(`${this.appConfig.getAPIEndpoint()}${url}`)
            .pipe(map(this.extractResponseData))
            .pipe(catchError(this.handleError));
  }

  private extractResponseData(response: HttpResponse) {
    let data = response.json();
    return data.body ? data.body.message ? data.body.message : {} : {};
  }

  private handleError(error: HttpResponse | any) {
    let errorMessage: string;
    if (error instanceof HttpResponse) {
        const body = error.json() || '';
        const err = body.error || JSON.stringify(body);
        errorMessage = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
        errorMessage = error.message ? error.message : error.toString();
    }
    console.error(errorMessage);
    return throwError(errorMessage);
  }
}

class DetailedService extends CoreService {
  getDetailsForCheckout() {
    let queryParam = '7668';
    return this.fetchData(`/checkout/fetchDetails?${queryParam}`) }
}

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 the incredible powers of Ionic2, Angular2, HTTP requests, and

Despite all the research I've done on observables, I still struggle to grasp how they function. The HTTP request code snippet is as follows: import { Component, OnInit, Injectable } from '@angular/core'; import { Http, Response, Headers, R ...

Error message: NextJs throws aReferenceError when trying to access the document object on page refresh

encountered the error ReferenceError: document is not defined when attempting to refresh the page I am working on creating a component using react-quill and then calling that component within a page. This is my component : import React, { useState } from ...

Is Angular File API Support Compatible with HTML5?

When checking for HTML5 File API browser support in my code: private hasHtml5FileApiSupport; constructor(@Optional() @Inject(DOCUMENT) document: Document) { const w = document.defaultView; this.hasHtml5FileApiSupport = w.File && w.FileReader & ...

What is the process for exporting the reducer function and integrating it into the storeModule.forRoot within an Angular application?

Recently, I started delving into ngrx and decided to educate myself by going through the official documentation on their website ngrx.io. During this exploration, I came across a puzzling piece of code in one of their reducers. The file in question is cou ...

How can I get the class name of the drop destination with react-dnd?

Imagine having this component that serves as a drop target module. import { useDrop } from 'react-dnd'; import './css/DraggableGameSlot.css'; type DraggableGameSlotProps = { className: string, text: string } function Draggable ...

Hold off on addressing the nested loops within a TypeScript subscription

Goal: Ensure all nested loops complete processing before returning final value. Problem: Final value returned prematurely, before completion of loop processing. In the code snippet below, I am sending paramListToComplete to a data service for creating a ...

Make sure that every component in create-react-app includes an import for react so that it can be properly

Currently, I am working on a TypeScript project based on create-react-app which serves as the foundation for a React component that I plan to release as a standalone package. However, when using this package externally, I need to ensure that import React ...

What is the TypeScript syntax for defining a component that does not require props to be passed when called?

Can you provide guidance on the correct type to specify for Component in order to compile this example without any type errors? import { memo } from "react"; import * as React from "react"; export function CustomComponent( props: ...

Installing Angular 4 in Visual Studio 2017

Looking to build an Angular web application using Visual Studio 2017. Starting with a new project by selecting Asp.net Web application with Empty template. Feeling unsure about which files need to be copied/included in the project based on the attached sc ...

Angular2 - Transmitting validation information from parent component to child component input validation

I am currently developing an automatic word correction module using Angular2. Within my child component, I have set up an EventEmitter. import {Component, Input, Output, EventEmitter} from '@angular/core'; ... export class StudyThumbsComponent{ ...

Angular is unable to modify the value of 'name' since it is either a constant or a property that cannot be modified

I am encountering an error that says "Cannot assign to 'name' because it is a constant or a read-only property" when trying to send data to the API. Does anyone know how I can solve this issue? Thank you. onSubmit() { const name = this.backU ...

Using Typescript to typecast in D3.js

Utilizing the D3 graph example available here. I've defined my data object as shown below: interface ID3Data { age: string, population: number } const data: ID3Data[] = [ { age: "<5", population: 2704659 }, { age: "5-13", population: 4499 ...

The interface 'HTMLIonIconElement' is not able to extend both 'IonIcon' and 'HTMLStencilElement' types at the same time

After upgrading my Angular Ionic app to use Angular v13 from Angular 12 with the command ng update, I encountered errors preventing me from running the application successfully. [ng] Error: node_modules/ionicons/dist/types/components.d.ts:66:15 - error TS2 ...

Unable to transfer variable from a function to the test in Protractor

Currently, I am working on a test to verify the amount of gold in my possession. The test is being conducted using TypeScript and Protractor. Within this testing scenario, I have a method named GetAmountOfChips: public static GetAmountOfChips(): PromiseL ...

Whenever I attempt to run my application using ng serve on Linux, I encounter the error stating: "Module '@angular-devkit/build-angular/package.json' cannot be found."

Hey everyone! I'm facing an error when trying to run my app from the terminal on Linux. The command I used was: ng serve And the error message I received in the terminal is as follows: AppBlog/blog# ng serve An unhandled exception occurred: Cann ...

Monitor changes in a dynamic child component using Angular fire and TypeScript only (no HTML)

Currently, I am developing a component using TypeScript and passing inputs to my child component from there. In the parent TypeScript file: this.childComponent = this.viewContainerRef.createComponent(this.data.body).instance; this.childComponent['chi ...

Tips for obtaining the passed Tag name when executing the Cypress Framework

Currently, I am working with a framework that involves Cypress 12.4, TypeScript -4.9, and Cucumber (cucumber-pre-processor -15). In this framework, I have some test cases labeled as @Sanity and others as @Regression. Below you can see the package.json scri ...

Various types of generics within an object

Is there a way to achieve different types for the nested K type within a type like MyType? Here's an example: type Config<K> = { value: K; onUpdate: (value: K) => void; } type MyType<F extends string> = { [K in F]: <V>() =& ...

Prevent coverage tracking for files or paths enclosed in square brackets in jest

I am trying to exclude a specific file from test coverage in Jest by modifying the collectCoverageFrom array. The file name contains square brackets, and I have added an entry with a negation for this file. collectCoverageFrom: [ './src/**/*.{js ...

Error: Undefined Property in Angular 2 ViewChild Declaration

Exploring a simple example where the childMethod is called within the child component from the parent component using the @ViewChild() decorator. However, encountering an issue where the ViewChild variable remains undefined. Sample Child Component Code: ...